Summary and recommendation
Amplitude exposes a SCIM 2.0 API at https://core.amplitude.com/scim/1 authenticated via a static Bearer token (the SCIM Key) generated in Access and SSO Settings. The API supports full user and group lifecycle: list, get, create (invite), full-replace update, and group membership management.
SCIM must be explicitly enabled by an Admin before the key can be generated; the key is shown exactly once and, if regenerated, immediately invalidates all existing consumers. User IDs in SCIM routes are email addresses (strings); group IDs are numeric integers - do not conflate the two.
The rate limit is 100 requests per minute per org; burst increases require contacting Support or your CSM. Amplitude does not emit outbound webhooks for org-level events, so state change detection requires polling.
For teams managing Amplitude alongside a broader SaaS portfolio, Stitchflow's MCP server with ~100 deep IT/identity integrations provides a unified provisioning layer that handles SCIM token management, pagination, and cross-app deprovisioning logic without custom glue code.
API quick reference
| Has user API | Yes |
| Auth method | Bearer Token (SCIM Key) |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise (keys-and-tokens doc states Enterprise; context seed notes Growth may also qualify — confirm with Amplitude Sales/CSM) |
Authentication
Auth method: Bearer Token (SCIM Key)
Setup steps
- Ensure your Amplitude organization is on the Enterprise plan (SCIM is gated to Enterprise).
- Navigate to Settings > Organization settings > Access and SSO Settings > Provisioning Settings.
- Set the 'Enable SCIM Provisioning' toggle to Enabled and save.
- Click 'Generate SCIM Key' to create the bearer token.
- Copy and securely store the key immediately - it is only shown once.
- Use the key as the Bearer Token in the Authorization header: 'Authorization: Bearer
'. - If integrating with an IdP (e.g., Okta), paste the SCIM key as the API Token in the IdP's provisioning configuration.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| SCIM Key (org-level bearer token) | Single static token with global user management permissions for the entire Amplitude organization. Not a scoped OAuth token. | All SCIM API operations: list/get/create/update/delete users and groups. |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string (email) | Unique identifier for the user in Amplitude; must be a valid email address. | required | immutable | Used as the URL path parameter for GET/PUT on a specific user. Cannot be changed after creation. |
| userName | string (email) | SCIM userName; must match id and be a valid email. | required | immutable | Must equal id. Email address cannot be changed via SCIM. |
| name.givenName | string | User's first name. | optional | updatable | Placeholder 'NO_GIVEN_NAME' used for pending users who have never joined any Amplitude org. |
| name.familyName | string | User's last name. | optional | updatable | Placeholder 'NO_FAMILY_NAME' used for pending users who have never joined any Amplitude org. |
| active | boolean | Whether the user is active in the Amplitude organization. | optional | updatable | Setting active=false via PUT removes the user from the organization and revokes all access immediately. |
| emails | array of objects [{value, primary}] | User's email addresses. Primary email must match id/userName. | required | read-only | Email cannot be changed. primary must be true for the matching address. |
| groups | array | Permission groups the user belongs to. | ignored | ignored | Groups field is ignored on user routes. Use Group API routes (/scim/1/Groups) to manage group membership. |
| meta.resourceType | string | Always 'User' for user resources. | optional | read-only | Server-set metadata. |
| schemas | array of strings | SCIM schema URIs. Must include 'urn:ietf:params:scim:schemas:core:2.0:User'. | required | required | Standard SCIM 2.0 schema declaration. |
Core endpoints
List Users
- Method: GET
- URL:
https://core.amplitude.com/scim/1/Users - Watch out for: Returns both pending (invited but not yet joined) and active users. Supports pagination via startIndex/itemsPerPage and SCIM filter parameter.
Request example
GET /scim/1/Users HTTP/1.1
Host: core.amplitude.com
Authorization: Bearer {scim-token}
Response example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"startIndex": 1,
"itemsPerPage": 100,
"totalResults": 1,
"Resources": [{"id": "user@example.com", "userName": "user@example.com", "active": true}]
}
Get User by ID
- Method: GET
- URL:
https://core.amplitude.com/scim/1/Users/{userId} - Watch out for: userId in the URL path is the user's email address, not a numeric ID.
Request example
GET /scim/1/Users/user@example.com HTTP/1.1
Host: core.amplitude.com
Authorization: Bearer {scim-token}
Response example
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "user@example.com",
"userName": "user@example.com",
"name": {"givenName": "Data", "familyName": "Monster"},
"active": true,
"emails": [{"primary": true, "value": "user@example.com"}]
}
Create User (invite)
- Method: POST
- URL:
https://core.amplitude.com/scim/1/Users - Watch out for: Triggers an email invitation to the user. Fails if the user already exists or has a pending invite. id and userName must both be valid email addresses and must match.
Request example
POST /scim/1/Users HTTP/1.1
Host: core.amplitude.com
Authorization: Bearer {scim-token}
Content-Type: application/json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "newuser@example.com",
"userName": "newuser@example.com",
"name": {"givenName": "New", "familyName": "User"},
"emails": [{"value": "newuser@example.com", "primary": true}]
}
Response example
HTTP/1.1 201 Created
{original request body returned}
Update User (full replace)
- Method: PUT
- URL:
https://core.amplitude.com/scim/1/Users/{userId} - Watch out for: Setting active=false immediately removes the user from the org and revokes all access. Email (id/userName) cannot be changed.
Request example
PUT /scim/1/Users/user@example.com HTTP/1.1
Host: core.amplitude.com
Authorization: Bearer {scim-token}
Content-Type: application/json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "user@example.com",
"active": false
}
Response example
HTTP/1.1 200 OK
{updated user object}
List Groups
- Method: GET
- URL:
https://core.amplitude.com/scim/1/Groups - Watch out for: Group IDs are numeric integers, not email addresses. Members are returned with email as 'value' and display name as 'display'.
Request example
GET /scim/1/Groups HTTP/1.1
Host: core.amplitude.com
Authorization: Bearer {scim-token}
Response example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"startIndex": 1,
"itemsPerPage": 100,
"totalResults": 1,
"Resources": [{"id": 632, "displayName": "My Group", "members": []}]
}
Get Group by ID
- Method: GET
- URL:
https://core.amplitude.com/scim/1/Groups/{groupId} - Watch out for: groupId is a numeric integer. All core Group Schema fields are supported.
Request example
GET /scim/1/Groups/632 HTTP/1.1
Host: core.amplitude.com
Authorization: Bearer {scim-token}
Response example
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"id": 632,
"displayName": "My Group",
"members": [{"value": "user@example.com", "display": "User Name"}]
}
Update User Properties (end-user analytics profile)
- Method: POST
- URL:
https://api2.amplitude.com/identify - Watch out for: Uses project-level API key in the POST body (not Authorization header). Does not count as an event. Property updates only appear on the user's next event. Changing user_id to a new value creates a new Amplitude user.
Request example
POST /identify HTTP/1.1
Host: api2.amplitude.com
Content-Type: application/x-www-form-urlencoded
api_key=<API-KEY>&identification=[{"user_id":"12345","user_properties":{"plan":"premium"}}]
Response example
HTTP/1.1 200 OK
{"code": 200}
Delete / Privacy (User Privacy API)
- Method: POST
- URL:
https://amplitude.com/api/2/deletions/users - Watch out for: Requires org-level API key + secret key (Basic auth, base64-encoded). Deletion is asynchronous and processed in batches. Separate from SCIM deprovisioning.
Request example
POST /api/2/deletions/users HTTP/1.1
Host: amplitude.com
Authorization: Basic <base64(api_key:secret_key)>
Content-Type: application/json
{"user_ids": ["12345"], "delete_from_org": true}
Response example
HTTP/1.1 200 OK
{"day": "2024-01-15", "status": "staging", "amplitude_ids": [...]}
Rate limits, pagination, and events
- Rate limits: SCIM API: 100 requests per minute per organization. Identify API: 1,800 user property updates per hour per Amplitude ID. User Activity/Search (Dashboard REST API): 10 concurrent requests, 360 queries/hour. General Dashboard REST API: 5 concurrent requests, 108,000 cost units/hour. HTTP V2 ingest: 100 batches/sec, 1,000 events/sec. User Profile API: 600 requests/minute per org.
- Rate-limit headers: No
- Retry-After header: No
- Rate-limit notes: HTTP 429 is returned when limits are exceeded. For SCIM, Amplitude can lift the 100 req/min cap for burst use cases on a per-request basis - contact Support or a CSM. For Identify API throttling, pause 15 seconds before retrying on 429. SCIM path '/scim/1' uses '1' to denote Amplitude's internal API version, not SCIM 1.1.
- Pagination method: offset
- Default page size: 100
- Max page size: 0
- Pagination pointer: startIndex / itemsPerPage (SCIM 2.0 standard list response fields)
| Plan | Limit | Concurrent |
|---|---|---|
| All plans (SCIM API) | 100 requests/minute per organization | 0 |
| All plans (Identify API) | 1,800 user property updates/hour per Amplitude ID | 0 |
| All plans (Dashboard REST API - User Activity/Search) | 360 queries/hour | 10 |
| All plans (Dashboard REST API - general) | 108,000 cost units/hour | 5 |
| All plans (User Profile API) | 600 requests/minute per org | 0 |
- Webhooks available: No
- Webhook notes: Amplitude does not offer native outbound webhooks for user-management or org-level events (e.g., user created, user deprovisioned). Amplitude is a data ingestion target, not a webhook emitter for admin events.
- Alternative event strategy: Use SCIM API polling to detect user/group state changes. For inbound data pipelines, third-party tools (e.g., Integrate.io) can receive webhooks from other systems and forward events to Amplitude's HTTP V2 or Identify APIs.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise (keys-and-tokens doc states Enterprise; context seed notes Growth may also qualify - confirm with Amplitude Sales/CSM)
Endpoint: https://core.amplitude.com/scim/1
Supported operations: GET /scim/1/Users - list all users (pending + joined), with pagination and filtering, GET /scim/1/Users/{userId} - get a single user by email, POST /scim/1/Users - create/invite a user (sends invitation email), PUT /scim/1/Users/{userId} - full update of a user (including deactivation via active=false), GET /scim/1/Groups - list all permission groups, GET /scim/1/Groups/{groupId} - get a single group by numeric ID, POST /scim/1/Groups - create a permission group, PUT /scim/1/Groups/{groupId} - update a group (members, displayName), DELETE /scim/1/Groups/{groupId} - delete a permission group
Limitations:
- SCIM must be explicitly enabled in Access and SSO Settings before the key can be generated.
- Regenerating the SCIM key immediately invalidates the old key - even if other page changes are unsaved.
- Email address (id/userName) is immutable after user creation; cannot be changed via SCIM.
- The Groups field is ignored on user POST/PUT routes; group membership must be managed via Group API routes.
- Only a subset of SCIM core User Schema fields are supported (id, userName, name.givenName, name.familyName, active, emails, groups, meta).
- Path prefix is /scim/1 - the '1' is Amplitude's internal API version, not SCIM 1.1.
- Base URL varies by data residency region - check the Endpoints table in official docs for EU/other regions.
- Pending users who have never joined any Amplitude org will return placeholder names (NO_GIVEN_NAME, NO_FAMILY_NAME) on import.
- Rate limit is 100 requests/minute per org; burst increases require contacting Support or CSM.
- SCIM key has global user management permissions - treat as a highly privileged secret.
Common scenarios
Three integration patterns cover the majority of production use cases. For IdP-driven provisioning (e.
g. , Okta), generate the SCIM Key in Amplitude, paste it as the API Token in the Okta Amplitude app, then assign users or groups - Okta sends POST /scim/1/Users per user, and Amplitude dispatches an invitation email.
users appear as pending until they complete sign-up, and placeholder names (NO_GIVEN_NAME / NO_FAMILY_NAME) are expected for net-new Amplitude accounts. For deprovisioning, remove the user's IdP assignment.
the IdP sends PUT /scim/1/Users/{userEmail} with active=false, which immediately and irreversibly removes org access - transfer content ownership in the Amplitude UI before triggering this, as there is no grace period or undo via API.
For group sync, all group membership changes must go through /scim/1/Groups routes; the Groups field on user POST/PUT routes is silently ignored, which is the single most common integration bug in this API surface.
Provision a new employee via IdP (Okta)
- Ensure Amplitude org is on Enterprise plan and SCIM is enabled in Access and SSO Settings.
- Generate SCIM Key in Amplitude and copy it.
- In Okta Integration Network, find the Amplitude app and configure API Integration using the SCIM key as the API Token.
- Assign the user or their group to the Amplitude Okta application.
- Okta sends POST /scim/1/Users to core.amplitude.com with the user's email, givenName, and familyName.
- Amplitude sends an invitation email to the user to complete sign-up.
- User appears as 'pending' in Amplitude until they accept the invite and log in.
Watch out for: If the user has never been in any Amplitude org, their name will show as NO_GIVEN_NAME / NO_FAMILY_NAME until they complete sign-up. Okta's 'Import Users' will reflect these placeholders.
Deprovision a departing employee
- Remove the user's assignment from the Amplitude application in the IdP (e.g., Okta).
- IdP sends PUT /scim/1/Users/{userEmail} with active=false.
- Amplitude immediately removes the user from the organization and revokes all access.
- Optionally, use Amplitude Admin UI to bulk-transfer ownership of the user's charts, dashboards, and cohorts to another user before deprovisioning.
Watch out for: Deprovisioning via SCIM (active=false) is immediate and irreversible via API. Content created by the removed user becomes unassigned - transfer ownership first to avoid orphaned assets.
Sync permission groups from IdP
- Create permission groups in Amplitude (Settings > Organization settings > Members & Groups > Groups tab).
- In the IdP, enable 'Push Groups' and map IdP groups to Amplitude permission groups.
- IdP sends POST /scim/1/Groups to create new groups or PUT /scim/1/Groups/{groupId} to update membership.
- To add a user to a group, send PUT /scim/1/Groups/{groupId} with the updated members array (do not use the Groups field on user routes).
- Verify group membership in Amplitude UI under Members & Groups.
Watch out for: The Groups field on user POST/PUT routes is silently ignored. All group membership changes must go through the Group API routes (/scim/1/Groups). A user can belong to multiple groups; Amplitude grants the highest permission level across all group memberships.
Why building this yourself is a trap
The SCIM API has three non-obvious failure modes worth calling out explicitly. First, setting active=false is a hard delete from the org - not a soft disable - and is irreversible via API; any content the user owns becomes unassigned immediately, so orchestration logic must sequence a content-transfer step before deprovisioning, not after.
Second, the SCIM Key is a single global credential with full user management permissions across the entire org; there is no scope restriction, no expiry, and no rotation reminder - loss or exposure requires immediate regeneration, which breaks all active IdP integrations simultaneously.
Third, the Identify API (api2.amplitude.com/identify) and the SCIM API are entirely separate surfaces with different auth schemes (project-level API key in POST body vs. org-level Bearer token in Authorization header) and different purposes (end-user analytics profile updates vs. org membership management); mixing credentials or endpoints produces silent failures rather than explicit errors in several cases.
Automate Amplitude 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.