Skip to main content
GET
/
oauth
/
authorize
GET https://api.resend.com/oauth/authorize?client_id=550e8400-e29b-41d4-a716-446655440000&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A49152%2Foauth%2Fcallback&scope=emails%3Asend&state=STATE_VALUE&code_challenge=CODE_CHALLENGE_VALUE&code_challenge_method=S256
HTTP/1.1 302 Found
Location: https://resend.com/oauth/authorize/3f9c1e2a-...
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:
  1. The client opens /oauth/authorize in the user’s browser.
  2. Resend redirects (302) to the Resend dashboard consent screen, which handles login if needed.
  3. The user reviews and approves (or denies) the request.
  4. The dashboard redirects the browser back to the client’s redirect_uri with a code and the original state.

Query Parameters

client_id
string
required
The client_id from registration.
response_type
string
required
Must be "code".
redirect_uri
string
required
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.
scope
string
Space-delimited list of requested scopes. If omitted, defaults to the client’s full registered scope set.

Scopes

  • emails:send is enough for send-only routes: POST /emails, POST /email, POST /emails/sending, POST /email/sending, and POST /broadcasts/:broadcastId/send.
  • full_access is required for every other API route. Also satisfies any emails:send-scoped check.
state
string
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.
code_challenge
string
required
Base64url-encoded SHA-256 hash of a code_verifier your client generates.
code_challenge_method
string
required
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.
GET https://api.resend.com/oauth/authorize?client_id=550e8400-e29b-41d4-a716-446655440000&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A49152%2Foauth%2Fcallback&scope=emails%3Asend&state=STATE_VALUE&code_challenge=CODE_CHALLENGE_VALUE&code_challenge_method=S256
HTTP/1.1 302 Found
Location: https://resend.com/oauth/authorize/3f9c1e2a-...

Errors

Once Resend validates client_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.
errorWhen
invalid_requestresponse_type isn’t code, or code_challenge_method isn’t S256.
unauthorized_clientThe client isn’t registered for the authorization_code grant.
invalid_scopeNo scope requested, a scope isn’t supported, or a scope isn’t in the client’s registered scopes_allowed.
server_errorResend failed to persist the authorization request.