Quipier

API 레퍼런스

Quipier 공개 REST API — 인증, Comments·Feed 엔드포인트, 에러 형식, 제한.

SDK가 내부적으로 호출하는 공개 REST API입니다. 직접 호출(헤드리스 연동·자체 클라이언트)할 때 참고하세요. 베이스 URL: https://api.quipier.com

공통 형식

성공 응답은 항상 data envelope, 에러는 error envelope입니다:

{ "data": { /* … */ } }
{ "error": { "code": "FORBIDDEN", "message": "this IP is blocked from commenting" } }
에러 코드HTTP의미
INVALID_REQUEST400형식 오류 (필드 누락·제약 위반)
UNAUTHORIZED401API 키/토큰 없음·무효, origin 불허
FORBIDDEN403모듈 비활성·쿼터 초과·차단(IP/신원)
NOT_FOUND404리소스 없음
RATE_LIMITED429분당 작성 한도 초과
INTERNAL500서버 오류

인증

세 가지 수준이 있습니다:

  1. API 키 (x-quipier-key) — 읽기·게이트 통과용 publishable key (qp_…). Origin 게이트와 함께 동작: localhost·문서 플레이그라운드는 항상 허용, development 프로젝트는 전체 허용, production 프로젝트는 대시보드에서 검증된 도메인만(와일드카드 *.example.com 지원). RN 등 Origin 헤더가 없는 환경은 x-quipier-origin 헤더로 대신할 수 있습니다.
  2. 패스포트 토큰POST /v1/passports/auth로 발급 (scope passport, 15분). 패스포트 자체 조회용.
  3. 프로젝트 세션 토큰POST /v1/project-passports/join으로 발급 (scope project, 24시간). 모든 쓰기(댓글·포스트 작성/수정/삭제/좋아요/신고)는 이 토큰을 Authorization: Bearer <jwt>로 보냅니다.

선택 헤더 x-quipier-client: web|ios|android — 대시보드 분류용 자기 보고 값입니다.

패스포트 인증

POST /v1/passports/auth

기기의 Ed25519 키로 서명해 패스포트 토큰을 받습니다. 인증 불필요.

{
  "public_key": "base64(32B Ed25519 공개키)",
  "signature": "base64(64B 서명)",
  "ts": 1718000000000
}
  • 서명 대상: quipier:passport-auth:<passportId>:<ts> · ts는 현재 시각 ±5분 이내
  • 응답: { data: { passport_id, token, expires_at, created } } (신규면 201)

POST /v1/project-passports/join

패스포트를 프로젝트에 연결하고 프로젝트 세션 토큰을 받습니다. Bearer <패스포트 토큰> 필요.

{ "project_id": "…", "project_token_id": "BASE32_16-64자", "nickname": "민수" }
  • nickname: 2–32자, 문자/숫자/공백/._-
  • 응답: { data: { project_passport, session: { token, expires_at }, created } }

GET /v1/passports/me · GET /v1/passports/me/comments

Bearer <패스포트 토큰> — 연결된 프로젝트 목록 / 내가 쓴 댓글 목록.

Comments

메서드경로인증
GET/v1/comments?project_id&page_id&cursor&limitAPI 키(+origin)
POST/v1/commentsAPI 키 + 세션 토큰
PATCH/v1/comments/:id세션 토큰(작성자만)
DELETE/v1/comments/:id세션 토큰(작성자만)
POST / DELETE/v1/comments/:id/like세션 토큰
POST/v1/comments/:id/report세션 토큰

작성 body: { project_id, page_id(≤512자), content(1–2000자), parent_id? } 신고 body: { reason: "spam"|"harassment"|"adult"|"privacy"|"other" }

Comment 객체:

{
  "id": "…", "project_id": "…",
  "author_id": "<project_token_id>", "nickname": "민수",
  "page_id": "/blog/hello", "content": "…", "parent_id": null,
  "is_deleted": false, "created_at": "ISO",
  "likes_count": 0, "liked_by_me": false, "client": "web"
}

Feed (Posts)

메서드경로인증
GET/v1/posts?project_id&cursor&limitAPI 키(+origin) — 타임라인(최상위만)
GET/v1/posts/:id?project_idAPI 키 — 단건(공유 딥링크용)
GET/v1/posts/:id/replies?project_id&cursor&limitAPI 키 — 답글(오래된 순)
POST/v1/postsAPI 키 + 세션 토큰
PATCH / DELETE/v1/posts/:id세션 토큰(작성자만)
POST / DELETE/v1/posts/:id/like세션 토큰
POST/v1/posts/:id/report세션 토큰

작성 body: { project_id, content(이미지 있으면 생략 가능), parent_id?, image? }

  • image: data:image/...;base64,... data URL (디코드 기준 최대 2MB — SDK는 자동 압축)
  • 응답 Post에는 reply_count, image_url이 추가됩니다

Chat

1:1 DM + 오픈채팅방. 메시지·실시간은 방 종류와 무관하게 동일합니다. 모든 엔드포인트는 API 키(+origin) 그리고 패스포트 세션 토큰이 필요합니다(읽기 포함 — 방은 멤버만 봅니다).

메서드경로설명
POST/v1/chat/dm{ target_author_id } → 1:1 DM open-or-get
GET/v1/chat/users?q=&limit닉네임으로 사람 검색(새 DM 상대, 자기·차단 제외)
GET/v1/chat/rooms내 방 목록(DM + 가입 오픈방) + unread
POST/v1/chat/rooms{ name, category?, max_members?, duration_minutes? } → 오픈방 생성
GET/v1/chat/rooms/explore?category=&limit공개 오픈방 탐색(joined·member_count 포함)
POST/v1/chat/rooms/:id/join · /leave오픈방 참여(정원·만료 체크)/나가기
GET/v1/chat/rooms/:id/messages?cursor&limit메시지 히스토리(최신→과거 커서)
POST/v1/chat/rooms/:id/messages{ content } 전송
POST/v1/chat/rooms/:id/read읽음 워터마크 갱신
WS/v1/chat/rooms/:id/ws?token=실시간 구독(WebSocket) — 보통 SDK가 자동 처리
  • ChatRoomkind("dm" | "open")에 따라 peer(DM) 또는 name/category/member_count/max_members/expires_at(오픈방)을 가집니다. unread·joined는 요청자 기준.
  • ChatMessage: { id, room_id, author_id, nickname, content, is_deleted, created_at, mine }.
  • 실시간: 방마다 Durable Object가 새 메시지·타이핑을 연결된 소켓에 push합니다. WS URL의 token은 패스포트 세션 토큰(브라우저가 헤더를 못 보내므로 쿼리로 전달).
  • 운영자용 집계: GET /v1/projects/:id/chat-usage(세션) — 방·메시지·참여자 수만(대화 내용은 비공개).

제한

항목
작성 rate limitIP당 분당 10건 (comments·posts 각각)
content1–2000자
page_id≤512자
목록 limit1–100 (기본 20), next_cursor 커서 페이지네이션
모듈 게이트모듈 OFF 시 쓰기만 403 (읽기는 허용)
쿼터플랜 한도 초과 시 403 + 사유 메시지

파일

GET /v1/files/{key} — 업로드된 공개 이미지(포스트 첨부·서비스 아이콘)는 인증 없이 서빙됩니다. image_url이 이 경로를 가리킵니다.

Webhooks

이벤트 수신(아웃바운드)은 Webhooks 문서를 보세요 — payload envelope·서명 검증·재시도 규약.

On this page