Skip to main content
POST
Dynamic Client Registration (DCR) lets a client obtain a client_id at runtime instead of being pre-registered by Resend. This endpoint is unauthenticated (no API key). By default it issues a public client that authenticates at the token endpoint with PKCE alone. Register with a client_secret_* authentication method to get a confidential client, which is issued a client_secret in the response. Confidential clients still complete PKCE on every authorization code exchange. The secret is an additional factor, not a replacement.
This endpoint is rate-limited to 20 registrations per hour per IP address. Requests over the limit get a 429 with {"error": "too_many_requests"}.

Body Parameters

string
required
A human-readable name for the client. Maximum 200 characters.
string[]
required
URIs the authorization server may redirect to after the user approves the request. At least one is required, up to 10, each up to 2048 characters. See Allowed redirect URIs for the rules.
string[]
default:"[\"authorization_code\", \"refresh_token\"]"
Must include authorization_code. refresh_token is also supported.
string[]
default:"[\"code\"]"
Only code is supported. The value is validated if present but not stored; the response always echoes back ["code"].
string
Space-delimited list of scopes to request, e.g. "emails:send". Must be a subset of the supported scopes. If omitted, the client is registered with every supported scope.
string
default:"none"
How the client authenticates at the token and revocation endpoints. none (the default) is a public client that proves itself with PKCE alone. client_secret_basic and client_secret_post are confidential clients that also present a client_secret, sent in the HTTP Authorization: Basic header or as a body parameter respectively. A client_secret_* method issues a client_secret in the response. See Confidential clients.
string
A URL for the client’s homepage. Echoed back, not otherwise used.
string
A URL for the client’s logo. Shown on the consent screen.

Confidential clients

Registering with token_endpoint_auth_method set to client_secret_basic or client_secret_post returns two extra fields:
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.
number
Unix time at which the secret expires. Always 0, meaning the secret does not expire.
Only register a confidential client when it has a backend that can keep the secret private, such as a server-side web app. Native, CLI, and other clients that can’t protect a secret should stay public (none) and rely on PKCE. See Building an OAuth client for how each client type authenticates.

Allowed redirect URIs

  • https:// URIs are unrestricted.
  • http:// is only allowed for loopback addresses (127.0.0.1, localhost, [::1]), for native/CLI clients that run a local callback server.
  • Private-use URI schemes (e.g. cursor://, vscode://) are allowed, since the OS routes them only to the registered native app.
  • file, ftp, data, javascript, blob, about, and vbscript schemes are rejected, and none of the URIs may include a fragment.

Errors

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