Stitchflow
Miro logo

Miro User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 9, 2026

Summary and recommendation

Miro exposes two distinct API surfaces for identity and user management: a REST API (base URL `https://api.miro.com/v2`) using OAuth 2.0 or static access tokens, and a SCIM 2.0 API (`https://miro.com/scim/v2`) using a separate static bearer token.

These surfaces use different base URLs, different auth tokens, and different data models - they must not be mixed in the same request flow.

Org-level operations (listing members, updating roles, removing members) require `organizations:read` or `organizations:write` scopes and a caller with Company Admin privileges. Team-level operations require `organizations:teams:read` or `organizations:teams:write`. The `users:read` and `users:write` scopes are scoped to the authenticated user's own profile only and do not grant access to arbitrary user records.

For identity graph construction - mapping users across org membership, team assignments, and board-level roles - you must join data from `GET /v2/orgs/{org_id}/members`, `GET /v2/orgs/{org_id}/teams/{team_id}/members`, and SCIM `GET /Users`.

These three sources use different identifiers: the REST API uses a numeric `member_id`, SCIM uses its own `id`, and the `org_id` is a numeric string retrieved from `GET /v2/users/me` or the Miro admin UI.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 (authorization code flow) or static access token
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredEnterprise

Authentication

Auth method: OAuth 2.0 (authorization code flow) or static access token

Setup steps

  1. Go to https://miro.com/app/settings/user-profile/apps and create a new app
  2. Set the redirect URI for your application
  3. Select required OAuth 2.0 scopes for your app
  4. Use the authorization endpoint https://miro.com/oauth/authorize to obtain an authorization code
  5. Exchange the code for an access token at https://api.miro.com/v1/oauth/token
  6. Include the token in requests as: Authorization: Bearer
  7. For SCIM, generate a dedicated SCIM token from Company Settings > Security > SCIM (Enterprise only)

Required scopes

Scope Description Required for
organizations:read Read organization details and membership List organization members, get org info
organizations:teams:read Read teams within an organization List teams, get team members
organizations:teams:write Create, update, delete teams and manage team membership Add/remove team members, create teams
users:read Read the current user's profile Get current user info
users:write Update the current user's profile Update user profile fields
organizations:write Manage organization-level settings and members Update org member roles, remove members

User object / data model

Field Type Description On create On update Notes
id string Unique Miro user identifier system-generated immutable Used as path param in user endpoints
name string Full display name of the user set by user updatable
email string Primary email address required not updatable via API Email changes require user action
role string Organization role: company_admin, member, non_team_member, viewer assigned on invite updatable by admin Enum values vary by plan
type string Object type, always 'user' system-generated immutable
createdAt string (ISO 8601) Timestamp when the user joined the organization system-generated immutable
active boolean Whether the user account is active (SCIM field) defaults true updatable via SCIM Setting false deactivates the user
teamRole string Role within a specific team: admin, member, non_team_member set on team invite updatable Returned in team-member context only

Core endpoints

Get current user

  • Method: GET
  • URL: https://api.miro.com/v2/users/me
  • Watch out for: Returns only the authenticated user's own profile; cannot retrieve arbitrary users via REST without org-level scopes.

Request example

GET /v2/users/me
Authorization: Bearer <token>

Response example

{
  "id": "3458764517517852417",
  "name": "Jane Doe",
  "email": "jane@example.com",
  "type": "user"
}

Get organization members

  • Method: GET
  • URL: https://api.miro.com/v2/orgs/{org_id}/members
  • Watch out for: Requires organizations:read scope and the caller must be a Company Admin or have org-level access.

Request example

GET /v2/orgs/3458764517517852417/members?limit=10&cursor=
Authorization: Bearer <token>

Response example

{
  "data": [{"id":"...","name":"Jane","role":"member"}],
  "cursor": "next_cursor_value",
  "total": 120
}

Get organization member by ID

  • Method: GET
  • URL: https://api.miro.com/v2/orgs/{org_id}/members/{member_id}
  • Watch out for: org_id must be the numeric organization ID, not the org name or slug.

Request example

GET /v2/orgs/3458764517517852417/members/3458764517517852418
Authorization: Bearer <token>

Response example

{
  "id": "3458764517517852418",
  "name": "John Smith",
  "email": "john@example.com",
  "role": "member"
}

Update organization member role

  • Method: PATCH
  • URL: https://api.miro.com/v2/orgs/{org_id}/members/{member_id}
  • Watch out for: Only Company Admins can promote/demote roles. Role values are plan-dependent.

Request example

PATCH /v2/orgs/{org_id}/members/{member_id}
Content-Type: application/json

{"role": "company_admin"}

Response example

{
  "id": "3458764517517852418",
  "role": "company_admin"
}

Remove organization member

  • Method: DELETE
  • URL: https://api.miro.com/v2/orgs/{org_id}/members/{member_id}
  • Watch out for: Removing a member does not delete their Miro account; it only removes them from the organization.

Request example

DELETE /v2/orgs/{org_id}/members/{member_id}
Authorization: Bearer <token>

Response example

HTTP 204 No Content

Get team members

  • Method: GET
  • URL: https://api.miro.com/v2/orgs/{org_id}/teams/{team_id}/members
  • Watch out for: Requires organizations:teams:read scope.

Request example

GET /v2/orgs/{org_id}/teams/{team_id}/members?limit=10
Authorization: Bearer <token>

Response example

{
  "data": [{"id":"...","name":"Jane","teamRole":"admin"}],
  "cursor": "abc123"
}

Add team member

  • Method: POST
  • URL: https://api.miro.com/v2/orgs/{org_id}/teams/{team_id}/members
  • Watch out for: User must already be an org member before being added to a team.

Request example

POST /v2/orgs/{org_id}/teams/{team_id}/members
Content-Type: application/json

{"memberId": "3458764517517852418", "role": "member"}

Response example

{
  "id": "3458764517517852418",
  "teamRole": "member"
}

Remove team member

  • Method: DELETE
  • URL: https://api.miro.com/v2/orgs/{org_id}/teams/{team_id}/members/{member_id}
  • Watch out for: Removes user from team only; does not remove from organization.

Request example

DELETE /v2/orgs/{org_id}/teams/{team_id}/members/{member_id}
Authorization: Bearer <token>

Response example

HTTP 204 No Content

Rate limits, pagination, and events

  • Rate limits: Miro enforces per-app rate limits. The REST API allows up to 1000 requests per minute per app token. SCIM API has separate limits. Rate limit details are returned in response headers.
  • Rate-limit headers: Yes
  • Retry-After header: Yes
  • Rate-limit notes: Headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset are returned. On 429, use Retry-After header value.
  • Pagination method: cursor
  • Default page size: 10
  • Max page size: 100
  • Pagination pointer: cursor
Plan Limit Concurrent
All plans (REST API) 1000 requests/minute per app 0
Enterprise (SCIM) Not publicly specified; subject to standard enterprise limits 0
  • Webhooks available: Yes
  • Webhook notes: Miro supports webhooks for board-level events (item created, updated, deleted, etc.) but does not offer dedicated user-management or org-membership webhook events as of the current API version.
  • Alternative event strategy: Poll GET /v2/orgs/{org_id}/members on a schedule to detect membership changes. Use SCIM provisioning for real-time user lifecycle events triggered by your IdP.
  • Webhook events: board:created, board:updated, board:deleted, item:created, item:updated, item:deleted

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Enterprise

  • Endpoint: https://miro.com/scim/v2

  • Supported operations: GET /Users - list users, GET /Users/{id} - get user by ID, POST /Users - provision new user, PUT /Users/{id} - replace user attributes, PATCH /Users/{id} - update user attributes (including active=false to deactivate), DELETE /Users/{id} - deprovision user, GET /Groups - list teams/groups, POST /Groups - create group, PATCH /Groups/{id} - update group membership, DELETE /Groups/{id} - delete group

Limitations:

  • Requires Enterprise plan
  • SAML SSO must be configured before SCIM can be enabled
  • Only Company Admins can generate the SCIM token in Company Settings
  • SCIM token is a static bearer token, not an OAuth token
  • Deactivating a user via SCIM (active=false) suspends them but does not delete the account
  • IdP-initiated group pushes map to Miro Teams
  • Supported IdPs include Okta, Microsoft Entra ID (Azure AD), Google Workspace, and OneLogin

Common scenarios

Three primary automation scenarios are supported by the provided data.

Deprovision a leaver via SCIM: Locate the user with GET /scim/v2/Users?filter=userName eq "user@example.com", then send PATCH /scim/v2/Users/{id} with active=false. Use PATCH over DELETE - DELETE is irreversible and removes content ownership. SCIM is Enterprise-only; the token is generated from Company Settings > Security > SCIM.

Assign an existing org member to a team via REST: Confirm org membership with GET /v2/orgs/{org_id}/members/{member_id}, then POST /v2/orgs/{org_id}/teams/{team_id}/members with {"memberId": "<member_id>", "role": "member"}. The user must already be an org member - adding a non-member returns a 400 or 404.

Bulk member audit via cursor pagination: Call GET /v2/orgs/{org_id}/members?limit=100, extract the cursor field from each response, and repeat until no cursor is returned. Max page size is 100; pagination is cursor-based only - offset-based page numbers are not supported. At 1,000 requests/minute, large orgs will require backoff logic.

Deprovision a leaver via SCIM

  1. Ensure SAML SSO and SCIM are enabled in Miro Company Settings (Enterprise plan required)
  2. Obtain the SCIM bearer token from Company Settings > Security > SCIM
  3. Find the user's SCIM ID: GET https://miro.com/scim/v2/Users?filter=userName eq "user@example.com"
  4. Deactivate the user: PATCH https://miro.com/scim/v2/Users/{id} with body {"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"replace","path":"active","value":false}]}
  5. Verify the user is suspended in Miro Company Settings

Watch out for: Use PATCH active=false rather than DELETE to preserve board content and audit history. DELETE permanently removes the user.

Assign a user to a team via REST API

  1. Authenticate with OAuth 2.0 and obtain a token with organizations:teams:write scope
  2. Retrieve the org_id from GET /v2/users/me or Miro admin settings
  3. List teams to find the target team_id: GET /v2/orgs/{org_id}/teams
  4. Confirm the user is an org member: GET /v2/orgs/{org_id}/members/{member_id}
  5. Add the user to the team: POST /v2/orgs/{org_id}/teams/{team_id}/members with body {"memberId": "", "role": "member"}

Watch out for: The user must already be an organization member before they can be added to a team. Adding a non-member returns a 404 or 400 error.

Bulk-list all org members for an audit

  1. Authenticate with a token holding organizations:read scope
  2. Call GET /v2/orgs/{org_id}/members?limit=100
  3. Check the response for a 'cursor' field; if present, call GET /v2/orgs/{org_id}/members?limit=100&cursor={cursor}
  4. Repeat until no cursor is returned in the response
  5. Aggregate all member objects for the audit report

Watch out for: Max page size is 100. For large organizations, cursor pagination may require many sequential requests; respect rate limits (1000 req/min) and implement backoff.

Why building this yourself is a trap

The REST API does not support user invitation - POST /Users is a SCIM-only operation, and SCIM requires Enterprise. Any workflow that needs to provision net-new users via API is blocked below Enterprise tier, with no REST equivalent.

OAuth access tokens expire and require refresh token handling; the static SCIM token does not expire but is a separate credential that must be rotated independently. Conflating the two auth flows or reusing tokens across API surfaces will produce auth failures that are not immediately obvious from error messages.

Miro's webhook events cover board-level activity only (item created/updated/deleted, board created/updated/deleted). There are no webhook events for org membership changes, user deactivation, or team assignment.

Any identity graph that needs to stay current must poll GET /v2/orgs/{org_id}/members on a schedule or rely on IdP-side SCIM push events - there is no push-based notification path for user lifecycle changes via the REST API.

Automate Miro 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.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 9, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen