Skip to main content
The verification flow enables users to verify their email addresses or phone numbers. Verification typically works by sending a verification link or code to the address.

Initialize verification flow for browsers

curl -X GET 'https://your-project.projects.oryapis.com/self-service/verification/browser' \
  -H 'Accept: application/json'

Endpoint

GET /self-service/verification/browser
Initializes a browser-based account verification flow. Once initialized, the browser is redirected to the verification UI.

Query parameters

return_to
string
URL to redirect the browser to after successful verification.

Response

id
string
required
The flow ID, used to fetch and submit the flow.
type
string
required
The flow type: browser or api.
expires_at
string
required
Time when this flow expires (RFC3339 format).
issued_at
string
required
Time when this flow was issued (RFC3339 format).
request_url
string
required
The original request URL.
state
string
required
Current state of the flow: choose_method, sent_email, or passed_challenge.
ui
object
required
UI container with form fields and messages.

Status codes

StatusDescription
200Verification flow created (AJAX requests)
303Redirect to verification UI with flow ID
400Already authenticated user trying to verify

Initialize verification flow for native apps

curl -X GET 'https://your-project.projects.oryapis.com/self-service/verification/api' \
  -H 'Accept: application/json'

Endpoint

GET /self-service/verification/api
Initializes a verification flow for native apps. Use this for mobile apps, smart TVs, and other non-browser clients.
Do NOT use this endpoint in browser-based applications. Use /self-service/verification/browser instead to prevent CSRF attacks.

Query parameters

return_to
string
URL for informational purposes. This has no effect on the flow logic.

Response

Returns the same verification flow object as the browser endpoint.

Status codes

StatusDescription
200Verification flow created successfully
400Invalid request

Get verification flow

curl -X GET 'https://your-project.projects.oryapis.com/self-service/verification/flows?id=flow-id' \
  -H 'Accept: application/json'

Endpoint

GET /self-service/verification/flows
Returns a verification flow’s context with error details and other information.

Query parameters

id
string
required
The verification flow ID from the flow URL query parameter.

Headers

HTTP Cookie header for browser flows. Required for CSRF validation.

Response

Returns the verification flow object.

Status codes

StatusDescription
200Verification flow found
403Forbidden (CSRF violation)
404Flow not found

Submit verification flow

The verification flow has multiple states, each requiring different submissions:

Choose method state

Submit the email address to send a verification link or code.
curl -X POST 'https://your-project.projects.oryapis.com/self-service/verification?flow=flow-id' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{
    "method": "link",
    "email": "[email protected]",
    "csrf_token": "token-from-flow"
  }'

Sent email state

Submit the verification code received via email.
curl -X POST 'https://your-project.projects.oryapis.com/self-service/verification?flow=flow-id' \
  -H 'Content-Type: application/json' \
  -d '{
    "method": "code",
    "code": "123456",
    "csrf_token": "token-from-flow"
  }'

Endpoint

POST /self-service/verification
Completes a verification flow by verifying the email address.

Query parameters

flow
string
required
The verification flow ID.
token
string
Verification token from the verification link (used in passed_challenge state).

Headers

HTTP Cookie header for browser flows.

Request body

method
string
required
Verification method: link or code.
email
string
Email address to verify (required in choose_method state).
code
string
Verification code (required when submitting code in sent_email state).
csrf_token
string
CSRF token from the flow (required for browser flows).

Response

state
string
required
Updated flow state.
ui
object
required
Updated UI with messages and form fields.

Response (browser flows)

Browser flows behave differently: In choose_method state:
  • 200 OK with updated flow (API/AJAX)
  • 303 redirect to verification UI (browser)
In sent_email state:
  • 200 OK with updated flow (API/AJAX)
  • 303 redirect to verification UI with success message (browser)
In passed_challenge state (valid verification link):
  • 303 redirect to configured success URL or settings UI
In passed_challenge state (invalid verification link):
  • 303 redirect to verification UI with error message

Status codes

StatusDescription
200Flow updated successfully
303Redirect (browser flows)
400Form validation errors
410Flow expired

Verification flow states

The verification flow progresses through these states:
  1. choose_method - User selects verification method and provides email
  2. sent_email - Verification email sent, user can submit code or request another
  3. passed_challenge - User clicked verification link or submitted valid code

Error responses

Common validation errors:
  • email is required - No email provided
  • Could not find email - Email not found
  • Verification token is invalid - Token expired or already used
  • The verification code is invalid - Code is incorrect or expired
  • security_csrf_violation - CSRF token validation failed

Build docs developers (and LLMs) love