Authentication
The OneFinOps API uses OAuth 2.0 client credentials. You exchange a client id and secret for a short-lived bearer token, and pass that token on every API call.
Issue an OAuth client
OAuth clients are managed from the Developer hub in your OneFinOps dashboard. When creating a client you choose a label (for your own bookkeeping). The single API scope gstn-india is assigned automatically — you don't pick per-action scopes.
We return the client_id (visible forever) and client_secret (shown once). Store the secret in a secrets manager — we cannot recover it; you would have to rotate.
Client ids are environment-prefixed:
| Environment | Prefix |
|---|---|
| Sandbox | ofin_test_ |
| Production | ofin_live_ |
Request a token
curl -X POST 'https://login.onefinops.com/realms/onefinops/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'client_id=ofin_live_<id>' \
-d 'client_secret=<secret>' \
-d 'scope=gstn-india'The response includes access_token (JWT) and expires_in (seconds, typically 900). Cache the token until it nears expiry. Pass it as Authorization: Bearer <access_token>.
Permissions are not scope-based
The gstn-india scope is a marker — it tells the API surface "this token is for me." It is not a permission grant. What your token can do is governed by your plan / entitlement and per-call rate limits, not by per-action OAuth scopes.
Practical effect:
- You request a single scope
gstn-indiaregardless of which endpoints you call. - The endpoints you can call depend on your plan / add-ons. A token whose plan doesn't include e-way-bill access will still authenticate, but the call will be rejected at the entitlement layer with a billing-shaped error code.
- Rate limits (see Rate limits) apply per OAuth client per minute, irrespective of which endpoint you hit.
This is intentionally simpler than per-action scope juggling: you don't have to maintain a scope catalogue in your client config, and we can enable / disable products on your account without forcing you to rotate keys.
Tenant binding
Every token carries an organization_id claim that pins the call to your tenant. You cannot override the organization in the request body or path — the API reads it from the token. This is what keeps multi-org customers' data separated.
Rotating secrets
You can rotate a client's secret from the Developer hub. Rotation issues a new secret and starts a 24-hour overlap window during which both the old and new secrets work — long enough to roll your deployment without downtime. After 24 hours, the old secret is revoked.
Common mistakes
- Calling the API with the OIDC token endpoint URL as the base URL. The token endpoint is at
login.onefinops.com; the API lives atapi.in.onefinops.com(or sandbox). - Putting the client_secret in browser code. Client credentials is server-to-server only. Never embed a secret in a SPA or mobile app.
- Reissuing a token on every request. Cache and reuse — the token endpoint is rate-limited and aggressive churn will fail open with 429s.
- Mixing sandbox tokens with production hosts. The audience claim is environment-scoped; cross-env tokens are rejected with 401.
- Requesting per-action scopes (
einvoice:generateetc.). They don't exist. Just requestscope=gstn-india.
Updated about 5 hours ago
