Summary and recommendation
Airtable exposes two parallel API surfaces for user management: the Enterprise REST API (base URL https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}) and the SCIM 2.0 API (base URL https://airtable.com/scim/v2). Both require a Personal Access Token (PAT) passed as a Bearer token; legacy API keys were fully deprecated on February 1, 2024. OAuth 2.0 is supported for third-party integrations.
Enterprise API scopes (enterprise.*) are only available on Enterprise Scale plan accounts - Business plan PATs cannot include these scopes. SCIM user provisioning is available on Business and Enterprise Scale; SCIM group management requires Enterprise Scale. SSO must be configured before SCIM can be used.
Stitchflow connects to Airtable through an MCP server with ~100 deep IT/identity integrations, enabling automated user lifecycle management without building or maintaining direct API logic.
API quick reference
| Has user API | Yes |
| Auth method | Personal Access Token (PAT) — Bearer token in Authorization header. OAuth 2.0 also supported for third-party integrations. Legacy API keys fully deprecated February 1, 2024. |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Business (user SCIM only); Enterprise Scale (user SCIM + group SCIM). SSO is a mandatory prerequisite. |
Authentication
Auth method: Personal Access Token (PAT) - Bearer token in Authorization header. OAuth 2.0 also supported for third-party integrations. Legacy API keys fully deprecated February 1, 2024.
Setup steps
- Log in to Airtable Developer Hub and navigate to https://airtable.com/create/tokens.
- Click 'Personal access tokens' in the left nav, then '+ Create new token'.
- Assign a name and add the required scopes (e.g., enterprise.scim.usersAndGroups:manage for SCIM; enterprise.* scopes require Enterprise Scale plan).
- Select the bases/workspaces the token can access, then click 'Create Token' and copy the value immediately (shown only once).
- Pass the token in all API requests as: Authorization: Bearer
. - For OAuth 2.0 integrations: register an OAuth app at https://airtable.com/create/oauth, obtain Client ID and Client Secret, implement the authorization code flow, and use the resulting access token as Bearer.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| enterprise.scim.usersAndGroups:manage | Read and write SCIM users and groups via the SCIM 2.0 API. | All SCIM provisioning operations (create, read, update, deactivate users; manage groups on Enterprise Scale) |
| enterprise.user:read | Read enterprise user information via the Enterprise API. | GET /v0/meta/enterpriseAccounts/{enterpriseAccountId}/users/{userId} |
| enterprise.user:write | Update, activate, or deactivate enterprise users via the Enterprise API. | PATCH/DELETE user endpoints in the Enterprise API |
| enterprise.account:read | Read enterprise account metadata including user lists. | GET /v0/meta/enterpriseAccounts/{enterpriseAccountId} |
| enterprise.auditLog:read | Read audit log events for the enterprise account. | Audit log retrieval endpoints |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Airtable user ID (e.g., usrXXXXXXXXXXXXXX) | system-generated | immutable | Used as path parameter in Enterprise API user endpoints |
| string | User's email address | required | updatable via Enterprise API or SCIM (IdP-side for SCIM) | Must belong to a private domain on Business/Enterprise plans | |
| name | string | User's display name | optional | updatable | Returned in Enterprise API user info response |
| state | string (enum) | User provisioning state: 'provisioned', 'deactivated', 'unmanaged' | set to 'provisioned' on creation | updatable (activate/deactivate) | Deactivated users are not billed; sessions are terminated on deactivation |
| lastActivityTime | string (ISO 8601) | Timestamp of the user's last activity | null | system-managed | Read-only |
| isAdmin | boolean | Whether the user has enterprise admin privileges | false by default | updatable via Grant/Revoke admin endpoints | Separate grant/revoke admin endpoints exist in the Enterprise API |
| collaborations | object | User's workspace and base collaboration memberships | not set | managed via collaborator endpoints | Returned only when ?include=collaborations query param is passed |
| active (SCIM) | boolean | SCIM active attribute; maps to Airtable user activated/deactivated state | true | updatable via SCIM PATCH or PUT | Programmatic deactivation via SCIM is only supported for Okta; Entra ID has a known issue with automatic deactivation using custom integrations |
| userName (SCIM) | string | SCIM userName; maps to the user's email address in Airtable | required | updatable via IdP | Used as the matching attribute for SCIM sync |
| displayName (SCIM) | string | SCIM displayName; maps to Airtable user name | optional | updatable | |
| costCenter (SCIM extension) | string | Custom metadata attribute pushed from IdP; displayed in Admin Panel Users page | optional | must be updated in IdP; read-only within Airtable | Currently only synced via Okta for cost center data |
Core endpoints
Get enterprise user by ID or email
- Method: GET
- URL:
https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users/{userId} - Watch out for: Collaborations are not returned by default; append ?include=collaborations. Fetching all users requires iterating per-user; there is no single-call list-all-users endpoint in the Enterprise API (use SCIM GET /Users for listing).
Request example
curl -H "Authorization: Bearer $PAT" \
"https://api.airtable.com/v0/meta/enterpriseAccounts/entXXX/users/usrXXX?include=collaborations"
Response example
{
"id": "usrXXXXXXXXXXXXXX",
"email": "user@example.com",
"name": "Jane Doe",
"state": "provisioned",
"lastActivityTime": "2024-01-15T10:00:00.000Z"
}
Update user (email, activate/deactivate) - single
- Method: PATCH
- URL:
https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users/{userId} - Watch out for: Deactivating a user logs out all sessions but does not delete the account. To permanently delete, use the DELETE endpoint or remove via Admin UI after transferring owned bases.
Request example
curl -X PATCH \
-H "Authorization: Bearer $PAT" \
-H "Content-Type: application/json" \
-d '{"state": "deactivated"}' \
"https://api.airtable.com/v0/meta/enterpriseAccounts/entXXX/users/usrXXX"
Response example
{
"id": "usrXXXXXXXXXXXXXX",
"state": "deactivated"
}
Batch manage users (activate/deactivate/email update)
- Method: POST
- URL:
https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users - Watch out for: Batch endpoint supports updating email and/or state for multiple users in one call. Errors are returned per-user in the errors array rather than failing the whole batch.
Request example
curl -X POST \
-H "Authorization: Bearer $PAT" \
-H "Content-Type: application/json" \
-d '{"users": [{"id": "usrXXX", "state": "deactivated"}]}' \
"https://api.airtable.com/v0/meta/enterpriseAccounts/entXXX/users"
Response example
{
"updatedUsers": [{"id": "usrXXX", "state": "deactivated"}],
"errors": []
}
Delete (remove) user from enterprise
- Method: DELETE
- URL:
https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users/{userId} - Watch out for: Permanently removes the user account. Bases and workspaces owned by the user must be transferred first or they will be lost. Prefer deactivation if re-activation may be needed.
Request example
curl -X DELETE \
-H "Authorization: Bearer $PAT" \
"https://api.airtable.com/v0/meta/enterpriseAccounts/entXXX/users/usrXXX"
Response example
{}
Grant admin access to user(s)
- Method: POST
- URL:
https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users/grantAdmin - Watch out for: Separate endpoint from general user update. Requires enterprise admin PAT scope.
Request example
curl -X POST \
-H "Authorization: Bearer $PAT" \
-H "Content-Type: application/json" \
-d '{"users": ["usrXXX"]}' \
"https://api.airtable.com/v0/meta/enterpriseAccounts/entXXX/users/grantAdmin"
Response example
{
"updatedUsers": [{"id": "usrXXX", "isAdmin": true}],
"errors": []
}
SCIM List Users
- Method: GET
- URL:
https://airtable.com/scim/v2/Users - Watch out for: SCIM requires Business or Enterprise Scale plan with SSO configured as a prerequisite. Pagination uses startIndex (1-based) and count parameters.
Request example
curl -H "Authorization: Bearer $PAT" \
"https://airtable.com/scim/v2/Users?startIndex=1&count=100"
Response example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 42,
"startIndex": 1,
"itemsPerPage": 100,
"Resources": [{"id": "usrXXX", "userName": "user@example.com", "active": true}]
}
SCIM Create User
- Method: POST
- URL:
https://airtable.com/scim/v2/Users - Watch out for: SSO must be configured before SCIM provisioning. Passwords cannot be set via SCIM. For CLAIM enterprises, SCIM can only manage claimed users.
Request example
curl -X POST \
-H "Authorization: Bearer $PAT" \
-H "Content-Type: application/json" \
-d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"user@example.com","active":true}' \
"https://airtable.com/scim/v2/Users"
Response example
{
"id": "usrXXXXXXXXXXXXXX",
"userName": "user@example.com",
"active": true,
"meta": {"resourceType": "User"}
}
SCIM Update User (replace)
- Method: PUT
- URL:
https://airtable.com/scim/v2/Users/{userId} - Watch out for: Programmatic deactivation via SCIM (setting active=false) is only supported for Okta. Entra ID custom integrations have a known issue with automatic deactivation; use the Airtable Gallery App for Entra ID instead.
Request example
curl -X PUT \
-H "Authorization: Bearer $PAT" \
-H "Content-Type: application/json" \
-d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"user@example.com","active":false}' \
"https://airtable.com/scim/v2/Users/usrXXX"
Response example
{
"id": "usrXXXXXXXXXXXXXX",
"userName": "user@example.com",
"active": false
}
Rate limits, pagination, and events
- Rate limits: 5 requests per second per base for all plans. Monthly call caps apply on Free and Team plans; Business and Enterprise Scale have unlimited monthly calls but remain subject to the per-second rate limit. Exceeding the rate limit returns HTTP 429. On Free/Team plans, exceeding the monthly cap throttles to 2 req/sec for the remainder of the month.
- Rate-limit headers: No
- Retry-After header: No
- Rate-limit notes: HTTP 429 is returned when the per-second limit is exceeded. Official docs recommend waiting 30 seconds before retrying after a 429. Batching up to 10 records per request is supported and can effectively yield up to 50 record operations per second. No official Retry-After header is documented.
- Pagination method: offset
- Default page size: 100
- Max page size: 100
- Pagination pointer: offset
| Plan | Limit | Concurrent |
|---|---|---|
| Free | 1,000 calls/month; 5 req/sec (drops to 2 req/sec after monthly cap) | 0 |
| Team | 100,000 calls/month; 5 req/sec (drops to 2 req/sec after monthly cap) | 0 |
| Business | Unlimited calls/month; 5 req/sec sustained | 0 |
| Enterprise Scale | Unlimited calls/month; 5 req/sec sustained | 0 |
- Webhooks available: Yes
- Webhook notes: Airtable provides two webhook mechanisms: (1) The Webhooks API (airtable.com/developers/web/api/webhooks-overview) allows programmatic creation of outbound webhooks on a base that fire on record-level data changes (tableData, tableFields, tableMetadata). (2) The Automations 'When webhook received' trigger provides an inbound webhook URL to trigger automations from external systems. Neither mechanism fires on user provisioning/deprovisioning events specifically.
- Alternative event strategy: Poll the Enterprise API GET user endpoint or use SCIM with an IdP (Okta/Entra ID) for user lifecycle event handling. Audit log API can be used to detect user-related admin actions.
- Webhook events: tableData (record created, updated, deleted), tableFields (field schema changes), tableMetadata (table name/description changes)
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Business (user SCIM only); Enterprise Scale (user SCIM + group SCIM). SSO is a mandatory prerequisite.
Endpoint: https://airtable.com/scim/v2
Supported operations: GET /Users - list users (paginated), POST /Users - create/provision user, GET /Users/{id} - get single user, PUT /Users/{id} - replace user (full update), PATCH /Users/{id} - partial update user, DELETE /Users/{id} - deprovision user, GET /Groups - list groups (Enterprise Scale only), POST /Groups - create group (Enterprise Scale only), GET /Groups/{id} - get single group (Enterprise Scale only), PUT /Groups/{id} - replace group (Enterprise Scale only), PATCH /Groups/{id} - update group membership (Enterprise Scale only), DELETE /Groups/{id} - delete group (Enterprise Scale only), GET /ServiceProviderConfig - SCIM service provider metadata, GET /Schemas - SCIM schema definitions
Limitations:
- SSO must be configured before SCIM can be used; passwords cannot be set via SCIM.
- Group provisioning (SCIM Groups endpoints) is unavailable on Business plan; requires Enterprise Scale.
- Programmatic user deactivation via SCIM (active=false) is only supported for Okta; Entra ID requires the Airtable Gallery App for reliable deactivation.
- For CLAIM enterprises, SCIM can only manage claimed users.
- Airtable supports only a subset of the SCIM 2.0 specification and a select list of user attributes.
- Nested groups are not supported.
- Additional metadata pushed via SCIM (e.g., cost center) cannot be edited from within Airtable; must be updated in the IdP.
- Enterprise scope PATs (enterprise.scim.usersAndGroups:manage) are only available on Enterprise Scale plans, not Business plans.
- Airtable only allows one set of IdP metadata per email domain globally.
Common scenarios
Three primary automation scenarios are well-supported by the API.
Offboarding via the Enterprise API: look up the user by email using GET /v0/meta/enterpriseAccounts/{entId}/users/{userId}, deactivate with PATCH setting state to 'deactivated' (immediately terminates all sessions), then call DELETE only after transferring owned bases - deactivation and deletion are separate, irreversible operations.
Bulk provisioning via SCIM with Okta: configure SSO first, create a PAT with enterprise. scim.
usersAndGroups:manage scope, point Okta's SCIM provisioning at https://airtable.com/scim/v2, and enable Push Users (and Push Groups on Enterprise Scale). Access auditing: paginate SCIM GET /Users for the full roster, then call GET /v0/meta/enterpriseAccounts/{entId}/users/{userId}?
include=collaborations per user for detailed membership data - note that collaborations are not returned by default and each user requires a separate request, which will consume rate limit budget quickly at scale.
The rate limit is 5 req/sec per base across all plans with no option to increase it; HTTP 429 responses should be retried after 30 seconds.
Offboard a departing employee via Enterprise API
- Look up the user's Airtable ID by email using GET /v0/meta/enterpriseAccounts/{entId}/users/{userId} (pass email as userId).
- Deactivate the user with PATCH /v0/meta/enterpriseAccounts/{entId}/users/{userId} body: {"state": "deactivated"} - this immediately terminates all sessions.
- Optionally unshare the user from all workspaces/bases using the unshare endpoint.
- If permanent deletion is required, transfer owned bases via Admin UI or API, then call DELETE /v0/meta/enterpriseAccounts/{entId}/users/{userId}.
Watch out for: Deactivation and deletion are separate operations. Deactivated users are not billed and can be reactivated; deleted users cannot. Always transfer owned bases before deletion to avoid data loss.
Provision users at scale via SCIM with Okta
- Ensure SSO (SAML) is configured for the organization's domain in the Airtable Admin Panel.
- In Airtable Developer Hub, create a PAT with the enterprise.scim.usersAndGroups:manage scope.
- In Okta, add the Airtable app from the Okta Integration Network and configure SCIM provisioning with base URL https://airtable.com/scim/v2 and the PAT as the Bearer token.
- Enable 'Push Users' and (on Enterprise Scale) 'Push Groups' in Okta.
- Assign users/groups to the Airtable app in Okta; Okta will POST to /scim/v2/Users to provision each user.
- To deprovision, unassign the user in Okta; Okta will PATCH active=false to deactivate the user in Airtable.
Watch out for: Group provisioning requires Enterprise Scale plan; Business plan must disable group mappings. Deactivation via SCIM is only reliable with Okta. Any existing provisioned users must be re-provisioned after initial SCIM setup to enable push features.
Audit user access across the enterprise
- Create a PAT with enterprise.user:read and enterprise.auditLog:read scopes.
- Use SCIM GET /scim/v2/Users with pagination (startIndex, count) to retrieve the full user roster with active status.
- For each user requiring detailed collaboration data, call GET /v0/meta/enterpriseAccounts/{entId}/users/{userId}?include=collaborations.
- Call the audit log endpoint GET /v0/meta/enterpriseAccounts/{entId}/auditLog to retrieve admin actions for the review period.
- Cross-reference user states and collaboration memberships to identify over-provisioned or inactive accounts.
Watch out for: There is no single endpoint to list all users with full collaboration details in one call. Fetching collaborations per user is a separate request and will consume rate limit budget quickly at scale; consider batching and caching results.
Why building this yourself is a trap
Several API behaviors create integration risk that is not obvious from the documentation. SCIM deactivation (active=false) is only reliably supported for Okta; Entra ID custom integrations have a known deactivation bug and require the Airtable Gallery App instead.
Seat type (Builder/Contributor/Viewer Restricted) cannot be set or read via SCIM or the Enterprise API - it is determined dynamically by the highest permission a user holds and must be managed in the admin panel.
There is no single endpoint to list all users with full collaboration details; fetching collaborations requires one request per user, making full-roster audits expensive against the 5 req/sec rate limit. Group SCIM endpoints are unavailable on Business plan, so any integration targeting group-based access control must be scoped to Enterprise Scale accounts only.
Finally, the enterprise.scim.usersAndGroups:manage PAT scope is itself only available on Enterprise Scale - Business plan tokens cannot include it, which limits what can be automated at that tier.
Automate Airtable 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.