Summary and recommendation
Marketo exposes a dedicated User Management REST API at `https://{munchkin-id}.mktorest.com/userservice/management/v1`. Authentication uses OAuth 2.0 client credentials - tokens expire after 3,600 seconds and must be refreshed. The API supports listing users, inviting users, updating attributes, deleting users, and managing role/workspace assignments.
There is no SCIM endpoint exposed by Marketo itself, no webhook support for user lifecycle events, and no soft-delete - deletion via the API is immediate and permanent. This API is one of ~100 deep integrations Stitchflow maintains for automated user lifecycle management.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 Client Credentials (Bearer token) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | Enterprise (Adobe Admin Console required) |
Authentication
Auth method: OAuth 2.0 Client Credentials (Bearer token)
Setup steps
- Log in to Marketo Admin → LaunchPoint → New Service, select 'Custom' type.
- Create or select an API-Only user and assign it to the service.
- Note the Client ID and Client Secret from the service detail.
- POST to https://{munchkin-id}.mktorest.com/identity/oauth/token?grant_type=client_credentials&client_id={id}&client_secret={secret} to obtain an access_token.
- Pass the token as Authorization: Bearer {access_token} on all subsequent requests.
- Tokens expire after 3600 seconds; re-request before expiry.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| Access API | Base permission required for any REST API call. | All endpoints |
| User Management | Grants access to User Management API endpoints (invite, update, delete users, manage roles/workspaces). | All /userservice/management/v1 endpoints |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| userid | string | Unique user identifier (email address used as login). | required | required (as path/query param) | Acts as the primary key. |
| firstName | string | User's first name. | required | optional | |
| lastName | string | User's last name. | required | optional | |
| emailAddress | string | User's email address. | required | optional | Must be unique within the subscription. |
| apiOnly | boolean | Whether the user is an API-only user (no UI login). | optional | read-only after creation | API-only users cannot be invited via the invite endpoint. |
| expiresAt | datetime (ISO 8601) | Account expiration date. | optional | optional | Null means no expiration. |
| reason | string | Reason provided when deleting or updating a user. | n/a | optional | Used in delete requests. |
| roles | array of objects | List of role assignments for the user. | optional (set via invite) | via separate roles endpoint | Each object contains roleId and workspaceId. |
| roleId | integer | Numeric ID of the role. | optional | optional | Obtained from GET /userservice/management/v1/users/roles.json |
| workspaceId | integer | Numeric ID of the workspace the role applies to. | optional | optional | Obtained from GET /userservice/management/v1/users/workspaces.json |
| id | integer | Internal numeric user ID assigned by Marketo. | system-assigned | read-only | Returned in GET responses. |
| createdAt | datetime (ISO 8601) | Timestamp when the user was created. | system-assigned | read-only | |
| updatedAt | datetime (ISO 8601) | Timestamp of last update. | system-assigned | read-only |
Core endpoints
List Users
- Method: GET
- URL:
https://{munchkin-id}.mktorest.com/userservice/management/v1/users/allusers.json - Watch out for: pageOffset is integer-based here (not a cursor token). Max pageSize is 200.
Request example
GET /userservice/management/v1/users/allusers.json?pageSize=50&pageOffset=0
Authorization: Bearer {token}
Response example
{"success":true,"result":[{"id":1,"userid":"user@example.com","firstName":"Jane","lastName":"Doe","emailAddress":"user@example.com","apiOnly":false}]}
Get User by ID
- Method: GET
- URL:
https://{munchkin-id}.mktorest.com/userservice/management/v1/users/{userid}/user.json - Watch out for: The {userid} path parameter is the email address and must be URL-encoded.
Request example
GET /userservice/management/v1/users/user%40example.com/user.json
Authorization: Bearer {token}
Response example
{"success":true,"result":[{"id":1,"userid":"user@example.com","firstName":"Jane","lastName":"Doe","apiOnly":false,"expiresAt":null}]}
Invite User
- Method: POST
- URL:
https://{munchkin-id}.mktorest.com/userservice/management/v1/users/invite.json - Watch out for: Sends an invitation email to the user. Cannot be used for API-only users. User must accept the invite before the account is active.
Request example
POST /userservice/management/v1/users/invite.json
Authorization: Bearer {token}
Content-Type: application/json
{"emailAddress":"new@example.com","firstName":"New","lastName":"User","expiresAt":null}
Response example
{"success":true,"result":[{"id":42,"userid":"new@example.com"}]}
Update User Attributes
- Method: POST
- URL:
https://{munchkin-id}.mktorest.com/userservice/management/v1/users/{userid}/update.json - Watch out for: Email address (userid) cannot be changed via this endpoint.
Request example
POST /userservice/management/v1/users/user%40example.com/update.json
Authorization: Bearer {token}
Content-Type: application/json
{"firstName":"Updated","lastName":"Name","expiresAt":"2025-12-31T00:00:00Z"}
Response example
{"success":true,"result":[{"id":1,"userid":"user@example.com","firstName":"Updated","lastName":"Name"}]}
Delete User
- Method: POST
- URL:
https://{munchkin-id}.mktorest.com/userservice/management/v1/users/{userid}/delete.json - Watch out for: Deletion is immediate and irreversible. API-only users can also be deleted via this endpoint.
Request example
POST /userservice/management/v1/users/user%40example.com/delete.json
Authorization: Bearer {token}
Content-Type: application/json
{"reason":"Offboarding"}
Response example
{"success":true,"result":[{"id":1,"userid":"user@example.com"}]}
Get Roles
- Method: GET
- URL:
https://{munchkin-id}.mktorest.com/userservice/management/v1/users/roles.json - Watch out for: Returns all roles defined in the subscription. roleId values are needed when assigning roles to users.
Request example
GET /userservice/management/v1/users/roles.json
Authorization: Bearer {token}
Response example
{"success":true,"result":[{"id":1,"name":"Admin"},{"id":2,"name":"Standard User"}]}
Add Roles to User
- Method: POST
- URL:
https://{munchkin-id}.mktorest.com/userservice/management/v1/users/{userid}/roles/create.json - Watch out for: Roles are workspace-scoped. You must supply a valid workspaceId even for single-workspace subscriptions.
Request example
POST /userservice/management/v1/users/user%40example.com/roles/create.json
Authorization: Bearer {token}
Content-Type: application/json
{"roles":[{"roleId":2,"workspaceId":1}]}
Response example
{"success":true,"result":[{"roleId":2,"workspaceId":1}]}
Delete Roles from User
- Method: POST
- URL:
https://{munchkin-id}.mktorest.com/userservice/management/v1/users/{userid}/roles/delete.json - Watch out for: Removing all roles from a user does not delete the user account; the user still exists but has no permissions.
Request example
POST /userservice/management/v1/users/user%40example.com/roles/delete.json
Authorization: Bearer {token}
Content-Type: application/json
{"roles":[{"roleId":2,"workspaceId":1}]}
Response example
{"success":true,"result":[{"roleId":2,"workspaceId":1}]}
Rate limits, pagination, and events
- Rate limits: Marketo enforces a daily API call quota and a concurrent request limit per subscription. The User Management API shares the same quota as the core REST API.
- Rate-limit headers: Yes
- Retry-After header: No
- Rate-limit notes: HTTP 429 is returned when the daily quota is exceeded. The response body error code 606 indicates max rate limit hit; 615 indicates concurrent request limit. Headers X-RateLimit-Limit and X-RateLimit-Remaining are present on responses.
- Pagination method: token
- Default page size: 20
- Max page size: 200
- Pagination pointer: pageToken / nextPageToken
| Plan | Limit | Concurrent |
|---|---|---|
| Standard (all plans) | 50,000 API calls per day (default); can be increased by contract | 10 |
- Webhooks available: No
- Webhook notes: Marketo does not offer native outbound webhooks for user-management events (user created, deleted, role changed). Marketo Webhooks exist only for lead/activity data triggers within Smart Campaigns, not for admin/user lifecycle events.
- Alternative event strategy: Poll the User Management API on a schedule to detect changes. For lead/activity events, Marketo supports Webhooks and also provides a Bulk Extract (REST) and a Streaming API (via Adobe I/O Events for some event types).
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Enterprise (Adobe Admin Console required)
- Endpoint: Not documented
Limitations:
- No native SCIM endpoint exposed by Marketo itself.
- User provisioning via SCIM is only available through Adobe Admin Console (Adobe IMS) using Azure AD or Google Workspace as the IdP.
- Okta SCIM provisioning to Marketo is not supported.
- OneLogin SCIM provisioning to Marketo is not supported.
- Permissions and workspace/role assignments are still managed manually within Marketo after provisioning.
- No JIT (Just-in-Time) provisioning support.
- Requires Marketo subscription to be migrated to Adobe Identity (Adobe IMS); legacy Marketo Identity subscriptions do not support SCIM at all.
Common scenarios
Provision a new user with a role: Fetch available roleId and workspaceId values first, then POST to /users/invite. json.
Role assignment via /roles/create. json should only happen after the user accepts the invitation - assigning roles to a pending invite may not persist.
Build a polling check against /users/{userid}/user. json to confirm active status before assigning roles.
Offboard a departing employee: DELETE is a two-step process - remove roles via /roles/delete.json, then permanently delete via /delete.json. If the instance uses Adobe IMS, the Adobe Admin Console must be updated separately; the two systems do not auto-sync.
Audit users and role assignments: Page through /allusers.json with pageSize=200 using integer pageOffset. Per-user role lookups against /users/{userid}/roles.json are required for full detail - cache the roles and workspaces reference data first to avoid burning daily quota on repeated lookups.
Provision a new marketing user with a specific role
- Obtain an OAuth 2.0 access token via POST to /identity/oauth/token.
- GET /userservice/management/v1/users/roles.json to retrieve available roleIds.
- GET /userservice/management/v1/users/workspaces.json to retrieve workspaceIds.
- POST /userservice/management/v1/users/invite.json with emailAddress, firstName, lastName.
- Wait for user to accept the invitation (account becomes active).
- POST /userservice/management/v1/users/{userid}/roles/create.json with the desired roleId and workspaceId.
Watch out for: Role assignment before invitation acceptance may not persist. Build a polling check or delay role assignment until the user status is confirmed active.
Offboard a departing employee
- Obtain an OAuth 2.0 access token.
- GET /userservice/management/v1/users/{userid}/user.json to confirm the user exists and retrieve their current roles.
- POST /userservice/management/v1/users/{userid}/roles/delete.json to remove all role assignments.
- POST /userservice/management/v1/users/{userid}/delete.json with a reason string to permanently delete the account.
Watch out for: Deletion is irreversible. If the subscription uses Adobe IMS, also deprovision the user from Adobe Admin Console separately, as the two systems are not automatically synchronized.
Audit all users and their role assignments
- Obtain an OAuth 2.0 access token.
- GET /userservice/management/v1/users/allusers.json with pageSize=200 and iterate pageOffset until result array is empty.
- For each user, GET /userservice/management/v1/users/{userid}/roles.json to retrieve their current role/workspace assignments.
- Cross-reference roleIds with GET /userservice/management/v1/users/roles.json and workspaceIds with GET /userservice/management/v1/users/workspaces.json.
- Compile the full user-role-workspace matrix for audit output.
Watch out for: With large user bases, iterating per-user role lookups can quickly consume daily API quota. Batch and cache role/workspace reference data to minimize calls.
Why building this yourself is a trap
The User Management API sits on a separate base URL from the core Marketo REST API - mixing them breaks auth silently. The {userid} path parameter is the user's email address and must be URL-encoded on every request.
The daily API quota (default 50,000 calls) is shared across all REST usage in the subscription, not scoped to user management alone - a busy marketing automation workload can exhaust quota before your provisioning jobs run. There are no webhooks for user lifecycle events, so detecting changes requires scheduled polling.
Instances migrated to Adobe IMS may have reduced API functionality and require parallel management in Adobe Admin Console, which has no REST API parity with the Marketo User Management API. Handling invite-acceptance state, quota sharing, IMS split-management, and permanent-deletion risk correctly requires ongoing maintenance that compounds quickly across a multi-app environment.
Automate Marketo 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.