Summary and recommendation
Soldo exposes a REST API under https://api.soldo.com/business/v2/ authenticated via OAuth 2.0 client credentials flow.
Credentials are scoped per company;
multi-tenant or multi-company access requires separate client_id/client_secret pairs per entity.
The API covers core employee lifecycle operations - create, read, update, deactivate - plus wallet reads, but has no SCIM layer and no publicly documented webhook system for event-driven triggers.
Because Soldo does not publish rate limit thresholds, defensive implementation with exponential backoff on HTTP 429 is required.
Building an identity graph against Soldo means correlating the employee `id` (UUID), `walletId`, `companyId`, and `status` fields to reconstruct a complete access and spend-authority picture per user.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 (client credentials flow) |
| Base URL | Official docs |
| SCIM available | No |
Authentication
Auth method: OAuth 2.0 (client credentials flow)
Setup steps
- Register an application in the Soldo Developer Portal to obtain a client_id and client_secret.
- POST to the token endpoint (https://api.soldo.com/oauth/token) with grant_type=client_credentials, client_id, and client_secret.
- Receive an access_token (Bearer token) in the response.
- Include the Bearer token in the Authorization header for all subsequent API requests.
- Tokens expire; implement refresh logic by re-requesting via client credentials.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| read:employees | Read employee/user records | GET employee list and individual employee details |
| write:employees | Create and update employee/user records | POST and PATCH employee endpoints |
| read:wallets | Read wallet/account data associated with users | GET wallet assignments per employee |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string (UUID) | Unique identifier for the employee | system-generated | immutable | |
| firstName | string | Employee first name | required | optional | |
| lastName | string | Employee last name | required | optional | |
| string | Employee email address | required | optional | Used as login identifier | |
| mobile | string | Mobile phone number | optional | optional | E.164 format recommended |
| status | string (enum) | Employee account status (e.g., ACTIVE, INACTIVE) | system-set | optional | |
| role | string (enum) | Role within the company (e.g., EMPLOYEE, ADMIN) | required | optional | |
| customFields | object | Key-value custom metadata fields | optional | optional | |
| walletId | string (UUID) | Associated wallet identifier | optional | optional | |
| companyId | string (UUID) | Parent company identifier | system-set | immutable | |
| createdAt | string (ISO 8601) | Timestamp of record creation | system-generated | immutable | |
| updatedAt | string (ISO 8601) | Timestamp of last update | system-generated | system-updated |
Core endpoints
List employees
- Method: GET
- URL:
https://api.soldo.com/business/v2/employees - Watch out for: Endpoint path and version prefix (v1 vs v2) should be verified against current developer docs; versioning may differ.
Request example
GET /business/v2/employees?page=0&pageSize=20
Authorization: Bearer {access_token}
Response example
{
"results": [{"id":"uuid","firstName":"Jane","lastName":"Doe","email":"jane@example.com","status":"ACTIVE"}],
"total": 1
}
Get employee by ID
- Method: GET
- URL:
https://api.soldo.com/business/v2/employees/{employeeId} - Watch out for: Returns 404 if employee does not exist or belongs to a different company scope.
Request example
GET /business/v2/employees/uuid-1234
Authorization: Bearer {access_token}
Response example
{
"id": "uuid-1234",
"firstName": "Jane",
"lastName": "Doe",
"email": "jane@example.com",
"status": "ACTIVE",
"role": "EMPLOYEE"
}
Create employee
- Method: POST
- URL:
https://api.soldo.com/business/v2/employees - Watch out for: Email must be unique within the company. Duplicate email returns an error.
Request example
POST /business/v2/employees
Authorization: Bearer {access_token}
Content-Type: application/json
{"firstName":"John","lastName":"Smith","email":"john@example.com","role":"EMPLOYEE"}
Response example
{
"id": "uuid-5678",
"firstName": "John",
"lastName": "Smith",
"email": "john@example.com",
"status": "ACTIVE"
}
Update employee
- Method: PATCH
- URL:
https://api.soldo.com/business/v2/employees/{employeeId} - Watch out for: Only fields included in the request body are updated; omitted fields are unchanged.
Request example
PATCH /business/v2/employees/uuid-5678
Authorization: Bearer {access_token}
Content-Type: application/json
{"mobile":"+441234567890"}
Response example
{
"id": "uuid-5678",
"mobile": "+441234567890",
"updatedAt": "2024-06-01T10:00:00Z"
}
Deactivate/delete employee
- Method: DELETE
- URL:
https://api.soldo.com/business/v2/employees/{employeeId} - Watch out for: Deactivation behavior (soft vs hard delete) is not explicitly documented; verify whether cards and wallets are automatically unlinked.
Request example
DELETE /business/v2/employees/uuid-5678
Authorization: Bearer {access_token}
Response example
HTTP 204 No Content
Get OAuth token
- Method: POST
- URL:
https://api.soldo.com/oauth/token - Watch out for: Token endpoint URL and parameter names should be confirmed in current developer docs; sandbox vs production environments use different base URLs.
Request example
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=xxx&client_secret=yyy
Response example
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600
}
Rate limits, pagination, and events
Rate limits: Soldo's public API documentation does not explicitly publish rate limit thresholds or tier-based limits as of research date.
Rate-limit headers: Unknown
Retry-After header: Unknown
Rate-limit notes: No rate limit values, headers, or Retry-After behavior are documented in official sources. Contact Soldo support for current limits.
Pagination method: offset
Default page size: 20
Max page size: 100
Pagination pointer: page and pageSize (or limit/offset - confirm in current API reference)
Webhooks available: Unknown
Webhook notes: Soldo's public developer documentation does not explicitly document a webhook system for user/employee lifecycle events as of research date.
Alternative event strategy: Poll the GET /employees endpoint periodically to detect changes, or contact Soldo support regarding event notification options.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Not documented
- Endpoint: Not documented
Limitations:
- No SCIM provisioning is publicly documented by Soldo.
- No IdP (Okta, Entra ID, Google Workspace, OneLogin) SCIM connectors are documented.
- SSO integration is not publicly documented in the Soldo help centre.
Common scenarios
Three integration scenarios cover the primary lifecycle surface.
Provisioning a new employee requires a POST to /business/v2/employees followed by a separate wallet assignment call - the employee record and wallet linkage are not atomic, so partial-success handling is necessary.
Deactivating a departed employee via DELETE on /business/v2/employees/{employeeId} has an undocumented soft-vs-hard-delete behavior;
callers must verify the returned status and separately confirm card state, since card blocking is not guaranteed to be automatic.
Directory sync must be poll-based: GET /business/v2/employees with offset pagination (default page size 20, max 100) iterated to exhaustion, then reconciled against the external directory using PATCH for field updates or POST for missing records.
API versioning (v1 vs v2) is inconsistently documented across endpoints;
always verify the version prefix in the current developer portal before shipping.
Provision a new employee and assign a wallet
- POST to /oauth/token with client credentials to obtain Bearer token.
- POST to /business/v2/employees with firstName, lastName, email, and role to create the employee record.
- Capture the returned employee id.
- Use the wallet assignment endpoint (verify in API docs) to link a wallet to the new employee id.
Watch out for: Wallet assignment may be a separate endpoint or part of the wallet resource, not the employee resource. Confirm in current API reference.
Deactivate a departed employee
- GET /business/v2/employees?email={email} to look up the employee id by email.
- DELETE /business/v2/employees/{employeeId} to deactivate the account.
- Verify the employee status is no longer ACTIVE via a subsequent GET request.
Watch out for: Confirm whether DELETE performs a soft deactivation or permanent deletion, and whether associated cards are automatically blocked.
Sync employee list to an external directory
- GET /business/v2/employees with pagination (page=0, pageSize=100) to retrieve all employees.
- Iterate through pages until total results are exhausted.
- Compare returned records against the external directory and reconcile differences.
- Use PATCH /business/v2/employees/{id} to update changed fields in Soldo, or POST to create missing records.
Watch out for: No webhook support means this sync must be scheduled/polled. Large employee lists may require careful pagination handling to avoid incomplete syncs.
Why building this yourself is a trap
The absence of SCIM and webhooks is the core architectural constraint. Without SCIM, no standard IdP connector (Okta, Entra ID, Google Workspace, OneLogin) can drive provisioning natively - all lifecycle events must be translated into direct REST calls, which means building and maintaining custom sync logic.
Without webhooks, there is no push notification for employee status changes, wallet assignments, or card events; any integration that needs near-real-time accuracy must poll, introducing latency and rate-limit exposure against undocumented thresholds.
The customFields object on the employee resource offers a hook for enriching records with external identifiers, but field schema is not validated server-side, so identity graph consistency depends entirely on the calling system's discipline. Sandbox and production environments use separate base URLs and credentials;
conflating them during development is a documented risk with no safeguard in the API itself.
Automate Soldo workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.