API 레퍼런스
CaptchaLa는 모든 서버 측 통합을 위한 RESTful API 를 제공합니다.
Base URL
https://apiv1.captcha.laBase URL은 하나뿐
이 페이지의 모든 엔드포인트는 apiv1.captcha.la에 있습니다. 예비 호스트(bypass.*, fallbackapiv1.*)는 장애 시 SDK가 스스로 전환하는 페일오버 대상이며, 통합을 그쪽으로 향하게 하면 service_online이 반환됩니다.
인증
모든 API 요청에는 인증 헤더가 필요합니다:
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRETWARNING
X-App-Secret is server-side only. Never expose it to browsers, mobile apps, or public repos.
서버 측 검증 API
💡 서버 SDK로 보일러플레이트 생략. 엔드포인트·재시도·타입 에러를 래핑:
- PHP —
Captcha-La/captchala-php- Go —
go get github.com/Captcha-La/captchala-go
사용자가 프런트엔드 CAPTCHA 를 통과한 뒤, 서버는 SDK 가 반환한 token 을 검증해야 합니다. 아래는 서버 측 검증 엔드포인트입니다.
서버 측 Token 검증
프런트엔드 SDK 가 반환한 pass_token(pt_ 접두사)을 검증합니다. X-App-Key 와 X-App-Secret 헤더가 필요합니다.
POST /v1/validate
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
Content-Type: application/json
{ "pass_token": "pt_xxx", "client_ip": "1.2.3.4" }client_ip 는 선택 사항이지만 권장됩니다 — 백엔드로 들어온 요청에서 얻은 최종 사용자 IP 로, 추가 위험 검사에 사용됩니다. 생략해도 안전합니다.
{
"code": 0,
"data": {
"valid": true,
"challenge_id": "ch_xxx",
"action": "login",
"uid": null,
"captcha_args": {
"platform": "web",
"user_ip": "1.2.3.4",
"referer": "https://your-site.com/login",
"pkg": null,
"solved_at": 1750000000,
"risk_score": 12
}
}
}captcha_args 는 참고용 필드입니다(로깅이나 위험 분석용): platform, user_ip, referer, pkg, solved_at, risk_score.
TIP
Validate data.valid === true and that data.action matches the scene you expected (reject if a token from a pay flow is presented at /login). Tokens are single-use.
서버 발급 Challenge Token
백엔드에서 짧은 수명의 server_token 을 발급합니다. 브라우저는 challenge 초기화 시 이 token 을 전달하여 요청이 신뢰된 서버에서 왔음을 증명합니다.
Server Token 발급
이 엔드포인트는 자체 서버에서만 호출해야 합니다. X-App-Key + X-App-Secret 이 필요합니다. 응답에는 프런트엔드가 인증 초기화 으로 전달하는 server_token(sct_ 접두사)이 포함됩니다.
POST /v1/server/challenge/issue
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
Content-Type: application/x-www-form-urlencoded
action=login&ttl=300&max_uses=1&bind_ip=1.2.3.4{
"code": 0,
"data": {
"server_token": "sct_xxxxxxxxxxxx",
"expires_in": 300,
"issued_at": 1713600000
}
}본문 파라미터 (form-urlencoded)
| 필드 | 설명 |
|---|---|
action | 비즈니스 장면, 예: login, register, pay. 인증 초기화 에서 사용하는 action 과 일치해야 합니다. |
ttl | token 수명(초). 기본 300, 최대 900. |
max_uses | token 최대 사용 횟수. 기본 10. |
bind_ip | token 을 클라이언트 IP 에 바인딩합니다. 다른 IP 에서 초기화하면 거부됩니다. |
bind_device_id | token 을 특정 디바이스 id 에 바인딩합니다. |
bind_fingerprint | token 을 특정 브라우저 지문에 바인딩합니다. |
Challenge 초기화
SDK 가 CAPTCHA challenge 를 시작할 때 호출합니다. /v1/server/challenge/issue 에서 발급된 선택적 server_token 을 받을 수 있습니다.
| 필드 | 설명 |
|---|---|
app_key | 공개 App Key. |
action | 비즈니스 장면. server_token 발급 시 사용한 action 과 일치해야 합니다. |
server_token | 선택 사항이지만 앱에서 server_token_required = true 인 경우 필수입니다. |
INFO
대시보드에서 이 앱에 server_token_required 를 활성화한 경우, 인증 초기화 은 유효한 server_token 이 없는 요청을 거부합니다.
오프라인 폴백 엔드포인트
메인 API에 도달할 수 없는 동안에도 검증이 계속되도록 CaptchaLa는 별도 호스트에서 예비 서비스를 운영합니다.
| 호스트 | 호출 주체 | 용도 |
|---|---|---|
bypass.captchala.com · bypass.captcha-cdn.net | 웹 / 네이티브 SDK(최종 사용자 측) | 메인 API 장애 중 오프라인 검증을 수행하고 offline_ pass token 발급 |
fallbackapiv1.captchala.com · fallbackapiv1.captcha-cdn.net | 서버 SDK | offline_ 토큰 검증(POST /api/validate) |
이들은 페일오버 대상이지 대체 API가 아닙니다. SDK는 메인 API가 실제로 실패한 뒤에만 스스로 전환하고, 복구되면 자동으로 되돌아갑니다. 어떤 설정도 이 호스트를 가리켜서는 안 됩니다.
service_online(HTTP 503)
{ "code": -1, "error": "service_online", "message": "Main API is online, please use main API" }메인 API가 살아 있을 때 나오는 오류입니다. 예비 서비스는 장애 중에만 동작합니다. 요청이 https://apiv1.captcha.la가 아니라 bypass.*로 간 것이니 URL을 고치세요. 재시도로는 해결되지 않습니다.
흔한 원인:
| 원인 | 해결 |
|---|---|
SDK apiServer가 bypass 호스트로 설정됨 | https://apiv1.captcha.la로 되돌리거나 옵션을 제거해 SDK가 고르게 함 |
bypassServers를 직접 덮어씀 | 별도로 안내받은 경우가 아니면 덮어쓰기 제거 |
| 자체 HTTP 클라이언트가 bypass URL을 복사함(장애 중 devtools 등에서) | https://apiv1.captcha.la를 호출하고 페일오버는 SDK에 맡기세요. 예비 서비스는 일반 챌린지 트래픽을 받지 않습니다 |
| 로드밸런서 / 프록시 / DNS가 API 호스트를 재작성함 | 업스트림을 apiv1.captcha.la로 되돌림 |
TIP
서버 측 검증에도 폴백 호스트는 필요 없습니다. apiv1.captcha.la의 POST /v1/validate를 호출하면 되고, offline_ 토큰은 PHP / Go 서버 SDK가 백업 API로 자동 처리합니다.
오류 코드
| 코드 | 설명 |
|---|---|
invalid_app_key | 유효하지 않은 App Key |
invalid_app_secret | 유효하지 않은 App Secret |
challenge_expired | Challenge 만료 |
challenge_not_found | Challenge 를 찾을 수 없음 |
invalid_answer | 유효하지 않은 정답 |
token_expired | Token 만료 |
token_already_used | Token 이미 사용됨 |
token_not_found | Token 을 찾을 수 없음 |
quota_exceeded | 할당량 초과 |
rate_limited | 속도 제한됨 |
rate_limit_exceeded | 이 앱의 발급 요청이 너무 많습니다. 잠시 후 다시 시도하세요. |
service_online | 메인 API가 정상인 상태에서 요청이 오프라인 폴백 서비스로 전달됨. https://apiv1.captcha.la를 사용하세요 — 오프라인 폴백 엔드포인트 참고. |