Summary and recommendation
The Smartsheet REST API (base URL: https://api.smartsheet.com/2.0) supports OAuth 2.0 authorization code flow and personal Bearer tokens. User management operations require the ADMIN_USERS scope and a System Admin-level token; a token issued to a non-System-Admin account will return 403 on most /users endpoints.
User IDs are 64-bit integers - JavaScript and languages without native BigInt support must coerce these to strings to avoid precision loss during JSON parsing. The default rate limit is 300 requests per minute per access token, with HTTP 429 and a Retry-After header on breach; exponential backoff is recommended.
Pagination uses a 1-based page/pageSize model with a default page size of 100 and a maximum of 10,000. Integrating Smartsheet user data into an identity graph requires polling GET /users on a schedule, since the webhooks system is scoped to sheet-level events only and does not emit signals for account membership changes.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 (authorization code flow) or API Access Token (Bearer token) |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise |
Authentication
Auth method: OAuth 2.0 (authorization code flow) or API Access Token (Bearer token)
Setup steps
- Register a developer app at https://developers.smartsheet.com to obtain a client_id and client_secret.
- Direct users to https://app.smartsheet.com/b/authorize?response_type=code&client_id=CLIENT_ID&scope=SCOPES&state=STATE for OAuth 2.0 authorization code flow.
- Exchange the returned code for an access token via POST https://api.smartsheet.com/2.0/token with grant_type=authorization_code.
- Alternatively, generate a personal API Access Token in Smartsheet Account > Personal Settings > API Access for server-to-server use.
- Include the token in all requests as: Authorization: Bearer ACCESS_TOKEN
Required scopes
| Scope | Description | Required for |
|---|---|---|
| READ_USERS | Read user and group information within the org account | GET /users, GET /users/{userId}, GET /groups |
| ADMIN_USERS | Add, update, remove, and transfer users within the org account | POST /users, PUT /users/{userId}, DELETE /users/{userId} |
| ADMIN_GROUPS | Create, update, and delete groups and group membership | POST /groups, PUT /groups/{groupId}, DELETE /groups/{groupId} |
| READ_SHEETS | Read sheet data; sometimes needed when transferring sheet ownership on user removal | DELETE /users/{userId} with transferTo parameter |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | integer | Unique numeric user ID assigned by Smartsheet | system-assigned | immutable | Used as path parameter in user-specific endpoints |
| string | User's primary email address (login identifier) | required | not updatable via API | Must be unique within the org account | |
| firstName | string | User's first name | optional | updatable | |
| lastName | string | User's last name | optional | updatable | |
| admin | boolean | Whether the user has System Admin privileges in the account | optional (default false) | updatable | Only System Admins can set this field |
| licensedSheetCreator | boolean | Whether the user holds a paid sheet-creator license | required | updatable | Determines whether a paid seat is consumed |
| groupAdmin | boolean | Whether the user can create and manage groups | optional (default false) | updatable | |
| resourceViewer | boolean | Whether the user can view resource management data | optional (default false) | updatable | |
| status | string (enum) | Account status: ACTIVE, PENDING, DECLINED | system-assigned (PENDING until invite accepted) | read-only | PENDING means invite sent but not yet accepted |
| profileImage | object | Contains imageId, height, width for the user's profile image | not settable | not settable via API | |
| title | string | User's job title | optional | updatable | |
| department | string | User's department | optional | updatable | |
| company | string | User's company name | optional | updatable | |
| mobilePhone | string | User's mobile phone number | optional | updatable | |
| workPhone | string | User's work phone number | optional | updatable | |
| locale | string | User's locale/language preference (e.g., en_US) | optional | updatable | |
| timeZone | string | User's time zone (e.g., US/Pacific) | optional | updatable | |
| customWelcomeScreenViewed | string (datetime) | Timestamp when user last viewed the custom welcome screen | system-assigned | read-only |
Core endpoints
List all users in account
- Method: GET
- URL:
https://api.smartsheet.com/2.0/users - Watch out for: Returns only users within the caller's org account. Requires ADMIN_USERS scope or System Admin token.
Request example
GET /2.0/users?pageSize=100&page=1
Authorization: Bearer ACCESS_TOKEN
Response example
{
"pageNumber": 1,
"pageSize": 100,
"totalPages": 2,
"totalCount": 150,
"data": [
{"id": 123, "email": "user@example.com", "status": "ACTIVE"}
]
}
Get current user (me)
- Method: GET
- URL:
https://api.smartsheet.com/2.0/users/me - Watch out for: Returns the authenticated user's own profile; does not require ADMIN_USERS scope.
Request example
GET /2.0/users/me
Authorization: Bearer ACCESS_TOKEN
Response example
{
"id": 123,
"email": "admin@example.com",
"firstName": "Jane",
"lastName": "Doe",
"admin": true,
"licensedSheetCreator": true,
"status": "ACTIVE"
}
Get user by ID
- Method: GET
- URL:
https://api.smartsheet.com/2.0/users/{userId} - Watch out for: userId is a 64-bit integer; use string handling in languages with integer precision limits.
Request example
GET /2.0/users/4583173393803140
Authorization: Bearer ACCESS_TOKEN
Response example
{
"id": 4583173393803140,
"email": "user@example.com",
"firstName": "John",
"lastName": "Smith",
"status": "ACTIVE",
"licensedSheetCreator": true
}
Add user to account
- Method: POST
- URL:
https://api.smartsheet.com/2.0/users - Watch out for: User status is PENDING until the invite email is accepted. sendEmail=false suppresses the invite; user must be added via SSO/SCIM instead.
Request example
POST /2.0/users?sendEmail=true
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"email": "newuser@example.com",
"admin": false,
"licensedSheetCreator": true
}
Response example
{
"message": "SUCCESS",
"resultCode": 0,
"result": {
"id": 9876543210,
"email": "newuser@example.com",
"status": "PENDING"
}
}
Update user
- Method: PUT
- URL:
https://api.smartsheet.com/2.0/users/{userId} - Watch out for: Email address cannot be changed via this endpoint. Only System Admins can modify the admin flag.
Request example
PUT /2.0/users/9876543210
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"admin": true,
"licensedSheetCreator": true,
"firstName": "John"
}
Response example
{
"message": "SUCCESS",
"resultCode": 0,
"result": {
"id": 9876543210,
"admin": true,
"licensedSheetCreator": true
}
}
Remove user from account
- Method: DELETE
- URL:
https://api.smartsheet.com/2.0/users/{userId} - Watch out for: transferTo (userId) is required if the removed user owns sheets; otherwise those sheets are deleted. removeFromSharing=true removes the user from all shared items.
Request example
DELETE /2.0/users/9876543210?transferTo=111222333&removeFromSharing=true
Authorization: Bearer ACCESS_TOKEN
Response example
{
"message": "SUCCESS",
"resultCode": 0
}
List groups in account
- Method: GET
- URL:
https://api.smartsheet.com/2.0/groups - Watch out for: Requires ADMIN_GROUPS scope. Group membership details are returned in GET /groups/{groupId}.
Request example
GET /2.0/groups?pageSize=100&page=1
Authorization: Bearer ACCESS_TOKEN
Response example
{
"pageNumber": 1,
"totalCount": 5,
"data": [
{"id": 555, "name": "Engineering", "owner": "admin@example.com"}
]
}
Add members to group
- Method: POST
- URL:
https://api.smartsheet.com/2.0/groups/{groupId}/members - Watch out for: Users must already be members of the org account before being added to a group. Non-member emails will return an error.
Request example
POST /2.0/groups/555/members
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
[
{"email": "user1@example.com"},
{"email": "user2@example.com"}
]
Response example
{
"message": "SUCCESS",
"resultCode": 0,
"result": [
{"id": 101, "email": "user1@example.com"},
{"id": 102, "email": "user2@example.com"}
]
}
Rate limits, pagination, and events
- Rate limits: Smartsheet enforces per-account and per-user rate limits. Requests exceeding limits receive HTTP 429. The Retry-After header indicates when to retry.
- Rate-limit headers: Yes
- Retry-After header: Yes
- Rate-limit notes: HTTP 429 response includes a Retry-After header (seconds). Smartsheet recommends exponential backoff. Bulk operations (e.g., bulk add users) count as a single request.
- Pagination method: offset
- Default page size: 100
- Max page size: 10000
- Pagination pointer: page and pageSize (1-based page index)
| Plan | Limit | Concurrent |
|---|---|---|
| All plans (default) | 300 requests per minute per access token | 0 |
| Enterprise (elevated) | Higher limits available by contacting Smartsheet support; exact values not publicly documented | 0 |
- Webhooks available: No
- Webhook notes: Smartsheet webhooks are scoped to sheet-level events (row/column/cell changes) and do not fire on user provisioning, deprovisioning, or account membership changes.
- Alternative event strategy: Poll GET /users on a schedule to detect membership changes, or use SCIM provisioning callbacks via your IdP (Okta, Entra ID) for lifecycle events.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise
Endpoint: https://api.smartsheet.com/2.0/scim/v2
Supported operations: GET /Users (list users), GET /Users/{id} (get user), POST /Users (create/provision user), PUT /Users/{id} (replace user attributes), PATCH /Users/{id} (update user attributes, including deactivate), GET /Groups (list groups), GET /Groups/{id} (get group), POST /Groups (create group), PUT /Groups/{id} (replace group), PATCH /Groups/{id} (update group membership), DELETE /Groups/{id} (delete group)
Limitations:
- Requires Enterprise plan and SSO (SAML 2.0) to be configured before SCIM can be enabled.
- Supported IdPs with documented integration guides: Okta, Microsoft Entra ID (Azure AD). Other IdPs may work but are not officially documented.
- SCIM DELETE /Users is not supported; deprovisioning is done via PATCH with active=false.
- User email (userName) cannot be changed via SCIM after provisioning.
- SCIM token is a long-lived bearer token generated in the Smartsheet Admin Center; it does not expire automatically.
Common scenarios
Three lifecycle scenarios cover the primary automation surface. To provision a new licensed user, POST /users with licensedSheetCreator=true; the user status will be PENDING until the invite is accepted, though group membership via POST /groups/{groupId}/members can be written immediately.
To deprovision and transfer assets atomically, call DELETE /users/{userId}? transferTo={receivingUserId}&removeFromSharing=true - omitting transferTo permanently deletes all sheets owned by that user with no recovery path.
For bulk lifecycle management, SCIM 2. 0 is available at https://api.smartsheet.com/2.0/scim/v2 on Enterprise plans.
note that Smartsheet does not support SCIM DELETE /Users - deprovisioning must be sent as a PATCH with active=false, and the SCIM bearer token is generated separately in Admin Center and cannot be substituted with a standard OAuth token.
Provision a new licensed user and assign to a group
- POST /users with email, licensedSheetCreator=true, sendEmail=true to create the user (status will be PENDING).
- Poll GET /users/{userId} until status=ACTIVE (user has accepted invite), or proceed immediately if using SCIM/SSO where activation is automatic.
- POST /groups/{groupId}/members with the new user's email to add them to the appropriate group.
Watch out for: Group membership addition will succeed even while user status is PENDING, but the user won't have access until they accept the invite and status becomes ACTIVE.
Deprovision a user and transfer their assets
- GET /users to find the target user's numeric ID.
- Identify a receiving user ID (transferTo) who will inherit the departing user's sheets.
- DELETE /users/{userId}?transferTo={receivingUserId}&removeFromSharing=true to remove the user, transfer sheet ownership, and remove them from all shared items in one call.
Watch out for: If transferTo is omitted and the user owns sheets, those sheets are permanently deleted. There is no soft-delete or recycle bin for this operation.
Bulk-sync users via SCIM with Okta
- Confirm Enterprise plan is active and SAML SSO is configured in Smartsheet Admin Center.
- In Smartsheet Admin Center > Security > SCIM, generate a SCIM bearer token.
- In Okta, add the Smartsheet app from the OIN catalog and configure SCIM provisioning with base URL https://api.smartsheet.com/2.0/scim/v2 and the generated token.
- Enable Okta SCIM features: Push New Users, Push Profile Updates, Push Groups.
- Assign users/groups in Okta; Okta will POST /Users to Smartsheet for each assigned user.
Watch out for: SCIM DELETE is not supported by Smartsheet; configure Okta to send PATCH with active=false for deprovisioning instead of DELETE. Verify this in Okta's SCIM settings.
Why building this yourself is a trap
The most consequential API caveat is the hard-delete behavior on DELETE /users: without a transferTo parameter, owned sheet data is permanently destroyed - there is no soft-delete, no recycle bin, and no API-level undo.
A second structural gap is the absence of user-lifecycle webhooks; any system building a real-time identity graph against Smartsheet must poll GET /users and diff results, or rely on IdP-side SCIM callbacks from Okta or Entra ID.
The email field is immutable after user creation via the REST API - email changes must be made by the user in their own account settings, which breaks any automation that assumes email is a mutable identity attribute.
Finally, the SCIM token and the REST API token are distinct credentials with separate issuance paths; conflating them is a common integration error that produces authentication failures against SCIM endpoints.
Automate Smartsheet 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.