Summary and recommendation
Twilio exposes user management through two distinct API surfaces: the Organizations REST API (`https://accounts.twilio.com/v1/Organizations/{OrganizationSid}/Users`) for direct programmatic control, and a SCIM 2.0 endpoint (`https://accounts.twilio.com/scim/v2/Organizations/{OrganizationSid}`) for IdP-driven provisioning. Both require an Organization SID (OR...), which is separate from the Account SID (AC...) used for product APIs.
SCIM is restricted to Enterprise plans with an active SSO add-on and authenticates via a dedicated Organization-level API key - standard Account SID/Auth Token credentials are rejected at the SCIM endpoint.
Integrating Twilio into an identity graph requires handling both surfaces: the REST API for audit and role enumeration, SCIM for lifecycle events sourced from Okta, Entra ID, or OneLogin.
API quick reference
| Has user API | Yes |
| Auth method | HTTP Basic Auth (Account SID as username, Auth Token as password); API Keys also supported as an alternative credential pair |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise (with SSO add-on) |
Authentication
Auth method: HTTP Basic Auth (Account SID as username, Auth Token as password); API Keys also supported as an alternative credential pair
Setup steps
- Log in to Twilio Console at console.twilio.com
- Navigate to Account > API keys & tokens
- Copy your Account SID and Auth Token, or create a new API Key (Standard or Main) to obtain a Key SID and Secret
- Use Account SID + Auth Token (or API Key SID + Secret) as Basic Auth credentials: Authorization: Basic base64(SID:token)
- For SCIM provisioning, generate an Organization-level API key from the Twilio Console under your Organization settings (requires Enterprise plan with SSO)
Required scopes
| Scope | Description | Required for |
|---|---|---|
| N/A - role-based | Twilio REST API does not use OAuth scopes; access is governed by the Account SID/Auth Token or API Key permissions and Console role assignments (Administrator, Developer, Billing Manager, etc.) | All API operations |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| sid | string | Unique identifier for the user (e.g., US...) | auto-generated | immutable | Twilio-assigned SID prefix 'US' |
| string | User's email address; used as login identifier | required | supported | Must be unique within the organization | |
| friendly_name | string | Display name for the user | optional | supported | |
| role_sid | string | SID of the Console role assigned to the user | optional | supported | Roles: Administrator, Developer, Billing Manager, etc. |
| account_sid | string | SID of the account the user belongs to | auto-assigned | immutable | |
| date_created | datetime (ISO 8601) | Timestamp when the user was created | auto-generated | immutable | |
| date_updated | datetime (ISO 8601) | Timestamp of last update | auto-generated | auto-updated | |
| url | string (URI) | Canonical URL of the user resource | auto-generated | immutable | |
| first_name | string | User's first name (SCIM: name.givenName) | optional | supported | Exposed via SCIM; may not appear in all REST responses |
| last_name | string | User's last name (SCIM: name.familyName) | optional | supported | Exposed via SCIM; may not appear in all REST responses |
| active | boolean | Whether the user account is active (SCIM attribute) | defaults to true | supported | Setting to false deactivates the user; primary deactivation mechanism via SCIM |
Core endpoints
List Users in Organization
- Method: GET
- URL:
https://accounts.twilio.com/v1/Organizations/{OrganizationSid}/Users - Watch out for: Requires Organization SID, not Account SID. Organization SID is found in Console under Organization settings.
Request example
GET /v1/Organizations/ORxxx/Users
Authorization: Basic base64(AccountSID:AuthToken)
Response example
{
"users": [{"sid":"USxxx","email":"user@example.com","friendly_name":"Jane Doe","role_sid":"RLxxx"}],
"meta": {"page":0,"page_size":50,"next_page_url":null}
}
Fetch a Single User
- Method: GET
- URL:
https://accounts.twilio.com/v1/Organizations/{OrganizationSid}/Users/{UserSid} - Watch out for: User SID (US...) is distinct from Account SID (AC...).
Request example
GET /v1/Organizations/ORxxx/Users/USxxx
Authorization: Basic base64(AccountSID:AuthToken)
Response example
{
"sid": "USxxx",
"email": "user@example.com",
"friendly_name": "Jane Doe",
"role_sid": "RLxxx",
"date_created": "2024-01-15T10:00:00Z"
}
Create/Invite User
- Method: POST
- URL:
https://accounts.twilio.com/v1/Organizations/{OrganizationSid}/Users - Watch out for: Creates an invitation; user must accept via email. Does not immediately activate the account.
Request example
POST /v1/Organizations/ORxxx/Users
Content-Type: application/x-www-form-urlencoded
Email=user@example.com&RoleSid=RLxxx&FriendlyName=Jane+Doe
Response example
{
"sid": "USxxx",
"email": "user@example.com",
"role_sid": "RLxxx",
"date_created": "2024-06-01T12:00:00Z"
}
Update User Role
- Method: POST
- URL:
https://accounts.twilio.com/v1/Organizations/{OrganizationSid}/Users/{UserSid} - Watch out for: Twilio REST API uses POST for updates on some resources, not PATCH. Verify current behavior in official docs.
Request example
POST /v1/Organizations/ORxxx/Users/USxxx
Content-Type: application/x-www-form-urlencoded
RoleSid=RLyyy
Response example
{
"sid": "USxxx",
"role_sid": "RLyyy",
"date_updated": "2024-06-02T09:00:00Z"
}
Delete User
- Method: DELETE
- URL:
https://accounts.twilio.com/v1/Organizations/{OrganizationSid}/Users/{UserSid} - Watch out for: Removes user from the organization. Cannot be undone via API; user must be re-invited.
Request example
DELETE /v1/Organizations/ORxxx/Users/USxxx
Authorization: Basic base64(AccountSID:AuthToken)
Response example
HTTP 204 No Content
List Subaccounts
- Method: GET
- URL:
https://api.twilio.com/2010-04-01/Accounts.json - Watch out for: Subaccounts are not the same as Console users. Subaccounts are isolated Twilio environments, not individual human users.
Request example
GET /2010-04-01/Accounts.json?FriendlyName=MySubaccount
Authorization: Basic base64(AccountSID:AuthToken)
Response example
{
"accounts": [{"sid":"ACxxx","friendly_name":"MySubaccount","status":"active"}],
"next_page_uri": null
}
SCIM List Users
- Method: GET
- URL:
https://accounts.twilio.com/scim/v2/Organizations/{OrganizationSid}/Users - Watch out for: Requires Enterprise plan with SSO add-on. Auth uses an Organization-level API key, not standard Account SID/Auth Token.
Request example
GET /scim/v2/Organizations/ORxxx/Users?startIndex=1&count=50
Authorization: Bearer {org_api_key_secret}
Response example
{
"schemas":["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults":2,
"Resources":[{"id":"USxxx","userName":"user@example.com","active":true}]
}
SCIM Deactivate User
- Method: PATCH
- URL:
https://accounts.twilio.com/scim/v2/Organizations/{OrganizationSid}/Users/{UserSid} - Watch out for: SCIM PATCH deactivation does not delete the user; it suspends access. Full removal requires DELETE.
Request example
PATCH /scim/v2/Organizations/ORxxx/Users/USxxx
Content-Type: application/scim+json
{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"replace","path":"active","value":false}]}
Response example
{
"id": "USxxx",
"userName": "user@example.com",
"active": false
}
Rate limits, pagination, and events
- Rate limits: Twilio enforces per-endpoint and per-account concurrent request limits. Limits vary by product and account tier. The Accounts API and IAM endpoints are subject to general REST API limits.
- Rate-limit headers: Yes
- Retry-After header: No
- Rate-limit notes: HTTP 429 is returned when rate limits are exceeded. Twilio recommends exponential backoff. Specific numeric limits for IAM/SCIM endpoints are not publicly documented; check response headers for current limits.
- Pagination method: token
- Default page size: 50
- Max page size: 1000
- Pagination pointer: PageSize / NextPageUri (Twilio uses page-based navigation with NextPageUri in response body)
| Plan | Limit | Concurrent |
|---|---|---|
| Pay-as-you-go / Trial | Varies by endpoint; typically 20–100 requests/sec for most REST endpoints | 0 |
| Enterprise | Higher limits negotiated; contact Twilio support for specifics | 0 |
- Webhooks available: No
- Webhook notes: Twilio does not offer webhooks specifically for Console user-management events (user created, role changed, deleted). Twilio webhooks are product-level (SMS received, call status, etc.), not IAM/user-lifecycle events.
- Alternative event strategy: Poll the Organizations Users API or use SCIM provisioning events triggered by your IdP (Okta, Entra ID, OneLogin) for user lifecycle automation.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise (with SSO add-on)
Endpoint: https://accounts.twilio.com/scim/v2/Organizations/{OrganizationSid}
Supported operations: GET /Users (list users), GET /Users/{id} (fetch user), POST /Users (create user), PUT /Users/{id} (replace user), PATCH /Users/{id} (update user, including deactivation), DELETE /Users/{id} (remove user), GET /Groups (list groups), POST /Groups (create group), PATCH /Groups/{id} (update group membership), DELETE /Groups/{id} (remove group), GET /ServiceProviderConfig, GET /Schemas
Limitations:
- Requires Enterprise plan with SSO add-on; not available on pay-as-you-go or standard plans
- SSO must be configured before SCIM provisioning can be enabled
- Authentication uses Organization-level API key, not standard Account SID/Auth Token
- Supported IdPs: Okta, Microsoft Entra ID (Azure AD), OneLogin; Google Workspace not officially supported
- SCIM Groups map to Twilio Console roles/groups; mapping must be configured in IdP
- Deactivating a user via SCIM sets active=false but does not immediately revoke active sessions
Common scenarios
Three scenarios cover the majority of programmatic use cases. For IdP-driven provisioning, configure your IdP with the SCIM base URL and an Organization API key secret as the Bearer token; Twilio will send an invitation email on POST /Users regardless - user acceptance is always required and cannot be bypassed via API.
For deprovisioning a departed employee, SCIM PATCH with active=false suspends access but does not terminate active sessions immediately; DELETE on the Organizations Users endpoint is the only path to immediate, hard removal, and it is irreversible via API.
For access auditing, paginate GET /v1/Organizations/{OrganizationSid}/Users with PageSize up to 1000, iterate via NextPageUri, and map role_sid values to human-readable role names manually - role SIDs are opaque identifiers with no self-describing label in the response payload.
Provision a new Console user via SCIM (IdP-driven)
- Ensure Enterprise plan with SSO add-on is active and SSO is configured in Twilio Console
- Generate an Organization-level API key in Console under Organization > Settings > API Keys
- Configure your IdP (Okta/Entra/OneLogin) with Twilio SCIM base URL: https://accounts.twilio.com/scim/v2/Organizations/{OrganizationSid}
- Set the Bearer token in your IdP to the Organization API key secret
- Assign the user to the Twilio application in your IdP
- IdP sends SCIM POST /Users with userName (email), name.givenName, name.familyName, active=true
- Twilio creates the user and sends an invitation email; user must accept to activate
Watch out for: If SSO is not configured first, SCIM provisioning will fail. The user invitation email is always sent regardless of SCIM provisioning.
Deactivate a departed employee
- Identify the user's SID via GET /v1/Organizations/{OrganizationSid}/Users or SCIM GET /Users?filter=userName eq "user@example.com"
- Via SCIM: PATCH /scim/v2/Organizations/{OrganizationSid}/Users/{UserSid} with Operations: [{op:replace, path:active, value:false}]
- Alternatively, DELETE /v1/Organizations/{OrganizationSid}/Users/{UserSid} to fully remove the user
- If using IdP, simply remove the user from the Twilio app assignment; IdP will send SCIM PATCH active=false automatically
Watch out for: SCIM PATCH active=false suspends the user but does not immediately terminate active sessions. For immediate revocation, use DELETE.
List all Console users and audit roles
- Authenticate with Account SID + Auth Token or API Key
- GET https://accounts.twilio.com/v1/Organizations/{OrganizationSid}/Users?PageSize=100
- Iterate through pages using NextPageUri from the meta object until null
- For each user, record sid, email, friendly_name, role_sid, date_created
- Cross-reference role_sid against known role SIDs to map to human-readable role names (Administrator, Developer, etc.)
Watch out for: Role SIDs are not self-descriptive; you must maintain a mapping of role SIDs to role names, or fetch roles separately if a roles listing endpoint is available in your Console.
Why building this yourself is a trap
The most common integration failure is credential mismatch: developers authenticate SCIM requests with Account SID/Auth Token and receive 401s because SCIM requires an Organization-level API key generated separately under Organization > Settings > API Keys in the Console.
A second trap is conflating subaccounts with users - subaccounts (https://api.twilio.com/2010-04-01/Accounts.json) are isolated API environments, not human identities, and appear nowhere in the Organizations Users API. A third caveat: Twilio does not emit IAM-scoped webhooks; there are no event notifications for user creation, role changes, or deletion.
Lifecycle automation must either poll the Organizations Users API on a schedule or rely entirely on IdP-initiated SCIM pushes. Rate limits for IAM and SCIM endpoints are not publicly documented with specific thresholds - implement exponential backoff on HTTP 429 from the start, not as an afterthought.
Automate Twilio 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.