Three lines

Uber

Developers

Dynamic Client Registration

Overview

Dynamic Client Registration (DCR) lets your backend programmatically register a new OAuth application with Uber without using the Developer Dashboard. This is useful when you need to create client credentials on behalf of multiple sub-organizations or partners at scale.

The registered client uses private_key_jwt for token endpoint authentication. You provide a JSON Web Key Set (JWKS) containing your RSA or EC public signing key or keys; Uber stores them and validates your signed client assertions during token requests.

OAuth 2.0 endpoints

Authorization Host https://auth.uber.com
Token Endpoint https://auth.uber.com/oauth/v2/token
DCR Endpoint https://api.uber.com/v2/oauth/register

Required Scopes

Two scopes grant access to the DCR endpoint, depending on your integration type:

Scope Grant Type When to use
oauth.dcr Authorization Code Your end user (organization admin) authorizes the registration via an OAuth consent flow
oauth.dcr.b2b Client Credentials Your backend registers clients server-to-server without a user present

Contact your Uber Partner Engineer to request one of these scopes for your application.


Prerequisites
  • A Developer account and application registered at developer.uber.com
  • One or more RSA-2048 (or stronger) or EC P-256 key pairs. The JWKS you provide must contain the public key or keys. You retain each private key and use it to sign client assertions when calling the token endpoint as the newly-registered client.

Generate a JWKS

Generate one or more key pairs locally. Send the public half as a JWKS object in the jwks field of the registration request. Keep each private half securely; you’ll use it later to sign client assertions when calling the token endpoint as the registered client.

Uber supports JWKS rotation during registration. You may include one or more signing keys in the keys array. Uber registers every usable RSA signing key (kty: "RSA") and EC P-256 signing key (kty: "EC", crv: "P-256") whose use is omitted or set to sig; keys with use set to enc are not registered for token endpoint authentication.

Provide a kid for each key you plan to use. The kid must be a UUID string and must match the kid JWT header you send later in the client_assertion. Unsupported key types or EC curves are ignored; registration requires at least one usable signing key.

Key type Public JWK fields to include JWT signing algorithm
RSA kty, kid, n, e RS256
EC P-256 kty, kid, crv, x, y ES256

The language snippets below generate an RSA JWKS. For EC P-256, generate an EC key pair and send a public JWK with kty: "EC", crv: "P-256", and base64url-encoded x and y coordinates. Set alg to ES256 for EC P-256 keys and RS256 for RSA keys so the JWKS documents the signing algorithm your token requests will use.

Golang
expand to see code snippets
import (
    "crypto/rand"
    "crypto/rsa"
    "encoding/base64"
    "encoding/json"
    "math/big"

    "github.com/google/uuid"
)

type jwk struct {
    Kty string `json:"kty"`
    Use string `json:"use"`
    Alg string `json:"alg"`
    Kid string `json:"kid"`
    N   string `json:"n"`
    E   string `json:"e"`
}

type jwks struct {
    Keys []jwk `json:"keys"`
}

// GenerateJWKS returns the JWKS JSON to send to Uber and the private key
// to retain locally for signing client assertions. The kid value must be
// sent later as the client_assertion JWT kid header.
func GenerateJWKS() (string, *rsa.PrivateKey, error) {
    priv, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        return "", nil, err
    }
    pub := priv.PublicKey
    set := jwks{Keys: []jwk{{
        Kty: "RSA",
        Use: "sig",
        Alg: "RS256",
        Kid: uuid.New().String(),
        N:   base64.RawURLEncoding.EncodeToString(pub.N.Bytes()),
        E:   base64.RawURLEncoding.EncodeToString(big.NewInt(int64(pub.E)).Bytes()),
    }}}
    b, err := json.Marshal(set)
    if err != nil {
        return "", nil, err
    }
    return string(b), priv, nil
}
Java
expand to see code snippets
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.KeyUse;
import com.nimbusds.jose.jwk.RSAKey;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPublicKey;
import java.util.UUID;

public class JWKSGenerator {
    // Returns the JWKS JSON to send to Uber. Persist the KeyPair's private key
    // locally for signing client assertions later.
    public static String generateJWKS(KeyPair[] outKeyPair) throws Exception {
        KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
        gen.initialize(2048);
        KeyPair kp = gen.generateKeyPair();
        outKeyPair[0] = kp;

        RSAKey publicJwk = new RSAKey.Builder((RSAPublicKey) kp.getPublic())
                .keyUse(KeyUse.SIGNATURE)
                .algorithm(JWSAlgorithm.RS256)
                .keyID(UUID.randomUUID().toString())
                .build()
                .toPublicJWK();

        return new JWKSet(publicJwk).toString();
    }
}
Python
expand to see code snippets
import json
import uuid
from jwcrypto import jwk

def generate_jwks():
    # Generate an RSA-2048 key as a JWK
    key = jwk.JWK.generate(
        kty="RSA",
        size=2048,
        kid=str(uuid.uuid4()),
        use="sig",
        alg="RS256",
    )

    # Public-only JWKS object for the DCR request body
    public_jwks = {"keys": [json.loads(key.export(private_key=False))]}

    # Private key (PEM) to retain locally for client_assertion signing
    private_pem = key.export_to_pem(private_key=True, password=None)

    return json.dumps(public_jwks), private_pem

Obtain an Access Token

Acquire an access token carrying either the oauth.dcr or oauth.dcr.b2b scope before calling the DCR endpoint:

Pass the resulting token in the Authorization: Bearer <access_token> header on all requests below.


Register a Client

Call the DCR endpoint with the access token obtained above. The request body is JSON.

Request Details:

  • Method: POST
  • URL: https://api.uber.com/v2/oauth/register
  • Content-Type: application/json
  • Authorization: Bearer <access_token>

Request Body Parameters:

Parameter Type Required Description
client_name string Yes Display name for the new application
client_description string No Short description of the application
redirect_uris array of strings Yes (for auth-code clients) Allowed redirect URIs for the OAuth consent flow
jwks object Yes JSON Web Key Set containing one or more RSA or EC P-256 public signing keys used for private_key_jwt authentication. Use RSA-2048 or stronger keys for RS256, or EC P-256 keys for ES256. Each kid must be a UUID and must match the JWT kid header used later.
scope string No Space-delimited list of OAuth scopes to request. Defaults to all scopes approved for your integration if omitted.
privacy_policy_uri string No URL to the application’s privacy policy
webhook_uri string No HTTPS endpoint to receive Uber webhook events for this client
contacts array of strings No Developer email addresses to invite as collaborators on the registered application
organization_uuid string Yes UUID of the organization this client belongs to

Example Request:

curl -X POST 'https://api.uber.com/v2/oauth/register' \
  -H 'Authorization: Bearer <ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "client_name": "Ramen XYZ Payment Integration",
    "client_description": "Payment integration for Ramen XYZ partner stores",
    "redirect_uris": ["https://ramen-xyz.com/auth/callback"],
    "jwks": {
      "keys": [
        {
          "kty": "RSA",
          "use": "sig",
          "alg": "RS256",
          "kid": "4d00ebc0-3b70-4f85-b873-8bcfbf1567f6",
          "n": "<base64url-encoded-modulus>",
          "e": "AQAB"
        },
        {
          "kty": "EC",
          "use": "sig",
          "alg": "ES256",
          "kid": "a1daed88-cf91-4f66-9a10-6a234f5e82c5",
          "crv": "P-256",
          "x": "<base64url-encoded-x-coordinate>",
          "y": "<base64url-encoded-y-coordinate>"
        }
      ]
    },
    "scope": "profile",
    "privacy_policy_uri": "https://ramen-xyz.com/privacy",
    "webhook_uri": "https://ramen-xyz.com/webhooks/uber",
    "contacts": ["dev@ramen-xyz.com"],
    "organization_uuid": "<YOUR_ORGANIZATION_UUID>"
  }'

Response Parameters:

Field Type Description
clientId string Unique identifier for the newly registered application
scope string Space-delimited list of scopes granted to the client
tokenEndpointAuthMethod string Always private_key_jwt — authenticate token requests by signing a JWT with the RSA or EC private key matching a registered JWKS kid
webhookSigningSecret string Present only when webhook_uri was provided. HMAC-SHA256 secret used to verify Uber webhook payloads. Store this securely; it will not be returned again.

Example Response:

{
  "clientId": "abc123xyz",
  "scope": "profile",
  "tokenEndpointAuthMethod": "private_key_jwt",
  "webhookSigningSecret": "a3f8c2...d9e1"
}

Webhook Verification

If you registered a webhook_uri, Uber signs each webhook payload using the webhookSigningSecret returned at registration. Verify the signature to confirm the payload is authentic:

  1. Extract the X-Uber-Signature header from the incoming request.
  2. Compute HMAC-SHA256(webhookSigningSecret, request_body).
  3. Compare your computed value with the header value. Reject the request if they do not match.

Error Handling
HTTP Status Error Description
400 invalid_request Required parameter missing or malformed
400 invalid_redirect_uri One or more redirect_uris are invalid or disallowed
400 invalid_jwks The jwks field could not be parsed or contains no usable RSA or EC P-256 signing key
401 unauthorized Missing or invalid access token
403 forbidden Access token does not carry the required oauth.dcr or oauth.dcr.b2b scope
429 too_many_requests Rate limit exceeded. Back off and retry.
500 server_error Unexpected server error

Next Steps

The registered client authenticates to Uber’s token endpoint using private_key_jwt. For details on building and signing the client_assertion JWT with the RSA or EC private key that matches one of your registered JWKS kid values, see Client Asymmetric Key Authentication.

Uber

Developers
© 2026 Uber Technologies Inc.