Form ID

REST API

시크릿 키로 폼과 제출을 읽고, 제출을 스팸으로 옮기거나 되돌리고, 삭제하세요.

REST API로 서버에서 폼과 제출을 읽고, 제출을 스팸으로 옮기거나 되돌리고, 삭제할 수 있습니다. https://ikiform.com/api/v1에서 HTTPS로 JSON을 주고받습니다. OpenAPI 3.1 문서는 /api/v1/openapi.json에 있습니다.

제출 생성은 /api/v1에 포함되지 않습니다. 대신 시크릿 키와 함께 폼 엔드포인트로 POST하세요. 서버에서 보내기를 참고하세요.

API 키

대시보드의 API keys에서 키를 만드세요. 키는 하나의 워크스페이스에 속하며 그 워크스페이스만 볼 수 있습니다. 전체 키는 한 번만 표시되며, Ikiform은 해시만 저장합니다.

종류접두사용도
시크릿ik_sk_서버용. 선택한 스코프로 REST API를 호출하고, 제출을 생성할 수 있습니다.
퍼블리셔블ik_pub_브라우저용. 폼 제출만 할 수 있고, 키에 등록한 도메인에서만 작동합니다.

스코프

스코프허용 범위
forms:readGET /forms, GET /forms/:formId
submissions:readGET /submissions, GET /submissions/:id
submissions:writeDELETE /submissions/:id, POST /submissions/:id/spam과 /not-spam, 그리고 /f/:formId로 POST

인증

시크릿 키를 Bearer 토큰으로 보내세요. 이 API는 서버 간 통신 전용입니다. CORS 헤더를 보내지 않고 브라우저 프리플라이트에 405로 응답하므로, 시크릿 키는 웹 페이지에서 절대 작동하지 않습니다.

Terminal
curl https://ikiform.com/api/v1/forms \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"
  • 키가 없거나, 형식이 잘못되었거나, 알 수 없거나, 폐기되었거나, 만료되었으면 WWW-Authenticate: Bearer와 함께 401 unauthorized를 받습니다.
  • 퍼블리셔블 키는 403 forbidden(Publishable keys can only submit forms.)을 받습니다. 필요한 스코프가 없는 키는 메시지에 해당 스코프가 적힌 403 forbidden을 받습니다.
  • 응답은 Cache-Control: no-store와 함께 전송됩니다.

아래 SDK 예제는 모두 하나의 클라이언트를 공유합니다.

ikiform.ts
import { createClient } from "@ikiform/sdk";

const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY! });

요청 작성기

폼
Form ID
curl "https://ikiform.com/api/v1/submissions?form_id=frm_xxxxxxxxxxxxxxxx&status=received&limit=50" \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

서버에서 실행하세요. REST API는 브라우저 요청을 거부하므로 이 페이지에서는 보내지 않습니다.

엔드포인트

메서드경로스코프반환
GET/formsforms:read폼 목록
GET/forms/:formIdforms:read폼 조회
GET/submissionssubmissions:read제출 목록
GET/submissions/:idsubmissions:read제출 조회
POST/submissions/:id/spamsubmissions:write스팸으로 표시
POST/submissions/:id/not-spamsubmissions:write스팸 아님으로 표시
DELETE/submissions/:idsubmissions:write제출 삭제
GET/openapi.json없음OpenAPI 문서
GET/health없음{ "ok": true }

폼 목록

forms:read 스코프로 GET /forms.

  • 최신순입니다. limit(1~100, 기본값 25)과 cursor를 받습니다.
curl "https://ikiform.com/api/v1/forms?limit=10" \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

폼 조회

forms:read 스코프로 GET /forms/:formId.

  • 다른 워크스페이스의 폼 ID는 존재하지 않는 ID와 똑같이 404를 반환합니다.
curl https://ikiform.com/api/v1/forms/frm_xxxxxxxxxxxxxxxx \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

제출 목록

submissions:read 스코프로 GET /submissions.

파라미터값기본값
form_id폼 ID워크스페이스의 모든 폼
statusreceived 또는 spam둘 다
limit1~10025
cursor이전 페이지의 next_cursor첫 페이지
  • 최신순입니다. 다른 워크스페이스의 form_id는 오류 대신 빈 목록을 반환하므로 ID를 탐색할 수 없습니다.
curl "https://ikiform.com/api/v1/submissions?form_id=frm_xxxxxxxxxxxxxxxx&status=received&limit=50" \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

제출 조회

submissions:read 스코프로 GET /submissions/:id.

  • 다른 워크스페이스의 ID는 존재하지 않는 ID와 똑같이 404를 반환합니다.
curl https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3 \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

스팸으로 표시

submissions:write 스코프로 POST /submissions/:id/spam.

  • 수신된 제출을 스팸으로 옮기고, 폼의 submission_count를 줄이고, 대기 중인 웹훅 전송을 취소합니다.
  • 이미 스팸인 제출에 호출하면 변경 없이 그대로 반환합니다.
curl -X POST https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3/spam \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

스팸 아님으로 표시

submissions:write 스코프로 POST /submissions/:id/not-spam.

  • 제출을 다시 수신 상태로 옮기고, 스팸 점수와 사유를 지우고, 일치하는 모든 웹훅 엔드포인트로 submission.created를 보냅니다.
  • 수신 상태인 제출에 호출하면 변경 없이 그대로 반환합니다.
curl -X POST https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3/not-spam \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

제출 삭제

submissions:write 스코프로 DELETE /submissions/:id.

  • 제출과 그 웹훅 전송을 영구적으로 삭제합니다. 되돌릴 수 없습니다. 다시 삭제하면 404를 반환합니다.
curl -X DELETE https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3 \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

객체

객체는 object 필드가 있는 snake_case JSON입니다. 타임스탬프는 밀리초를 포함한 UTC 기준 ISO 8601입니다. 제출 ID는 시간순으로 정렬되며(sub_ 뒤에 26자), 폼 ID는 무작위입니다(frm_ 뒤에 16자).

폼 필드설명
statusactive, paused 또는 disabled
submission_count스팸을 제외한 수신 제출 수
제출 필드설명
statusreceived 또는 spam
fields저장된 값
metauser_agent, origin, referrer, country, subject, reply_to. 모든 키가 항상 있으며 어떤 값이든 null일 수 있습니다. IP 해시는 절대 반환하지 않습니다
spam.score, spam.reasons스팸 점수와 honeypot, origin_mismatch 같은 사유

페이지네이션

목록은 최신순이며 불투명 커서를 사용합니다.

  1. 커서 없이 요청합니다.
  2. has_more가 true이면 같은 필터와 함께 next_cursor를 cursor로 보냅니다.
  3. next_cursor가 null이면 멈춥니다.

새 제출이 들어와도 페이지는 안정적으로 유지됩니다. 새 제출은 첫 페이지에 나타나며, 뒤쪽 페이지에 중복으로 나타나지 않습니다. 커서를 직접 만들거나 파싱하지 마세요. 잘못된 커서는 400 invalid_request를 반환합니다.

for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx" })) {
  console.log(submission.id, submission.fields);
}

오류

오류는 폼 제출과 같은 형식을 사용합니다. 모든 응답에는 X-Request-Id 헤더가 있으며, 오류에는 이 값이 request_id로도 담깁니다.

403 Forbidden
{
  "ok": false,
  "error": { "code": "forbidden", "message": "This API key is missing the forms:read scope." },
  "request_id": "req_01k7v2c9t3e8m5q4x6z0a1b2c3"
}
상태코드발생 조건
400invalid_requestlimit, status, form_id, cursor 중 하나가 잘못됨. 메시지에 해당 항목이 표시됩니다
401unauthorized키가 없거나 잘못됨
403forbidden퍼블리셔블 키 또는 스코프 누락
404not_found알 수 없는 경로나 ID, 또는 다른 워크스페이스의 ID
405method_not_allowed브라우저 프리플라이트
429rate_limited키별 레이트 리밋 초과
500server_errorIkiform 쪽에서 문제가 발생함. request_id를 알려 주세요

레이트 리밋

키마다 60초에 100건의 요청을 보낼 수 있습니다. 한도를 넘으면 API는 초 단위의 Retry-After 헤더와 함께 429 rate_limited를 반환합니다. SDK에서는 error.retryAfter로 제공됩니다.