연락처
목록 조회
GET /contacts — 연락처 목록을 cursor pagination으로 조회합니다.
- Scope:
contacts:read - 쿼리:
limit(기본 50, 최대 100),cursor,q(이름·이메일·전화 부분 검색)
정렬은 created_at 내림차순입니다(최신 연락처가 먼저).
q는 대소문자를 구분하지 않는 부분 일치(substring)이며, q에 포함된 % 또는 _는 와일드카드가 아니라 리터럴 문자로 검색됩니다.
curl "https://api.talk.zeroworks.ai/api/public/v1/contacts?limit=50&q=hong" \
-H "Authorization: Bearer ztpat_..."
응답
{
"success": true,
"data": [
{
"id": "a1b2c3d4-...",
"email": "hong@example.com",
"phone": "+821012345678",
"display_name": "홍길동",
"is_member": false,
"tags": ["vip"],
"last_seen_at": "2026-05-01T10:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-05-01T10:00:00Z"
}
],
"meta": { "has_more": true, "next_cursor": "eyJ..." }
}
display_name은 이름 → 이메일 → 전화 → "Anonymous" 순으로 결정되는 표시용 이름입니다.
is_member는 해당 연락처가 로그인한 멤버(인증된 사용자)인지, 익명·식별된 방문자인지를 나타냅니다.
external_id·email·phone·avatar_url·last_seen_at은 값이 없으면 null이 아니라 키가 생략됩니다 ("key" in obj로 판별). 위 예시는 이메일·전화·last_seen_at만 있는 연락처라 나머지 선택 필드 키가 빠져 있습니다.
단건 조회
GET /contacts/{id} — 단일 연락처를 조회합니다. {id}는 연락처 UUID입니다.
- Scope:
contacts:read
{
"success": true,
"data": {
"id": "a1b2c3d4-...",
"display_name": "홍길동",
"email": "hong@example.com",
"is_member": false,
"tags": ["vip"],
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-05-01T10:00:00Z"
}
}
태그 목록
GET /contacts/{id}/tags — 연락처에 부여된 태그 이름 목록을 조회합니다.
- Scope:
contacts:read
data는 연락처에 붙은 태그 이름의 문자열 배열입니다(연락처의 tags 컬럼을 그대로 반환). 페이지네이션이 없어 meta 필드는 포함되지 않으며, 태그가 없으면 빈 배열([])입니다.
{
"success": true,
"data": ["vip", "신규문의"]
}
태그의 정의(색상·사용 횟수 등 객체 형태)가 필요하면 GET /contact-tags를 사용하세요. 이 엔드포인트는 이름만 반환합니다.