메시지
채널의 메시지를 읽는 조회 API입니다. 채널 단위로 기간을 지정해 목록을 가져오고, 메시지 ID로 한 건을 조회하고, 첨부 파일은 별도 엔드포인트에서 다운로드 URL을 받습니다.
채널 메시지 목록
GET /channels/{id}/messages — 채널 내 메시지를 cursor pagination으로 조회합니다.
- Scope:
channels:read+messages:read(둘 다 필요) - 쿼리:
since(RFC3339, 필수),until(RFC3339, 기본 현재 시각),limit(기본 50, 1~100),cursor(이전 응답의meta.next_cursor값) - 조회 구간은
(since, until]입니다.since는 배타적이라 경계 시각과 정확히 같은 메시지를 제외하고,until은 포함적입니다. - 다음 경우
400 INVALID_QUERY를 반환합니다:since누락·형식 오류,until형식 오류,until이since보다 뒤가 아닌 경우(같은 시각 포함),until - since가 30일 초과,limit이 1~100 범위를 벗어난 경우,cursor길이 초과. - 채널이 이 워크스페이스에 없으면
404 NOT_FOUND를 반환합니다.
아래 요청은 2026-05-01 이후의 메시지를 조회합니다.
curl "https://api.talk.zeroworks.ai/api/public/v1/channels/c1d2.../messages?since=2026-05-01T00:00:00Z" \
-H "Authorization: Bearer ztpat_..."
응답
{
"success": true,
"data": [
{
"id": "msg-1a2b-...",
"channel_id": "c1d2e3f4-...",
"sender_id": "a1b2c3d4-...",
"sender_type": "contact",
"sender_name": "홍길동",
"content_type": "text",
"content": "안녕하세요",
"attachments": [
{ "id": "att-1a2b-...", "type": "image", "filename": "photo.png" }
],
"is_edited": false,
"created_at": "2026-05-01T10:00:00Z",
"updated_at": "2026-05-01T10:00:00Z",
"content_revision": 0
}
],
"meta": { "has_more": true, "next_cursor": "..." }
}
메시지 cursor는 만료가 없습니다 (자세한 내용은 페이지네이션 참고). attachments는 참조(id·type·filename)만 포함하며, 실제 다운로드 URL은 아래 첨부 다운로드에서 조회합니다.
- 정렬: 메시지는
created_at**내림차순(최신순)**으로 반환됩니다.next_cursor로 다음 페이지를 따라가면since경계를 향해 과거 방향으로 이동합니다. 대화를 시간순으로 재구성하려면 클라이언트에서 역순으로 정렬하세요. attachments: 첨부가 없는 메시지는 키 자체가 생략됩니다(빈 배열도null도 아닙니다).- 위 예시는 한 번도 수정되지 않은 메시지라
content_modified_at키가 생략됐습니다. 수정된 메시지는"content_revision": 2, "content_modified_at": "2026-05-01T10:05:00.123456Z"처럼 두 키가 함께 실립니다.
필드 값 집합
| 필드 | 값 |
|---|---|
sender_type | member(상담원)·contact(고객)·system(시스템)·bot(봇)·internal(내부)·workflow(워크플로)·external(외부 플랫폼 상담원, 예: 네이버 톡톡)·integration(PAT 기반 아웃바운드 발신) |
content_type | text·markdown·image·file·card·button·email·video·audio·system·blocks·sticker·location |
attachments[].type | image·file·video·audio |
sender_id: 불투명 식별자입니다. 멤버와 고객은 각자의 UUID이고,integration발신은 토큰 ID입니다. 시스템이 시작한 봇 메시지(영업시간 외 자동 응답·인사말·자동 종료)는 고정 서비스 UUID(00000000-0000-0000-0000-000000000002)를 가지므로,sender_id로 고객 여부를 판정하지 말고sender_type으로 판정하세요.sender_type·sender_name: 일부 시스템 발신 메시지에서는 빈 문자열("")일 수 있습니다.content_revision: 본문이나 첨부가 바뀔 때마다 커지는 정수입니다. 편집 횟수가 아니며(한 번 저장에 두 번 커질 수 있습니다), "이전에 읽은 값과 다른가"로만 판정하세요. 한 번도 바뀌지 않은 메시지는0이고 키는 항상 있습니다.content_modified_at:content_revision이 마지막으로 바뀐 시각(RFC 3339, 나노초까지, 후행 0 제거)입니다. 한 번도 바뀌지 않았으면 키 자체가 생략됩니다. 처리한 서버의 시계라 두 시각의 순서가 뒤집힐 수 있으므로 순서 기준은content_revision입니다.is_edited·updated_at: 본문 변경을 판정하는 데 쓸 수 없습니다.is_edited는 한 번true가 되면 그대로이고,updated_at은 상태 변경에도 움직입니다. 단,content_revision도입(v0.4.64, 2026-09-04 prod 배포) 이전에 편집된 메시지는is_edited: true인데content_revision: 0으로 나옵니다. 그 이후의 변경부터content_revision이 커집니다.
단건 조회
GET /messages/{id} — 단일 메시지를 조회합니다. 응답 data는 목록의 항목 하나와 같은 형태입니다(content_revision·content_modified_at 포함).
- Scope:
messages:read - 삭제된 메시지는
404입니다.
아래 요청은 메시지 한 건을 조회합니다.
curl "https://api.talk.zeroworks.ai/api/public/v1/messages/msg-1a2b-..." \
-H "Authorization: Bearer ztpat_..."
첨부 다운로드
GET /attachments/{id} — 첨부 메타와 다운로드 URL을 조회합니다.
- Scope:
attachments:read+messages:read(둘 다 필요) status='ready'인 첨부만 노출됩니다 (그 외 →404).url은 5분간 유효한 presigned URL입니다. 만료 시각은url_expires_at으로 확인하세요.
아래 요청은 첨부 한 건의 메타와 다운로드 URL을 조회합니다.
curl "https://api.talk.zeroworks.ai/api/public/v1/attachments/att-1a2b-..." \
-H "Authorization: Bearer ztpat_..."
응답
{
"success": true,
"data": {
"id": "att-1a2b-...",
"filename": "photo.png",
"content_type": "image/png",
"size_bytes": 10240,
"url": "https://s3.../photo.png?X-Amz-...",
"url_expires_at": "2026-05-01T10:05:00Z",
"created_at": "2026-05-01T10:00:00Z"
}
}