Skip to main content
Resend Docs
current

Search documentation

Type to search this documentation.

On this pageOverview

Register Client

Dynamically register an OAuth client for the authorization code + PKCE flow (RFC 7591).

Unauthenticated (no API key). Rate-limited to 20 registrations per hour per IP address.

  • client_name (string, required) — A human-readable name for the client. Maximum 200 characters.

  • redirect_uris (string[], required) — 1 to 10 URIs, each up to 2048 characters. See Allowed redirect URIs.

  • grant_types (string[]) — Must include authorization_code. refresh_token is also supported.

  • response_types (string[]) — Only code is supported. Validated if present but not stored; the response always echoes back ["code"].

  • scope (string) — Space-delimited list of scopes, e.g. "emails:send". Must be a subset of the supported scopes. If omitted, the client is registered with every supported scope.

  • token_endpoint_auth_method (string) — How the client authenticates at the token and revocation endpoints. none registers a public client (PKCE only). client_secret_basic and client_secret_post register a confidential client and issue a client_secret in the response. See Confidential clients. PKCE is required on every authorization code exchange regardless of method.

  • client_uri (string) — A URL for the client's homepage. Echoed back, not otherwise used.

  • logo_uri (string) — A URL for the client's logo. Shown on the consent screen.

Registering with token_endpoint_auth_method set to client_secret_basic or client_secret_post returns two extra fields, documented in Response Fields below.

  • https:// URIs are unrestricted.
  • http:// is only allowed for loopback addresses (127.0.0.1, localhost, [::1]).
  • Private-use URI schemes (e.g. cursor://, vscode://) are allowed.
  • file, ftp, data, javascript, blob, about, and vbscript schemes are rejected. No URI may include a fragment.

The response echoes back the registered client metadata along with the issued client_id. Registering a confidential client returns two extra fields:

  • client_secret (string) — The generated client secret. Returned only once, in this response. Resend stores a hash and can't show it again, so persist it securely at registration time. If it's lost, register a new client.

  • client_secret_expires_at (number) — Unix time at which the secret expires. Always 0: the secret does not expire.

Public
curl -X POST 'https://api.resend.com/oauth/register' \
     -H 'Content-Type: application/json' \
     -d $'{
  "client_name": "Example OAuth Client",
  "redirect_uris": ["http://127.0.0.1/oauth/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "scope": "emails:send"
}'
Confidential
curl -X POST 'https://api.resend.com/oauth/register' \
     -H 'Content-Type: application/json' \
     -d $'{
  "client_name": "Example OAuth Client",
  "redirect_uris": ["http://127.0.0.1/oauth/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "client_secret_basic",
  "scope": "emails:send"
}'
Public
{
  "client_id": "550e8400-e29b-41d4-a716-446655440000",
  "client_id_issued_at": 1750000000,
  "client_name": "Example OAuth Client",
  "redirect_uris": ["http://127.0.0.1/oauth/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "scope": "emails:send"
}
Confidential
{
  "client_id": "550e8400-e29b-41d4-a716-446655440000",
  "client_id_issued_at": 1750000000,
  "client_name": "Example OAuth Client",
  "redirect_uris": ["http://127.0.0.1/oauth/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "client_secret_basic",
  "scope": "emails:send",
  "client_secret": "3vProAFw7...store-this-now...KpQ",
  "client_secret_expires_at": 0
}

Errors use the standard OAuth shape ({"error": "...", "error_description": "..."}) rather than Resend's usual error format.

Status error When
400 invalid_request A required field is missing, malformed, or a redirect URI is disallowed.
400 invalid_scope scope includes a value outside the supported scope set.
429 too_many_requests More than 20 registrations from this IP in the last hour.
Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu