Skip to main content

Obtaining OAuth tokens

Every RCM API call requires a bearer access token in the Authorization header. Tokens are obtained from OSIGU's SSO server (separate from the RCM API itself) via the OAuth2 client credentials grant.

Endpoints

EnvironmentOAuth token URL
Sandboxhttps://sandbox.osigu.com/v1/oauth/token
Productionhttps://api.osigu.com/v1/oauth/token

Credentials are environment-scoped — your sandbox client_id does not work against the production OAuth URL and vice versa.

Request

curl -X POST https://sandbox.osigu.com/v1/oauth/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials"

The -u flag puts client_id:client_secret into the HTTP Basic Authorization header (this is the OAuth2 convention for client credentials).

Body parameters:

FieldRequiredDescription
grant_typeyesAlways client_credentials.
scopenoSpace-separated list of scopes to request. Defaults to all scopes your client is permitted.

Response

{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "bearer",
"expires_in": 3600,
"scope": "rcm:read rcm:write"
}

Use the access_token as Authorization: Bearer <token> on every RCM call.

Caching

Tokens last 1 hour. Cache them. Don't request a fresh token per API call — the auth server rate-limits clients that hammer the token endpoint.

A reasonable strategy:

  • Cache the token in memory (or Redis if you have multiple workers).
  • Refresh ~5 minutes before expires_in runs out (so you don't hit the API with a token about to expire mid-request).
  • On 401 Unauthorized from RCM, fetch a fresh token once and retry; if that also returns 401, surface the error.

Scopes

Scopes determine which RCM actions your token can perform:

ScopeGrants
rcm:readGET endpoints — reading accounts, charges, dispatch packages.
rcm:writePOST / PUT / DELETE endpoints — creating and modifying charges, uploading support files, etc.
rcm:webhooksManaging webhook subscriptions via the /v1/integration/webhooks API.

Which scopes your client_id is granted is configured by OSIGU during onboarding. To request a subset of your granted scopes for a particular token, pass scope= in the request body.

Errors

StatusCause
401 Unauthorizedclient_id or client_secret is wrong, or you're hitting the wrong environment's OAuth URL.
400 invalid_grantBody is malformed. Confirm you're sending grant_type=client_credentials.
400 invalid_scopeYou requested a scope your client doesn't have. Drop the scope from the request.
429 Too Many RequestsYou're requesting tokens too fast. Cache them; back off and retry.