Authorize
Start the OAuth authorization code + PKCE flow.
GET
This is a browser redirect endpoint, not a JSON API call. Open this URL in the user’s browser. Don’t fetch it from a backend or CLI process and follow the redirect yourself, since the user has to see and approve the consent screen.
The flow:
- The client opens
/oauth/authorizein the user’s browser. - Resend redirects (
302) to the Resend dashboard consent screen, which handles login if needed. - The user reviews and approves (or denies) the request.
- The dashboard redirects the browser back to the client’s
redirect_uriwith acodeand the originalstate.
Query Parameters
The
client_id from registration.Must be
"code".Must exactly match one of the client’s registered redirect URIs. The only
exception is loopback URIs (
127.0.0.1, localhost, [::1]), where the port
is allowed to differ from what was registered.Space-delimited list of requested scopes. If omitted, defaults to the client’s
full registered scope set.
Scopes
emails:sendis enough for send-only routes:POST /emails,POST /email,POST /emails/sending,POST /email/sending, andPOST /broadcasts/:broadcastId/send.full_accessis required for every other API route. Also satisfies anyemails:send-scoped check.
An opaque value round-tripped back on the callback unchanged. Use it to bind
the callback to the request that started the flow. Recommended, not required
by the server, but a client that skips it can’t detect CSRF on the callback.
Maximum 1024 characters.
Base64url-encoded SHA-256 hash of a
code_verifier your client
generates.
Must be
"S256". Resend does not support the plain method.A
resource parameter (RFC 8707) is accepted but ignored. Resend does not
support resource indicators yet.Errors
Once Resend validatesclient_id and redirect_uri, every other error redirects (302) back to redirect_uri with error, error_description, and (if provided) state as query parameters, not a JSON body, since the user is mid-redirect in a browser. Before that point (unknown client_id, invalid or unregistered redirect_uri), Resend returns a 400 JSON body instead, since it can’t safely redirect to an unvalidated URL.
error | When |
|---|---|
invalid_request | response_type isn’t code, or code_challenge_method isn’t S256. |
unauthorized_client | The client isn’t registered for the authorization_code grant. |
invalid_scope | No scope requested, a scope isn’t supported, or a scope isn’t in the client’s registered scopes_allowed. |
server_error | Resend failed to persist the authorization request. |