> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Delegated OAuth for REST Agents

> Connect a public client directly to the Trackly API with owner consent and PKCE, without MCP.

<Note>
  Direct API authorization requires the corresponding Trackly app and external API rollout. Registration preview generation also requires the jobs worker rollout so it recognizes direct API grants. This guide describes the implemented connection contract, not confirmation that it is enabled for your account. Confirm availability with [support](/resources/support).
</Note>

Custom agents can use OAuth directly without running MCP or obtaining a service secret. The owner signs in or creates a Trackly account, verifies email and any required second factor, and approves the requested permissions in Trackly. An umbrella account is not required.

Use issuer `https://app.tracklysms.com`; discover its endpoints through `https://app.tracklysms.com/.well-known/oauth-authorization-server`. Public clients use S256 PKCE and `token_endpoint_auth_method: "none"`.

## Connect the client

1. Register the client at `POST https://app.tracklysms.com/oauth/register` with JSON containing `client_name`, your exact `redirect_uris`, `grant_types: ["authorization_code", "refresh_token"]`, `response_types: ["code"]`, and `token_endpoint_auth_method: "none"`. Store the returned `client_id`. Use only redirect URIs your client controls.
2. Generate a fresh private PKCE verifier and its S256 challenge, plus an unpredictable `state`. Open `/oauth/authorize` in the owner's browser with `response_type=code`, `client_id`, `redirect_uri`, `code_challenge`, `code_challenge_method=S256`, `state`, `resource=https://api.tracklysms.com/api`, and `scope=trackly.registration`. Add `trackly.agent` only if approved SMS capability is also needed; registration permission does not authorize sending.
3. Validate the callback state and issuer before accepting the code. Exchange it at `/oauth/token` using form encoding and exactly `grant_type=authorization_code`, `client_id`, `code`, `redirect_uri`, `code_verifier`, and the same `resource`.
4. Store the access and refresh tokens in private client credential storage. Send the access token as `Authorization: Bearer …` to the API. Never put tokens, verifiers, or provider credentials in chat, logs, source control, or tool arguments.

Authorization requests expire after 10 minutes and codes after 2 minutes. Direct API access tokens last at most 15 minutes; follow the returned `expires_in`. Grants last at most 7 days and can end sooner through revocation or changed account authority.

`trackly.registration` permits account/setup reads and the four [registration preparation operations](/api-reference/v2/agent-number-requests/create). Requests remain bound to the consenting account, grant, and dedicated credential. An existing SMS-only connection needs fresh consent for registration. Owner publication, optional Entri provider consent, and final paid registration submission remain separate human decisions.

## Refresh and disconnect

Send form-encoded `grant_type=refresh_token`, `client_id`, `refresh_token`, and the exact original `resource` to `/oauth/token`. Refresh tokens rotate and are single-use: replace both stored tokens together. Do not add scopes or switch audiences during refresh. After an uncertain refresh outcome, do not repeatedly replay the old refresh token; reconnect if the client cannot recover its stored replacement.

Disconnect through `/oauth/revoke` with form-encoded `client_id` and `token`. A public client does not supply a client secret. Revocation or expired authority requires a new owner-approved connection.

## Call registration directly

The following assumes your client has stored the bearer privately in `TRACKLY_API_ACCESS_TOKEN`; never paste its value into a conversation. Keep the operation key stable when recovering the same creation.

```bash theme={null}
curl https://api.tracklysms.com/api/v2/agent/number-requests \
  -H "Authorization: Bearer $TRACKLY_API_ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: example-registration-create-001' \
  --data '{"brandName":"Example Company","phoneNumberType":"toll_free","targetCountries":["US"]}'
```

Continue with [read](/api-reference/v2/agent-number-requests/get), [update](/api-reference/v2/agent-number-requests/update), and [private preview](/api-reference/v2/agent-number-requests/preview). Follow the [owner review and recovery workflow](/agents/number-registration).

The MCP resource remains `https://mcp.tracklysms.com/mcp`. Tokens issued for that audience cannot be sent directly to the API; Trackly's MCP adapter uses its separate exchange path, whose API tokens remain limited to 60 seconds. Direct REST clients use the API resource above and need no adapter exchange secret.
