Form ID

문제 해결

CORS 오류, 출처 불일치, challenge_required, 429, 알 수 없는 필드, 할당량 오류 해결 방법.

응답부터 확인하세요. Ikiform의 모든 응답에는 X-Request-Id 헤더가 있고, 오류에는 바뀌지 않는 error.code가 있습니다. 다음 curl은 여러분의 사이트가 보낼 것과 같은 출처에서 둘 다 보여 줍니다.

Terminal
curl -i https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Origin: https://example.com" \
  -d '{"email":"ada@example.com"}'

Ikiform 자체에서 5xx 오류나 시간 초과가 발생하나요? 먼저 status.ikiform.com에서 현재 장애를 확인하세요.

브라우저에서 CORS가 요청을 막았다고 나올 때

제출 엔드포인트는 모든 출처를 허용하므로, 실제 CORS 오류는 대개 요청이 Ikiform에 닿지 않았거나 잘못된 URL로 갔다는 뜻입니다.

  • URL이 frm_xxxxxxxxxxxxxxxx처럼 전체 frm_ ID를 포함한 https://ikiform.com/f/<formId>이고 뒤에 경로가 붙지 않았는지 확인하세요.
  • 브라우저에서 /api/v1을 호출하고 있습니다. REST API는 설계상 브라우저 요청을 거부하므로 서버에서 호출하세요.
  • 광고 차단기, 개인정보 보호 확장 프로그램, 회사 프록시가 요청을 막았습니다. 확장 프로그램 없이 시크릿 창에서 시도해 보세요.
  • 사이트 자체의 Content-Security-Policy가 막고 있습니다. connect-src에 https://ikiform.com을 추가하고, 일반 HTML POST라면 form-action에도 추가하세요.

프리플라이트를 직접 확인하세요. 여러분의 출처를 그대로 돌려주며 204로 응답해야 합니다.

Terminal
curl -i -X OPTIONS https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
  -H "Origin: https://example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: content-type"

제출이 origin_mismatch로 스팸에 들어갈 때

폼에 허용 도메인이 있는데 POST가 다른 곳에서 왔습니다. 대시보드의 스팸 사유에 origin_mismatch가 표시됩니다.

  • www, 스테이징, 미리보기 도메인을 포함해 폼이 제공되는 모든 도메인을 추가하세요. 등록한 도메인의 하위 도메인은 이미 일치합니다.
  • 로컬에서 개발하는 동안에는 localhost를 추가하세요.
  • 여러분의 서버에서 보낸 POST에는 Origin이 없습니다. 이 검사를 건너뛰는 시크릿 키를 보내세요.
  • Mark as spam 대신 Reject를 골랐다면 같은 POST가 403 origin_not_allowed를 받습니다.

403 challenge_required

폼의 스팸 검사가 Ikiform으로 설정되어 있는데 POST에 Turnstile 토큰이 없었습니다.

  1. 브라우저 코드: 제출 직전마다 SDK의 challenge(formId)를 호출하고, 토큰을 submit에 turnstileToken으로 전달하세요.
  2. 서버 코드: 시크릿 키로 Authorization: Bearer ik_sk_...를 보내세요. 시크릿 키는 확인을 건너뜁니다.
  3. 일반 HTML POST는 이 코드를 받지 않고 대신 확인 페이지를 받습니다. 폼 POST에서 이 코드가 나온다면 무언가가 Accept: application/json을 보내고 있는 것입니다.
  4. curl로 테스트하고 있나요? 테스트용 폼에서는 확인을 끄거나 시크릿 키를 사용하세요.

403 captcha_failed는 토큰을 보냈지만 검증되지 않았다는 뜻입니다. 토큰은 한 번만 쓸 수 있고 300초 후 만료되므로 시도할 때마다 새로 받으세요.

429 rate_limited

  • Retry-After를 읽고 그 초만큼 기다리세요.
  • 직접 손으로 테스트하고 있나요? Standard 프리셋은 IP 하나에서 분당 5건, 10초에 3건을 허용합니다. 테스트용 폼은 Relaxed로 바꾸세요.
  • 방문자마다 서버에서 POST하고 있나요? 모든 POST가 서버의 IP를 공유합니다. 브라우저에서 POST하거나 Relaxed 또는 Custom을 고르세요.
  • 같은 사무실이나 이벤트 네트워크를 쓰는 많은 사람도 IP를 공유합니다. Relaxed는 분당 20건을 허용합니다.

Unknown field와 함께 422가 나올 때

폼에 필드가 정의되어 있는데 POST에 정의에 없는 이름이 있습니다. error.fields에 그 이름이 표시됩니다. 예: { "website": ["Unknown field \"website\""] }.

  • 필드를 정의에 추가하거나 입력을 제거하세요.
  • 여러분만 쓰는 표시용 입력이라면 이름이 _로 시작하도록 바꾸세요. 예약된 이름은 검증하지 않고 제거됩니다.
  • 허니팟 이름이 폼의 Honeypot field 설정과 일치하는지 확인하세요.
  • 필드 ID는 소문자 snake_case입니다. 마크업의 firstName은 정의의 first_name과 같지 않습니다.

429 quota_exceeded

워크스페이스가 이번 달에 월간 한도의 2배를 받아, 다음 달이 시작되거나 워크스페이스가 업그레이드할 때까지 제출을 받지 않습니다. 월간 사용량을 참고하세요.

제출이 보이지 않을 때

  • 스팸 필터를 확인하세요. 스팸도 정상적인 성공 응답을 받으므로 방문자는 알 수 없습니다.
  • 폼이 일시 중지되지 않았는지, action의 ID가 대시보드와 일치하는지 확인하세요.
  • 브라우저 POST에서 Ikiform의 오류 페이지가 나왔다면 거부된 것입니다. 페이지에 이유가 표시됩니다.

웹훅이 실패할 때

  • no_matching_signature: JSON을 파싱하기 전의 원본 본문으로 검증하고, 올바른 whsec_ 시크릿을 복사했는지 확인하세요. 전송을 검증기에 붙여 넣어 보세요.
  • timestamp_too_old: 서버 시계가 맞지 않거나, 예전 전송을 재생하고 있습니다.
  • 시간 초과: 15초 안에 응답하고 오래 걸리는 작업은 그 뒤에 처리하세요.
  • 리디렉션은 따르지 않습니다. 프레임워크가 기대하는 끝의 슬래시까지 포함한 최종 URL을 사용하세요.
  • 5일 동안 실패했거나 410을 받아 엔드포인트가 비활성화되었습니다. 문제를 고친 뒤 엔드포인트 페이지에서 다시 켜세요.