Summary and recommendation
SurveyMonkey exposes a REST API (base URL: https://api.surveymonkey.com/v3) authenticated via OAuth 2.0, plus a separate SCIM 2.0 endpoint (https://api.surveymonkey.com/scim/v2) on Enterprise.
The two surfaces use distinct auth mechanisms: REST uses OAuth Bearer tokens obtained via the standard authorization code flow;
SCIM uses a static bearer token generated in the Admin UI.
Critically, the REST API is user-context-bound - GET /users/me returns only the token owner, and there is no super-admin endpoint to enumerate arbitrary users without iterating team members via GET /v3/teams/{team_id}/members.
Rate limits are per-app per-day (500 req/day on free app tier;
5,000 on paid), with X-Ratelimit-App-Global-Day-Remaining headers present but no documented Retry-After on 429 responses.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise |
Authentication
Auth method: OAuth 2.0
Setup steps
- Register an application at https://developer.surveymonkey.com/apps/ to obtain a client_id and client_secret.
- Direct the user to the authorization URL: https://api.surveymonkey.com/oauth/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scopes}
- Exchange the returned authorization code for an access token via POST https://api.surveymonkey.com/oauth/token with grant_type=authorization_code.
- Include the access token in all API requests as a Bearer token in the Authorization header: Authorization: Bearer {access_token}.
- For server-side integrations, a long-lived access token can be generated directly in the app dashboard without the full OAuth redirect flow.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| users_read | Read access to the authenticated user's account details. | GET /users/me |
| teams_read | Read access to team members and team details. | GET /teams/{team_id}/members |
| teams_write | Write access to manage team membership. | POST /teams/{team_id}/members, DELETE /teams/{team_id}/members/{member_id} |
| surveys_read | Read access to surveys owned by or shared with the user. | Listing surveys for a user context |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Unique identifier for the user. | system-assigned | immutable | Returned as a string integer. |
| username | string | The user's SurveyMonkey username. | required | read-only via API | Typically the user's email address. |
| string | Primary email address of the user. | required | read-only via REST API; updatable via SCIM | Used for login and notifications. | |
| first_name | string | User's first name. | optional | updatable via SCIM | |
| last_name | string | User's last name. | optional | updatable via SCIM | |
| account_type | string | Plan type associated with the user (e.g., basic, advantage, premier, enterprise). | system-assigned | read-only | |
| date_created | string (ISO 8601) | Timestamp when the account was created. | system-assigned | immutable | |
| date_last_login | string (ISO 8601) | Timestamp of the user's last login. | system-assigned | system-managed | |
| language | string | Preferred language code for the user's interface. | optional | updatable | e.g., 'en', 'fr' |
| email_verified | boolean | Whether the user's email address has been verified. | system-assigned | read-only | |
| status | string | Account status (active, etc.). | system-assigned | manageable via SCIM deprovisioning | |
| type | string | Member role within a team (e.g., regular, admin). | set on team invite | updatable via team member endpoint | Returned in team member objects, not /users/me. |
Core endpoints
Get current authenticated user
- Method: GET
- URL:
https://api.surveymonkey.com/v3/users/me - Watch out for: Returns only the user associated with the access token. There is no admin endpoint to fetch arbitrary users by ID via the REST API.
Request example
GET /v3/users/me
Authorization: Bearer {access_token}
Response example
{
"id": "1234567",
"username": "jane@example.com",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"account_type": "enterprise"
}
List team members
- Method: GET
- URL:
https://api.surveymonkey.com/v3/teams/{team_id}/members - Watch out for: Requires teams_read scope. The team_id can be retrieved from GET /v3/teams.
Request example
GET /v3/teams/abc123/members?page=1&per_page=50
Authorization: Bearer {access_token}
Response example
{
"data": [
{"id": "111", "email": "a@example.com", "type": "regular"},
{"id": "222", "email": "b@example.com", "type": "admin"}
],
"per_page": 50,
"page": 1
}
Get team details
- Method: GET
- URL:
https://api.surveymonkey.com/v3/teams/{team_id} - Watch out for: A user can belong to only one team. The team_id for the authenticated user's team is returned in GET /v3/users/me under the 'team' key.
Request example
GET /v3/teams/abc123
Authorization: Bearer {access_token}
Response example
{
"id": "abc123",
"name": "Acme Corp",
"member_count": 42
}
Get a specific team member
- Method: GET
- URL:
https://api.surveymonkey.com/v3/teams/{team_id}/members/{member_id} - Watch out for: Requires teams_read scope.
Request example
GET /v3/teams/abc123/members/111
Authorization: Bearer {access_token}
Response example
{
"id": "111",
"email": "a@example.com",
"type": "regular",
"status": "active"
}
Invite/add a team member
- Method: POST
- URL:
https://api.surveymonkey.com/v3/teams/{team_id}/members - Watch out for: Requires teams_write scope. The invited user receives an email invitation; they are not immediately active. Seat limits apply based on the Enterprise plan.
Request example
POST /v3/teams/abc123/members
Authorization: Bearer {access_token}
Content-Type: application/json
{"email": "newuser@example.com", "type": "regular"}
Response example
{
"id": "333",
"email": "newuser@example.com",
"type": "regular",
"status": "pending"
}
Update a team member role
- Method: PATCH
- URL:
https://api.surveymonkey.com/v3/teams/{team_id}/members/{member_id} - Watch out for: Only the 'type' (role) field is updatable via this endpoint. Email and name changes require SCIM or direct account management.
Request example
PATCH /v3/teams/abc123/members/111
Authorization: Bearer {access_token}
Content-Type: application/json
{"type": "admin"}
Response example
{
"id": "111",
"email": "a@example.com",
"type": "admin"
}
Remove a team member
- Method: DELETE
- URL:
https://api.surveymonkey.com/v3/teams/{team_id}/members/{member_id} - Watch out for: Requires teams_write scope. Removing a member does not delete their SurveyMonkey account; it only removes them from the team. Survey ownership transfer may be required before removal.
Request example
DELETE /v3/teams/abc123/members/111
Authorization: Bearer {access_token}
Response example
HTTP 204 No Content
List workgroups (Enterprise)
- Method: GET
- URL:
https://api.surveymonkey.com/v3/workgroups - Watch out for: Workgroups are an Enterprise-only feature for organizing team members. Separate endpoints exist for workgroup membership management.
Request example
GET /v3/workgroups?page=1&per_page=50
Authorization: Bearer {access_token}
Response example
{
"data": [
{"id": "wg1", "name": "Marketing", "member_count": 10}
]
}
Rate limits, pagination, and events
- Rate limits: SurveyMonkey enforces per-app rate limits based on plan tier. Limits are applied per access token per day and per second (burst).
- Rate-limit headers: Yes
- Retry-After header: No
- Rate-limit notes: The API returns X-Ratelimit-App-Global-Day-Limit, X-Ratelimit-App-Global-Day-Remaining, and X-Ratelimit-App-Global-Day-Reset headers. A 429 status is returned when limits are exceeded. Retry-After header behavior is not explicitly documented.
- Pagination method: offset
- Default page size: 50
- Max page size: 1000
- Pagination pointer: page and per_page (e.g., ?page=1&per_page=50)
| Plan | Limit | Concurrent |
|---|---|---|
| Basic (free app) | 500 requests/day | 0 |
| Standard (paid app) | 5,000 requests/day | 0 |
| Platinum / Enterprise app | Higher limits available on request | 0 |
- Webhooks available: Yes
- Webhook notes: SurveyMonkey supports webhooks (called 'event callbacks') that send HTTP POST notifications to a configured URL when specified events occur.
- Alternative event strategy: Webhooks are survey/response-centric, not user-management-centric. For user provisioning events, SCIM with an IdP (Okta, Azure AD) is the recommended approach.
- Webhook events: response_completed, response_updated, response_disqualified, response_overquota, survey_created, survey_updated, survey_deleted, collector_created, collector_updated, collector_deleted
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise
Endpoint: https://api.surveymonkey.com/scim/v2
Supported operations: GET /Users – list provisioned users, GET /Users/{id} – get a specific user, POST /Users – provision a new user, PUT /Users/{id} – replace user attributes, PATCH /Users/{id} – update user attributes (including deactivation), DELETE /Users/{id} – deprovision a user, GET /Groups – list groups (workgroups), POST /Groups – create a group, PATCH /Groups/{id} – update group membership, DELETE /Groups/{id} – delete a group
Limitations:
- SCIM provisioning requires SAML SSO to be configured first on the Enterprise plan.
- Only one IdP can be connected per Enterprise team.
- Supported IdPs are Okta and Microsoft Azure AD (Entra ID); Google Workspace and OneLogin are not officially supported.
- SCIM bearer token is generated within the SurveyMonkey admin UI, not via OAuth.
- Deprovisioning via SCIM deactivates the user but may not immediately free a paid seat depending on billing cycle.
- Group (workgroup) sync support may vary by IdP connector version.
Common scenarios
Three integration patterns cover the primary lifecycle operations.
For automated provisioning on Enterprise, the SCIM flow requires SAML SSO to be fully configured before the SCIM bearer token can be activated;
Okta and Azure AD (Entra ID) are the only officially supported IdPs, and only one IdP can be active per team.
For REST-based team enumeration, the team_id must be extracted from GET /v3/users/me before calling GET /v3/teams/{team_id}/members
it is not a known constant and may require a separate GET /v3/teams call depending on API version.
Pagination uses 1-based page and per_page parameters (max 1,000 per page);
large teams require iterating until the response set is exhausted.
For offboarding, DELETE /v3/teams/{team_id}/members/{member_id} removes the user from the team but does not delete their SurveyMonkey account or transfer survey ownership automatically
both must be handled explicitly, with SCIM deactivation (PATCH /scim/v2/Users/{id} with active=false) preferred on Enterprise for full deprovisioning.
Provision a new Enterprise user via SCIM (Okta)
- Ensure SAML SSO is configured in SurveyMonkey Enterprise admin settings.
- In SurveyMonkey admin UI, navigate to Security > SCIM and generate a SCIM bearer token.
- In Okta, add the SurveyMonkey SCIM application and enter the SCIM base URL (https://api.surveymonkey.com/scim/v2) and bearer token.
- Assign the Okta user to the SurveyMonkey application; Okta sends POST /scim/v2/Users to SurveyMonkey.
- SurveyMonkey creates the user account and sends an activation email if the user is new.
- Verify the user appears in the SurveyMonkey team member list.
Watch out for: If SSO is not fully configured before enabling SCIM, provisioning will fail. Only one IdP can be active at a time.
List all team members and their roles via REST API
- Obtain an OAuth 2.0 access token with teams_read scope.
- Call GET /v3/users/me to retrieve the authenticated user's team ID from the response.
- Call GET /v3/teams/{team_id}/members?page=1&per_page=100 to retrieve the first page of members.
- Check the response for pagination metadata and iterate pages until all members are retrieved.
- Parse each member object for id, email, and type (role) fields.
Watch out for: Max per_page is 1000 but large teams may require multiple paginated requests. The team_id must be extracted from the user object, not passed as a known constant.
Deprovision a user when they leave the organization
- If using SCIM: Unassign the user from the SurveyMonkey app in the IdP (Okta/Entra); the IdP sends PATCH /scim/v2/Users/{id} with active=false or DELETE /scim/v2/Users/{id}.
- If using REST API only: Obtain an OAuth token with teams_write scope, then call DELETE /v3/teams/{team_id}/members/{member_id}.
- Before removal, consider transferring survey ownership: use the SurveyMonkey admin UI or API to reassign surveys to another team member.
- Confirm the user no longer appears in GET /v3/teams/{team_id}/members.
Watch out for: REST API DELETE removes the user from the team but does not delete their SurveyMonkey account. SCIM deactivation is the recommended method for full deprovisioning on Enterprise. Seat billing implications should be verified with the account CSM.
Why building this yourself is a trap
Building an identity graph across SaaS applications using SurveyMonkey's REST API alone introduces compounding constraints not obvious at integration design time. The user-context OAuth model means any pipeline enumerating team members must maintain a token scoped to an Admin account - token expiry or Admin offboarding can silently break provisioning.
The SCIM and REST layers are operationally independent: role updates via PATCH /v3/teams/{team_id}/members/{member_id} only modify the type field; email and name changes require SCIM or direct account management, creating a split-surface update model that complicates identity graph consistency.
Webhooks are survey- and response-centric with no user lifecycle event stream, so IdP-driven SCIM is the only supported push mechanism for provisioning events. There is no admin-scoped user lookup by arbitrary ID, no bulk user export endpoint, and workgroup management is isolated to Enterprise-only endpoints with IdP connector version dependencies.
Automate SurveyMonkey 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.