Authentication
The API uses OAuth 2.0 with the client_credentials flow and long-lived JWT tokens (12 hours).
Get a token
POST /v1/auth/login
Content-Type: application/json
{
"clientId": "your-client-id",
"clientSecret": "your-client-secret"
}
Response
{
"accessToken": "eyJhbGciOiJSUzI1NiIsInR...",
"tokenType": "Bearer",
"expiresIn": 43200,
"scope": "clients:read clients:write receivables:read receivables:write ..."
}
| Field | Description |
|---|---|
accessToken | JWT to use in Authorization: Bearer ... |
tokenType | Always Bearer |
expiresIn | Seconds until expiration. Default 43200 (12 hours) |
scope | Space-separated list of enabled scopes |
Use the token
Include the accessToken as a bearer token on every request:
GET /v1/me
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR...
Renewal
When the token expires, issue a new POST /v1/auth/login to obtain another one. There are no refresh tokens.
For server-to-server integrations: cache the token in memory, renew it before expiration (typically 5 minutes before), and reuse it across requests. The expiresIn field in the response indicates the lifetime in seconds.
Scopes
Each API key has a set of scopes that limit what it can do. The token returns the active scopes in the scope field.
| Scope | Allows |
|---|---|
clients:read | Read clients |
clients:write | Create and update clients |
associates:read | Read associates |
associates:write | Create, update, and disable associates |
receivable-accounts:read | Read receivable accounts |
receivable-accounts:write | Create, update, and disable receivable accounts |
current-accounts:read | Read current accounts (MAIN/SUB) |
receivables:read | Read receivables |
receivables:write | Create, update, and change the status of receivables |
movements:read | Read movements |
settlements:read | Read settlements |
route-settlements:read | Read route settlements |
route-settlements:write | Create/update route settlements |
reports:read | Generate and download reports |
webhooks:admin | Manage webhooks |
When a request requires a scope the token does not have, the response is 403 insufficient-scope.
Common errors
| Scenario | HTTP | code |
|---|---|---|
| Incorrect credentials | 401 | invalid-credentials |
| Expired token | 401 | token-expired |
| Malformed token | 401 | invalid-token |
| Missing required scope | 403 | insufficient-scope |
Rate limit on /auth/login | 429 | rate-limit-exceeded |
GET /v1/me
Convenience resource to inspect the context of the active token. Useful when integrating, to confirm credentials, customer, and environment:
GET /v1/me
Authorization: Bearer eyJ...
200 OK
{
"customer": {
"id": 17,
"businessName": "DistribuidoraDemo S.A.",
"taxId": "30999999999",
"creationDate": "2025-11-01T10:00:00-03:00"
},
"apiKey": {
"id": 88,
"name": "ERP Producción",
"scopes": [
"clients:read", "clients:write",
"associates:read", "associates:write",
"receivable-accounts:read", "receivable-accounts:write",
"receivables:read", "receivables:write",
"movements:read", "settlements:read", "reports:read",
"webhooks:admin"
],
"environment": "PRODUCTION",
"rateLimitTier": "STANDARD"
}
}
Credential rotation
The clientSecret can be rotated by contacting the Max Pay team. A self-service endpoint will be exposed in an upcoming release.