Everything an AI agent can do with the Stytch API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints29
API versionv1
Last updated23 June 2026
Orientation

How the Stytch API works.

The Stytch API is how an app or AI agent adds login to a product: sending a magic link or one-time passcode, checking a password, creating and looking up users, and validating or revoking their sessions. Access is granted through a project ID and secret that authenticate every call, and those credentials are project-wide, so a key that can call one method can call them all. Stytch serves a single v1 surface, split into a Consumer product and a B2B product, and can push a signed event to a webhook when a user changes.

29Endpoints
10Capability groups
6Read
23Write
21Permissions
Authentication
Stytch authenticates every server call with HTTP Basic auth: the project ID as the username and the secret as the password, both taken from the Project & API keys page in the Dashboard. There is a separate test environment and live environment, each with its own project ID and secret, and objects never cross between them. A public token is used for browser-initiated redirect flows like OAuth start, not for server calls.
Permissions
Stytch keys are project-level and environment-level. There are no granular per-endpoint scopes, so a project secret can call any method the project's enabled products expose. This makes per-method control the job of the layer in front of the key, not the key itself. The Connected Apps product issues separate OAuth tokens for end-user authorization, but those are a feature an app builds, not a scope on the project secret.
Products
The API is split into a Consumer product (users, one user pool per project) and a B2B / multi-tenant product (organizations, with members scoped to each organization). Paths under /v1 cover the shared authentication methods, B2B paths sit under /v1/b2b, and the two have separate data models. A project is set up as one or the other.
Data model
Stytch is JSON over HTTPS at api.stytch.com (live) and test.stytch.com (test). Most methods are a POST, including reads like Search Users, while single-object fetches and the JWKS endpoint are a GET. Every response carries a request_id for debugging, and an error returns a status_code, an error_type, an error_message, and an error_url.
Connect & authenticate

Connection & authentication methods.

How an app or AI agent connects to Stytch determines what it can reach. There is a route for making calls and a route for receiving events, and each is governed by the project credentials behind it.

Ways to connect

REST API

The REST API takes JSON request bodies and returns JSON over HTTPS, at https://api.stytch.com for live and https://test.stytch.com for test. A call authenticates with HTTP Basic auth, the project ID as the username and the secret as the password. Most methods are a POST, including reads like Search Users; single-object fetches and the JWKS endpoint are a GET. B2B methods live under the /v1/b2b path prefix.

Best forConnecting an app or AI agent to Stytch.
Governed byThe project ID and secret, which carry full project access.
Docs ↗

Webhooks

Stytch delivers webhooks through Svix to an HTTPS endpoint configured in the Dashboard, for events named source.object_type.action such as direct.user.create or dashboard.member.update. The receiver verifies the signature with Svix's libraries before trusting the payload. Delivery is not strictly ordered, so Stytch recommends treating an event as a signal to re-fetch the affected object.

Best forReceiving Stytch events at an app or AI agent.
Governed byThe Svix signing secret on the endpoint.
Docs ↗
Authentication

Project ID + secret (Basic auth)

Every server call authenticates with HTTP Basic auth: the project ID as the username and the secret as the password, both from the Project & API keys page. The secret is project-wide and environment-wide, so it can call any method the project's enabled products expose, with no per-endpoint scoping. A secret must stay server-side and is shown in full only in the Dashboard.

TokenBasic auth (project_id : secret)
Best forServer-side calls to the Stytch API.
Docs ↗

Public token

A public token identifies the project in browser-initiated redirect flows, like the OAuth start URL, and is safe to expose in front-end code. It cannot make authenticated server calls or read user data on its own; it only kicks off a flow that the server then completes with the secret.

TokenPublic token (in redirect URLs)
Best forClient-side OAuth and redirect start flows.
Docs ↗

Connected Apps (OAuth)

Connected Apps turns a Stytch project into an OAuth 2.0 authorization server so an app can let its own end users grant scoped access to client apps, including MCP clients, via the authorization_code grant. The access tokens are JWTs the app validates by introspection. This authorizes end users of an app built on Stytch; it is not a scope on the project secret that calls the Stytch API.

TokenOAuth access token (JWT), issued to end users
Best forLetting an app's own users authorize client and MCP apps.
Docs ↗
Capability map

What an AI agent can do in Stytch.

The Stytch API is split into authentication products an agent can act on, like magic links, one-time passcodes, passwords, sessions, and users. Each product has its own methods, and writes here create users, end sessions, or send login codes to real people.

Magic Links

4 endpoints

Methods for sending and authenticating email magic links, plus server-created embeddable links.

A write here sends a login link to a real inbox or mints a token that logs someone in.
View endpoints

One-Time Passcodes (OTP)

3 endpoints

Methods for sending and authenticating one-time passcodes over SMS and email.

A write here sends a code to a real phone or inbox, and SMS sends can cost money.
View endpoints

Passwords

4 endpoints

Methods for creating, authenticating, and resetting password-based logins.

A write here sets or resets a credential and can revoke a user's sessions.
View endpoints

Sessions

4 endpoints

Methods for authenticating, listing, and revoking user sessions, plus the JWKS for verifying JWTs.

A revoke here immediately logs a user out everywhere.
View endpoints

Users

5 endpoints

Methods for creating, fetching, updating, deleting, and searching users.

A write here creates or changes a person's account, and a delete is permanent.
View endpoints

OAuth

2 endpoints

The redirect start flow for social and enterprise providers, and the method that completes it.

Authenticate here logs a user in from a completed third-party flow.
View endpoints

TOTP

2 endpoints

Methods for setting up and verifying authenticator-app (time-based) one-time passwords.

A create here issues a secret and recovery codes for a second factor.
View endpoints

WebAuthn / Passkeys

2 endpoints

Methods for registering and authenticating passkeys and hardware authenticators.

A write here binds or uses a passkey credential for a user.
View endpoints

Machine-to-Machine (M2M)

1 endpoint

The token endpoint that issues access tokens to M2M clients.

A token here grants a machine client access for its lifetime.
View endpoints

Organizations (B2B)

2 endpoints

B2B / multi-tenant methods for creating and fetching organizations.

A write here creates a tenant in a multi-tenant project.
View endpoints
Endpoint reference

Every Stytch API method.

Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.

MethodEndpointWhat it doesAccessPermissionVersion
Methods for sending and authenticating email magic links, plus server-created embeddable links.4

No per-endpoint scope exists; the project secret can call this. Shares a rate-limit counter with send, login_or_create, and invite (1 request/second/email).

Acts onmagic_link
Permission (capability)magic_links:send
VersionAvailable since the API’s base version
Webhook eventNone
Rate limit1/second/email (shared with login_or_create and invite)

Can create a user, firing a user.create event. No per-endpoint scope; project secret calls it.

Acts onmagic_link
Permission (capability)magic_links:send
VersionAvailable since the API’s base version
Webhook eventuser.create
Rate limit1/second/email (shared with send and invite)

Returns a sensitive token that logs a user in; default 60-minute expiry, settable 5 to 10080 minutes.

Acts onmagic_link
Permission (capability)magic_links:create
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A used or expired token returns a 401 (unable_to_auth_magic_link).

Acts onmagic_link
Permission (capability)magic_links:authenticate
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

One-Time Passcodes (OTP)

Methods for sending and authenticating one-time passcodes over SMS and email.3

Sends a real SMS; codes expire after 2 minutes. Test environments cap SMS send at 60/hour/project.

Acts onotp
Permission (capability)otps:send
VersionAvailable since the API’s base version
Webhook eventNone
Rate limit60/hour/project (test environment)

Can create a user, firing a user.create event. Codes expire after 2 minutes.

Acts onotp
Permission (capability)otps:send
VersionAvailable since the API’s base version
Webhook eventuser.create
Rate limitStandard limits apply

A reused or expired code returns a 401 (unable_to_auth_otp_code).

Acts onotp
Permission (capability)otps:authenticate
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Passwords

Methods for creating, authenticating, and resetting password-based logins.4

Password must meet strength rules; a duplicate email returns a 400 (duplicate_email).

Acts onpassword
Permission (capability)passwords:create
VersionAvailable since the API’s base version
Webhook eventuser.create
Rate limitStandard limits apply

Can return a reset_password error if the password appears in a breach database.

Acts onpassword
Permission (capability)passwords:authenticate
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Sends a real email containing a reset link.

Acts onpassword
Permission (capability)passwords:reset
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A successful reset revokes all of the user's active sessions.

Acts onpassword
Permission (capability)passwords:reset
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Sessions

Methods for authenticating, listing, and revoking user sessions, plus the JWKS for verifying JWTs.4

Can extend the session lifetime if session_duration_minutes is supplied, so it is a write.

Acts onsession
Permission (capability)sessions:authenticate
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only; returns every active session for the user.

Acts onsession
Permission (capability)sessions:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Immediately logs the user out for that session; requires exactly one identifier.

Acts onsession
Permission (capability)sessions:revoke
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only; keys rotate roughly every 6 months, with both returned for a month around a rotation.

Acts onjwks
Permission (capability)sessions:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Users

Methods for creating, fetching, updating, deleting, and searching users.5

Creates an account and fires a user.create event.

Acts onuser
Permission (capability)users:write
VersionAvailable since the API’s base version
Webhook eventuser.create
Rate limitStandard limits apply

Read-only; returns the user's factors, contact info, and metadata.

Acts onuser
Permission (capability)users:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

New email or phone factors are added via the relevant /send endpoint, not here.

Acts onuser
Permission (capability)users:write
VersionAvailable since the API’s base version
Webhook eventuser.update
Rate limitStandard limits apply

Irreversible; fires a user.delete event.

Acts onuser
Permission (capability)users:write
VersionAvailable since the API’s base version
Webhook eventuser.delete
Rate limitStandard limits apply

A POST that reads; pages results with next_cursor.

Acts onuser
Permission (capability)users:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

OAuth

The redirect start flow for social and enterprise providers, and the method that completes it.2

A browser redirect started with the public token, not a server call; returns a token to authenticate.

Acts onoauth
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Returns provider access and refresh tokens alongside the session.

Acts onoauth
Permission (capability)oauth:authenticate
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

TOTP

Methods for setting up and verifying authenticator-app (time-based) one-time passwords.2

Issues a shared secret and recovery codes; an active TOTP already present returns active_totp_exists.

Acts ontotp
Permission (capability)totps:create
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Verifies a second-factor code.

Acts ontotp
Permission (capability)totps:authenticate
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

WebAuthn / Passkeys

Methods for registering and authenticating passkeys and hardware authenticators.2

Requires user_id and domain; returns options for navigator.credentials.create().

Acts onwebauthn
Permission (capability)webauthn:register
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Takes the result of navigator.credentials.get() and can start a session.

Acts onwebauthn
Permission (capability)webauthn:authenticate
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Machine-to-Machine (M2M)

The token endpoint that issues access tokens to M2M clients.1

Takes client_id, client_secret, and grant_type=client_credentials; returns a JWT access token.

Acts onm2m_token
Permission (capability)m2m:token
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Organizations (B2B)

B2B / multi-tenant methods for creating and fetching organizations.2

B2B projects only; creates a tenant and fires an organization.create event.

Acts onorganization
Permission (capability)organizations:write
VersionAvailable since the API’s base version
Webhook eventorganization.create
Rate limitStandard limits apply

Read-only; B2B projects only.

Acts onorganization
Permission (capability)organizations:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply
No endpoints match those filters.
Webhooks

Webhook events.

Stytch can notify an app when something changes, like a user being created, updated, or deleted. It delivers a signed event describing what happened through its webhook infrastructure, so an integration learns about activity without polling.

EventWhat it signalsTriggered by
{source}.user.createA user was created in a Consumer project, by API, SDK, or the Dashboard. The source segment names where it came from, like direct or dashboard./v1/users
/v1/magic_links/email/login_or_create
/v1/otps/email/login_or_create
{source}.user.updateA user's attributes changed, like name, metadata, or factors./v1/users/{user_id}
{source}.user.deleteA user was deleted from the project./v1/users/{user_id}
{source}.organization.createAn organization was created in a B2B (multi-tenant) project./v1/b2b/organizations
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

Stytch limits how fast an app can call, scoped by a field such as an email address, a phone number, or the project as a whole, and assessed over a fixed interval.

Request rate

Stytch rate-limits by a field over a fixed interval, not by a per-method point cost. The field is the identifier a limit is counted against, such as a specific email address, a phone number or its prefix, a Stytch user_id, or the project_id as a whole, so abuse against one email does not exhaust the whole project. Several endpoints share one counter: the Email Magic Link send, login_or_create, and invite methods together allow one request per second per email. Intervals are fixed windows aligned to the top of the hour or minute, not rolling. Test environments carry different, lower limits than live, for example SMS OTP send is 60 per hour per project in test. Going over returns HTTP 429 with error_type too_many_requests, and Stytch does not return headers naming which specific limit was hit, so the fix is exponential backoff plus spreading load across distinct fields.

Pagination

List-style methods that can return many objects, like Search Users, use a results_metadata block with a next_cursor. A request passes that cursor back to fetch the next page, and a null next_cursor means there are no more results. Single-object reads and small fixed lists, like Get Sessions for one user, return the full set without a cursor.

Request size

Search Users accepts a limit on results per page (commonly up to a few hundred per page) and pages the rest through the cursor. Tokens carry their own lifetimes rather than size caps: a magic link defaults to 60 minutes and can be set from 5 to 10080 minutes, an embeddable magic link token to the same range, and an OTP code expires after 2 minutes. A user's external_id may be up to 128 characters.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
400duplicate_email / bad_requestThe request was malformed or conflicts with existing data, for example duplicate_email when a user with that email already exists, or a missing or invalid parameter.Read error_message and error_url, fix the parameters or resolve the conflict, and resend. The request is not retryable as-is.
401unauthorized_credentialsThe project ID and secret were invalid, an incorrect password was supplied to a password authenticate, or a session token, magic link, or OTP was invalid or expired.Confirm the project ID and secret belong to the same project and environment, or send the user a fresh link, code, or login. Rotate the secret if it may be compromised.
403forbiddenThe credentials are valid but the action is not permitted for this project or environment, for example a product that is not enabled or an SDK-disallowed endpoint.Enable the relevant product in the Dashboard, or call the method from the server rather than the frontend SDK.
404not_foundThe requested object does not exist, or is not visible to this project or environment, for example an unknown user_id.Verify the ID and confirm it belongs to the same project and the same test or live environment.
429too_many_requestsA rate limit was hit for a field over its interval, such as too many sends to one email or phone number. Stytch does not return headers naming which specific limit was hit.Back off with exponential backoff, and spread load across distinct fields rather than hammering one email, phone, or the project.
500internal_server_errorA rare error on Stytch's side.Retry with backoff, and contact Stytch support if it persists.
Versioning & freshness

Version history.

Stytch serves a single v1 API and ships changes continuously rather than minting dated versions, splitting its surface into a Consumer product and a B2B (multi-tenant) product.

Version history

What changed, and when

Latest versionv1
v1Current version
Stytch v1 API (continuously updated)

Stytch serves a single, unversioned v1 API and ships changes continuously through its changelog rather than minting dated versions. The surface is split into a Consumer product and a B2B (multi-tenant) product, each with its own data model, and new authentication products and methods are added over time. The entries below are notable dated additions, newest first.

What changed
  • There is one v1 surface; additions and deprecations arrive through the changelog, not new version strings.
2026-01-16Feature update
Email Risk API (beta)

An Email Risk API launched in beta to score fraud risk from characteristics of an email address.

2025-11-07Feature update
SSO Migration Gateway (beta)

An SSO Migration Gateway entered beta for moving an existing SSO setup onto Stytch's platform with less disruption.

2025-10-17Feature update
Client ID Metadata Documents (CIMD)

Support for Client ID Metadata Documents was added, a standard for sharing OAuth client metadata securely.

2025-09-09Feature update
Connected Apps expanded for OAuth and AI agents

Connected Apps was expanded to layer onto any existing authentication system, enabling OAuth and AI agent (MCP) authorization flows.

2025-09-26Feature update
Device Fingerprinting raw signals

A raw signals feature was added to Device Fingerprinting, exposing low-level device and browser data.

There is one v1 surface; track the changelog for additions and deprecations.

Stytch changelog ↗
Questions

Stytch API, answered.

How does an app authenticate to the Stytch API?+
Every server call uses HTTP Basic auth with the project ID as the username and the secret as the password, both from the Project & API keys page in the Dashboard. A common shorthand in curl is -u 'PROJECT_ID:SECRET'. Test and live are separate environments with separate credentials, and a call always runs against the environment whose key it carries.
Can a Stytch key be scoped to just some endpoints?+
No. Stytch keys are project-level and environment-level, with no granular per-endpoint scopes. A project secret can call any method the project's enabled products expose, so limiting an agent to, say, reading users but not deleting them has to be enforced by the layer in front of the key. Stytch's Connected Apps issues OAuth tokens for end-user authorization, but that is a product an app builds for its own users, not a way to scope the project secret.
What is the difference between the Consumer and B2B APIs?+
A Stytch project is either Consumer or B2B. Consumer has a single pool of users per project; B2B (multi-tenant) adds organizations, and members belong to a specific organization. The shared authentication methods live under /v1, while B2B-specific methods live under /v1/b2b, and the two have different data models. Pick the one that matches whether the product serves individual end users or companies.
Does Stytch send webhooks?+
Yes. Stytch delivers webhooks through Svix for events structured as source.object_type.action, for example direct.user.create, dashboard.member.update, or a user delete. The receiver verifies the signature using Svix's libraries before trusting the payload. Because delivery is not strictly ordered, Stytch recommends treating a webhook as a signal to re-fetch the affected object from the API rather than relying only on the payload.
Does Stytch have an official MCP server for its own API?+
Not for calling the Stytch API itself. Stytch ships an MCP authorization product: its Connected Apps platform lets an app turn its own backend into an MCP server with Stytch acting as the OAuth authorization server, and it publishes a reference MCP server (at mcp.stytch.dev) that demonstrates the pattern. That is tooling for building MCP servers on top of Stytch, not a hosted server that exposes Stytch's own login methods to an agent.
How does the error response look?+
An error returns a JSON body with status_code, request_id, error_type, error_message, and error_url. The error_type is the machine-readable key to branch on, like duplicate_email on a 400 or unauthorized_credentials on a 401, and error_url links straight to that code's documentation. A 2xx confirms success, a 4xx points to something in the request, and a 5xx is a rare Stytch-side error.
How long do magic links and OTP codes stay valid?+
An OTP code expires after 2 minutes, and a user can have only one active code at a time, so sending a new one invalidates the previous. An email magic link defaults to a 60-minute expiry and can be set between 5 and 10080 minutes; an embeddable magic link token created server-side uses the same range. Authenticating a link or code that was already used, or has expired, returns a 401.
Related

More security API guides for agents

What is Bollard AI?

Control what every AI agent can do in Stytch.

Bollard AI sits between a team's AI agents and Stytch. Grant each agent exactly the access it needs, read or write, product by product, and every call is checked and logged.

  • Set read, write, or full access per agent, never a shared project secret.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
Stytch
Onboarding Agent
Look up users ResourceOffReadFull use
Send login codes ActionOffReadFull use
Delete users ActionOffReadFull use
Revoke sessions ActionOffReadFull use
Per-agent access, set in Bollard AI, not in Stytch