Essentials
Authentication
Exchange your client credentials for a short-lived bearer token, and send it with every request.
The API uses the OAuth 2.0 client credentials grant. Your server holds a client ID and secret; it trades them for an access token and sends that token on every call. Never put the secret in a browser or mobile app.
Get credentials
In the dashboard (sandbox or live), open Integrations → Applications and create an application. Each application has its own client ID and secret, so you can give separate services separate credentials and revoke one without touching the others.
Your Lint account must have completed BVN verification. Until it has, every call returns 403 bvn_not_verified.
Request a token
| Field | Value |
|---|---|
grant_type | Always client_credentials |
client_id | From your application |
client_secret | From your application |
curl -X POST https://staging.lint.finance/api/partner/v1/oauth/token \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "'"$LINT_CLIENT_ID"'",
"client_secret": "'"$LINT_CLIENT_SECRET"'"
}'{
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9…"
}Use the token
Send it in the Authorization header of every other request:
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9…Keep tokens fresh
A token lasts 60 minutes (expires_in is in seconds). Cache it and reuse it rather than requesting one per call. Refresh a minute or two before it expires, and if a call returns 401 unauthenticated, get a new token and retry that call once.
let cached = { token: null, expiresAt: 0 }
export async function accessToken() {
if (cached.token && Date.now() < cached.expiresAt - 60_000) return cached.token
const { access_token, expires_in } = await getToken()
cached = { token: access_token, expiresAt: Date.now() + expires_in * 1000 }
return access_token
}When it fails
The token endpoint follows the OAuth 2.0 standard, so its errors use OAuth's own format (which OAuth client libraries understand) rather than the Lint error shape:
{
"error": "invalid_client",
"error_description": "Client authentication failed",
"message": "Client authentication failed"
}A missing field returns 422 validation_failed in the usual Lint shape. Every other endpoint uses the Lint shape for all errors, including an expired token:
{
"message": "Missing, invalid or expired access token.",
"code": "unauthenticated",
"request_id": "req_01m6d5tvysh2k1xq57fqpn3eey"
}Treat the client secret like a password. If it leaks, revoke the application in the dashboard straight away and create a new one.