Summary and recommendation
Nimble exposes a REST API at https://api.nimble.com/api/v1 supporting API Key (Bearer token) and OAuth 2.0 authentication. The API covers contact CRUD operations and read-only team member listing, but it does not support user provisioning or deprovisioning - those actions are UI-only.
There is no SCIM 2.0 endpoint, no webhook system, and no service account or admin-impersonation token concept documented.
For identity graph use cases, the team members endpoint (GET /api/v1/team/members) provides id, email, name, role, and created_at fields, which is sufficient for read-only roster auditing and cross-referencing against an external identity graph. It is not sufficient for driving provisioning state - writes back to Nimble user accounts are not possible via API.
OAuth 2.0 access tokens expire; any long-running integration must implement token refresh logic. Rate limits are enforced but not publicly specified - implement exponential backoff on HTTP 429 responses and monitor nimble.readme.io for any published thresholds.
API quick reference
| Has user API | Yes |
| Auth method | API Key (Bearer token) or OAuth 2.0 access token passed in Authorization header |
| Base URL | Official docs |
| SCIM available | No |
Authentication
Auth method: API Key (Bearer token) or OAuth 2.0 access token passed in Authorization header
Setup steps
- Log in to Nimble and navigate to Settings > API Tokens.
- Generate a personal API token for direct API access.
- Alternatively, register an OAuth 2.0 application under Settings > Connected Apps to obtain client_id and client_secret.
- For OAuth 2.0, redirect users to https://api.nimble.com/oauth/authorize with required scopes, then exchange the authorization code for an access token at https://api.nimble.com/oauth/token.
- Include the token in all requests as: Authorization: Bearer
Required scopes
| Scope | Description | Required for |
|---|---|---|
| read_contacts | Read contact records | GET contacts endpoints |
| write_contacts | Create and update contact records | POST/PUT contacts endpoints |
| read_team | Read team member information | GET team members endpoint |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Unique identifier for the team member | system-generated | immutable | Used to reference a specific user in API calls |
| name | object | Contains first_name and last_name sub-fields | required | optional | Nested object with first_name and last_name keys |
| string | Primary email address of the team member | required | optional | Used as login identifier | |
| role | string | User role within the Nimble account (e.g., admin, user) | optional | optional | Controls permissions within the account |
| avatar | string (URL) | URL to the user's profile avatar image | optional | optional | Read-only in most contexts |
| created_at | string (ISO 8601) | Timestamp when the team member was added | system-generated | immutable |
Core endpoints
List team members
- Method: GET
- URL:
https://api.nimble.com/api/v1/team/members - Watch out for: Returns only members of the authenticated account; does not expose cross-account user data.
Request example
GET /api/v1/team/members HTTP/1.1
Host: api.nimble.com
Authorization: Bearer <token>
Response example
{
"resources": [
{"id": "abc123", "email": "user@example.com",
"name": {"first_name": "Jane", "last_name": "Doe"},
"role": "admin"}
],
"meta": {"total": 5}
}
Get current authenticated user
- Method: GET
- URL:
https://api.nimble.com/api/v1/myself - Watch out for: Returns the user associated with the API token, not an arbitrary user lookup.
Request example
GET /api/v1/myself HTTP/1.1
Host: api.nimble.com
Authorization: Bearer <token>
Response example
{
"id": "abc123",
"email": "user@example.com",
"name": {"first_name": "Jane", "last_name": "Doe"},
"role": "admin"
}
List contacts
- Method: GET
- URL:
https://api.nimble.com/api/v1/contacts - Watch out for: Contacts are CRM records, not platform users. Do not conflate with team member management.
Request example
GET /api/v1/contacts?per_page=30&page=1 HTTP/1.1
Host: api.nimble.com
Authorization: Bearer <token>
Response example
{
"resources": [{"id": "xyz789", "fields": {...}}],
"meta": {"total": 120, "per_page": 30, "page": 1}
}
Create contact
- Method: POST
- URL:
https://api.nimble.com/api/v1/contact - Watch out for: Field names use spaces (e.g., 'first name'), not underscores. Incorrect field name casing causes silent failures.
Request example
POST /api/v1/contact HTTP/1.1
Content-Type: application/json
Authorization: Bearer <token>
{"fields":{"first name":[{"value":"Jane"}],
"email":[{"value":"jane@example.com","modifier":"work"}]}}
Response example
{
"id": "xyz789",
"fields": {
"first name": [{"value": "Jane"}],
"email": [{"value": "jane@example.com", "modifier": "work"}]
}
}
Update contact
- Method: PUT
- URL:
https://api.nimble.com/api/v1/contact/{id} - Watch out for: Only fields included in the request body are updated; omitted fields are preserved.
Request example
PUT /api/v1/contact/xyz789 HTTP/1.1
Content-Type: application/json
Authorization: Bearer <token>
{"fields":{"phone":[{"value":"555-1234","modifier":"work"}]}}
Response example
{
"id": "xyz789",
"fields": {
"phone": [{"value": "555-1234", "modifier": "work"}]
}
}
Delete contact
- Method: DELETE
- URL:
https://api.nimble.com/api/v1/contact/{id} - Watch out for: Deletion is permanent and cannot be undone via API.
Request example
DELETE /api/v1/contact/xyz789 HTTP/1.1
Host: api.nimble.com
Authorization: Bearer <token>
Response example
HTTP/1.1 204 No Content
Rate limits, pagination, and events
- Rate limits: Nimble enforces per-account rate limits on API requests. Exact published limits are not fully documented in official sources.
- Rate-limit headers: Yes
- Retry-After header: No
- Rate-limit notes: HTTP 429 is returned when rate limit is exceeded. Specific request-per-minute or per-day limits are not published in official documentation as of research date.
- Pagination method: offset
- Default page size: 30
- Max page size: 100
- Pagination pointer: per_page / page
| Plan | Limit | Concurrent |
|---|---|---|
| Standard ($24.90/user/mo annual) | Not publicly specified; contact Nimble support for current limits | 0 |
- Webhooks available: No
- Webhook notes: Nimble does not document a native outbound webhook system in its official API reference as of research date.
- Alternative event strategy: Use polling against the contacts or team endpoints, or leverage Zapier/Make integrations which provide trigger-based automation on Nimble events.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Not documented
- Endpoint: Not documented
Limitations:
- No SCIM 2.0 provisioning endpoint is documented in official Nimble developer documentation.
- Okta integration is available but appears to be SSO-only (no automated provisioning/deprovisioning via SCIM).
- User lifecycle management must be performed manually through the Nimble UI or via the team members API.
Common scenarios
Three integration scenarios are well-supported by the current API surface:
Roster audit against an identity graph: GET /api/v1/team/members returns the full member list with id, email, role, and created_at. Parse the resources array and use meta.total to confirm completeness. This is read-only; no pagination is documented for this endpoint.
Token context validation: GET /api/v1/myself returns the user bound to the active token. Use this before any write operation to confirm the token's identity and role - there is no admin-impersonation path, so token scope is strictly per-user.
Bulk contact import: POST to /api/v1/contact with a fields object. Field names must use spaces and lowercase exactly (e.g., 'first name', not 'firstName' or 'first_name') - incorrect naming causes silent failures with no error surfaced. Monitor the 25,000 contact account limit before bulk runs; exceeding it will cause failures.
Contacts and team members are separate API concerns. Do not conflate /api/v1/contacts (CRM records) with /api/v1/team/members (licensed users).
Audit all team members in a Nimble account
- Authenticate with a valid API token (Settings > API Tokens in Nimble UI).
- GET https://api.nimble.com/api/v1/team/members with Authorization: Bearer
. - Parse the 'resources' array to extract id, email, name, and role for each member.
- Use meta.total to confirm all members were returned (no pagination documented for this endpoint).
Watch out for: This endpoint returns read-only data; you cannot create or remove team members via API - those actions require the Nimble admin UI.
Bulk import contacts via API
- Authenticate with an API token that has write_contacts scope.
- For each contact, POST to https://api.nimble.com/api/v1/contact with a JSON body containing 'fields' object.
- Use field names exactly as Nimble expects them (e.g., 'first name', 'last name', 'email').
- Handle HTTP 429 responses with exponential backoff.
- Verify each created contact by checking the returned 'id' field.
Watch out for: Field name format is strict - spaces and lowercase required. Exceeding the 25,000 contact limit per account will cause failures; monitor account usage before bulk imports.
Identify the authenticated user context for a token
- Issue GET https://api.nimble.com/api/v1/myself with the API token.
- Parse the response to retrieve the user's id, email, name, and role.
- Use this to validate which Nimble user account the token belongs to before performing write operations.
Watch out for: Each API token is scoped to a single Nimble user; there is no service account or admin-impersonation token concept documented.
Why building this yourself is a trap
The most significant integration trap is the hard boundary between what the API can read and what it can write. The team members endpoint is read-only - you can audit the roster and feed it into an identity graph, but you cannot invite, update roles, or remove users programmatically.
Any automation that assumes full lifecycle control via API will fail silently or require a UI fallback.
The contact field naming convention is a second common failure point. Nimble uses space-delimited lowercase field names ('first name', 'last name') rather than camelCase or snake_case. Incorrect field names do not return validation errors - they are silently dropped, producing incomplete records that are difficult to detect at scale.
No SCIM support means Okta and similar IdPs cannot drive provisioning or deprovisioning in Nimble. The Okta integration is SSO-only. Teams building identity graph pipelines that expect bidirectional sync will need to treat Nimble as a read-only node or route all write operations through the admin UI.
Rate limit specifics are unpublished; build retry logic with exponential backoff from the start rather than retrofitting it after hitting 429s in production.
Automate Nimble 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.