SMS PIN verification
The start to verify handshake that lets a phone-verified visitor submit an SMS PIN form.
SMS PIN verification
When a form's login_modes includes sms_pin, an unauthenticated visitor proves they control a phone number before submitting. The flow is a two-call handshake: start sends a 6-digit code by SMS, verify checks it and returns a smsPinToken you attach to the submit.
Flow
- Start - POST a phone number plus a Turnstile token. The API generates a 6-digit code, stores it for 10 minutes, and texts it to the phone via the owner's SMS key.
- Verify - POST the phone number and the code. On success you get
smsPinToken. - Submit - call
/submitwithsmsPinTokenandsmsPinPhone. The token both satisfies thesms_pinlogin mode and exempts the submit from captcha.
The verified marker is good for 30 minutes after verify, so do the submit promptly.
Start verification
https://forms.hep.gg/api/v1/forms/public/:slug/sms/startPublicOnly works when the form accepts sms_pin. A Cloudflare Turnstile token is mandatory on every start. The endpoint is rate limited per form and per IP: a burst limit of 3 sends per 60 seconds and a daily limit of 12 sends per 24 hours.
phone^\+?[0-9]{7,16}$ (an optional leading +, then 7 to 16 digits). Use full international format, for example +14155550101.turnstileToken{ "ok": true, "data": { "sent": true } }Start errors
| Status | When | error |
|---|---|---|
| 400 | Phone fails the format check | Invalid phone number |
| 400 | Turnstile token missing or rejected | Captcha verification failed |
| 400 | Form does not accept sms_pin | This form doesn't support SMS PIN |
| 404 | Form not found | Form not found |
| 429 | Burst limit (3 / 60s); includes Retry-After | Slow down. Try again in Ns. |
| 429 | Daily limit (12 / 24h) | Too many verification codes from this connection today. |
| 502 | The SMS send failed downstream | Could not send verification code |
| 503 | The form owner has no enabled SMS key | Form owner hasn't set up SMS |
Verify the code
https://forms.hep.gg/api/v1/forms/public/:slug/sms/verifyPublicConfirms the 6-digit code. On success the code is consumed, a 30-minute verified marker is set, and you receive the smsPinToken to carry into the submit.
phonestart.codeverifiedtrue on success.smsPinTokensmsPinToken in the submit body. Also pass the phone as smsPinPhone.Verify errors
| Status | When | error |
|---|---|---|
| 400 | Phone or code missing | Phone and code required |
| 401 | Code wrong or expired (10-minute window) | Code is invalid or expired |
| 404 | Form not found | Form not found |