Skip to content

Authentication

The Hedge broker API uses OAuth 2.1. Every request carries a short-lived bearer token in the Authorization header:

Authorization: Bearer <token>

Requests never authenticate with a static key: tokens are short-lived, audience-bound bearer JWTs, and refresh tokens rotate on every use. Machine credentials exist (a client_id/client_secret pair, created self-serve in the broker portal), but they are only ever exchanged for a short-lived token, never sent on API requests. How you obtain a token depends on what you are building:

Two scopes gate what a token can do:

Scope Grants
broker_mcp Read access: submissions, policies, payments, and appetite.
broker_submit Write access: create submissions, upload documents, answer quote questions, and finalize.

A token’s scope is capped by the brokerage’s programmatic-access controls and is always tied to the authenticated broker’s brokerage, never to the client. Read more about scope enforcement in Conventions.

Read access works for every connected brokerage: once a broker signs in and approves a client, broker_mcp reads work right away. Submitting is enabled per brokerage by Hedge: until your brokerage is enabled, tokens are capped to read-only and broker_submit grants nothing. The consent screen shows whether the app you are approving can submit. To turn on submission access for your brokerage, contact your Hedge account manager.

The authorization server publishes its metadata at a standard discovery endpoint. Clients should read it rather than hard-coding endpoint paths:

Terminal window
curl "https://api.hedgespecialty.com/api/v1/oauth/.well-known/oauth-authorization-server"

The document lists the token, authorization, device authorization, and registration endpoints, along with supported grant types and scopes.

The Device Authorization Grant (RFC 8628) is the default for the hedge CLI and any headless client. The broker approves the sign-in in the browser while the client polls for a token.

  1. Request a device code.

    Terminal window
    curl -X POST "https://api.hedgespecialty.com/api/v1/oauth/device_authorization" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "client_id=$HEDGE_CLIENT_ID" \
    -d "scope=broker_submit"

    The response includes a user_code, a verification_uri (the portal’s /device page), a verification_uri_complete, a polling interval, and an expires_in.

  2. Send the broker to approve.

    Show the broker the verification_uri and user_code, or open the verification_uri_complete for them. They sign in to the broker portal and approve the request. The brokerage the token is scoped to comes from that authenticated session, never from the client.

  3. Poll for the token.

    Terminal window
    curl -X POST "https://api.hedgespecialty.com/api/v1/oauth/token" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
    -d "device_code=$DEVICE_CODE" \
    -d "client_id=$HEDGE_CLIENT_ID"

    Poll at the interval the server returned. While the broker has not yet approved, the endpoint returns authorization_pending. Once approved, it returns an access_token and a refresh_token.

On a machine with a browser, the CLI can run the Authorization Code flow with PKCE over a loopback redirect (RFC 8252). This opens the portal, the broker approves, and the code is returned to a local http://127.0.0.1 listener and exchanged for a token.

Terminal window
hedge login --browser

The same brokerage-scoping rule applies: the principal comes from the authenticated portal session, and the scope is capped by the brokerage’s programmatic-access controls.

Clients can register themselves with Dynamic Client Registration (RFC 7591). This is how AI tools and other clients obtain a client_id without a manual setup step.

Terminal window
curl -X POST "https://api.hedgespecialty.com/api/v1/oauth/register" \
-H "Content-Type: application/json" \
-d '{
"client_name": "My Broker Tool",
"redirect_uris": ["http://127.0.0.1:4567/callback"]
}'

The endpoint is public by design and rate-limited per IP. It issues stateless public PKCE client ids that encode the registered redirect_uris. There is no client store and no client_secret.

Server-to-server integrations that act without an interactive broker use the Client Credentials grant with a machine credential — a client_id (bac_...) and client_secret (bas_...) pair.

Any broker user can create a read-only key under Settings, API keys in the broker portal; keys that carry broker_submit require a brokerage admin. The secret is shown exactly once, at creation — store it in a secret manager. Each brokerage can hold up to 10 active keys; revoking a key frees a slot and blocks new tokens immediately. The key’s scopes are a ceiling: every token mint re-caps them against the brokerage’s programmatic-access controls.

Exchange the credentials for a token:

Terminal window
curl -X POST "https://api.hedgespecialty.com/api/v1/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=$HEDGE_CLIENT_ID" \
-d "client_secret=$HEDGE_CLIENT_SECRET" \
-d "scope=broker_mcp"

Machine tokens carry no broker identity, so creating a submission with one additionally requires a producer_email naming an active portal user of your brokerage. Machine credentials cannot manage other machine credentials — key management lives in the portal only. They are also refused by the MCP write tools; see the MCP guide for the AI connector, which uses the interactive flows instead. OAuth grants for interactive apps (Claude, Cursor) are still managed under Settings, Connected apps.

Send the access token on every request:

Terminal window
curl "https://api.hedgespecialty.com/api/v1/broker/me" \
-H "Authorization: Bearer $HEDGE_TOKEN"

Tokens are short-lived. When one expires, use the rotating refresh token to get a new pair, or run the sign-in flow again. Read endpoints accept a token with broker_mcp; write endpoints require broker_submit.