Polyrankdocs
Auth

POST /v1/auth/email/start

Mail a 6-digit code (10 minutes, 5 attempts) to confirm an email for the signed-in account. Always `{ ok: true, expires_in_seconds }` for a well-formed address, whether or not it already belongs to another account (an owner who CONFIRMED the address gets a notice instead of a code; an address that sits unconfirmed on another wallet account does not block the code, and the right code moves the address to the account that proved the inbox). The mail is sent after the response, so the answer never says whether it was delivered: to RESEND, call this route again; it mails a FRESH code and the previous one stops working. Rate-limited per caller, per account and per address over 5 minutes, and per account and per address over a DAY (10 codes each): a 429 carries `retry_after_seconds` and `Retry-After`. 404 `email_confirmation_disabled` while EMAIL_CONFIRMATION_ENABLED is off.

POST
/v1/auth/email/start

Mail a 6-digit code (10 minutes, 5 attempts) to confirm an email for the signed-in account. Always { ok: true, expires_in_seconds } for a well-formed address, whether or not it already belongs to another account (an owner who CONFIRMED the address gets a notice instead of a code; an address that sits unconfirmed on another wallet account does not block the code, and the right code moves the address to the account that proved the inbox). The mail is sent after the response, so the answer never says whether it was delivered: to RESEND, call this route again; it mails a FRESH code and the previous one stops working. Rate-limited per caller, per account and per address over 5 minutes, and per account and per address over a DAY (10 codes each): a 429 carries retry_after_seconds and Retry-After. 404 email_confirmation_disabled while EMAIL_CONFIRMATION_ENABLED is off.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/auth/email/start" \  -H "Content-Type: application/json" \  -d '{    "email": "[email protected]"  }'
{  "ok": true,  "already_confirmed": true,  "expires_in_seconds": 1,  "dev_code": "string"}
{  "error": "string",  "message": "string",  "feature": "string",  "field": "string",  "plan": "string",  "retry_after_sec": 0,  "retry_after_seconds": 0,  "reason": "string",  "issues": [    null  ],  "trace_id": "string"}
{  "error": "string",  "message": "string",  "feature": "string",  "field": "string",  "plan": "string",  "retry_after_sec": 0,  "retry_after_seconds": 0,  "reason": "string",  "issues": [    null  ],  "trace_id": "string"}
{  "error": "string",  "message": "string",  "feature": "string",  "field": "string",  "plan": "string",  "retry_after_sec": 0,  "retry_after_seconds": 0,  "reason": "string",  "issues": [    null  ],  "trace_id": "string"}
{  "error": "string",  "message": "string",  "feature": "string",  "field": "string",  "plan": "string",  "retry_after_sec": 0,  "retry_after_seconds": 0,  "reason": "string",  "issues": [    null  ],  "trace_id": "string"}
{  "error": "string",  "message": "string",  "feature": "string",  "field": "string",  "plan": "string",  "retry_after_sec": 0,  "retry_after_seconds": 0,  "reason": "string",  "issues": [    null  ],  "trace_id": "string"}
{  "error": "string",  "message": "string",  "feature": "string",  "field": "string",  "plan": "string",  "retry_after_sec": 0,  "retry_after_seconds": 1,  "reason": "string",  "issues": [    null  ],  "trace_id": "string"}
{  "error": "string",  "message": "string",  "feature": "string",  "field": "string",  "plan": "string",  "retry_after_sec": 0,  "retry_after_seconds": 0,  "reason": "string",  "issues": [    null  ],  "trace_id": "string"}

PATCH /v1/auth/me PATCH

Update the current user’s display name, email, and/or X handle. With EMAIL_CONFIRMATION_ENABLED=1 this route never sets an address: `email: <address>` is a 409 `conflict` with `reason: use_email_code` (confirm it with POST /v1/auth/email/start and /verify; an address equal to the account’s current email is ignored). `email: null` removes the email (and any pending one) as before; the previous address gets a notice.

POST /v1/auth/email/verify POST

Check the 6-digit code from POST /v1/auth/email/start. On success the address is the account's confirmed email. A failure is a 400 `email_code_failed` with `reason`: `invalid_code` (with `attempts_left`), `expired`, `too_many_attempts` (after 5: ask for a new code), `no_pending`, or `unavailable` (the right code, but another account confirmed the address meanwhile). Wrong codes are also capped per DAY (20 per account, 20 per address): past a cap the answer is a 429 `email_code_failed`. Past the ACCOUNT's cap the `reason` is `rate_limited`, with `retry_after_seconds` and `Retry-After`: nothing is compared and the code keeps its attempts. Past the ADDRESS's cap (other accounts can spend it) a code that was never tried is still compared once, so the right code of a FRESH start passes; any other try (a code that was already tried, or a wrong first try) is a 429 with `reason` `new_code_required` and no `retry_after_seconds` or `Retry-After`: that code can no longer be used, and the remedy is a new code from POST /v1/auth/email/start, not a wait. A code that was already tried is refused without being compared and without costing it an attempt.