Stitchflow
Medusa logo

Medusa User Management API Guide

API workflow

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

UpdatedMar 11, 2026

Summary and recommendation

Medusa's Admin REST API exposes full CRUD for admin users under /admin/users, with authentication via Bearer JWT obtained from POST /auth/user/emailpass. A critical v2 caveat: user record creation (POST /admin/users) and auth identity creation (POST /auth/user/emailpass/register) are decoupled-a user record without a linked auth identity cannot log in.

Admin users and storefront customers are entirely separate entities; /admin/users returns only dashboard admins, while /admin/customers holds storefront customer records. Pagination uses offset/limit with a default page size of 20; no documented maximum page size exists in the open-source core.

API quick reference

Has user APIYes
Auth methodBearer JWT token (session cookie also supported); API key authentication available for server-to-server calls
Base URLOfficial docs
SCIM availableNo

Authentication

Auth method: Bearer JWT token (session cookie also supported); API key authentication available for server-to-server calls

Setup steps

  1. POST /auth/user/emailpass with email and password to obtain a JWT token
  2. Include the token as Authorization: Bearer header on subsequent requests
  3. Alternatively, use publishable API keys for storefront calls or secret API keys for admin server-to-server calls configured in Medusa dashboard or via environment variable MEDUSA_ADMIN_API_KEY

User object / data model

Field Type Description On create On update Notes
id string Unique user identifier (prefixed 'user_') auto-generated immutable
email string User's email address required optional Must be unique across admin users
first_name string|null User's first name optional optional
last_name string|null User's last name optional optional
avatar_url string|null URL to user avatar image optional optional
metadata object|null Arbitrary key-value pairs for custom data optional optional
created_at datetime ISO 8601 timestamp of creation auto-generated immutable
updated_at datetime ISO 8601 timestamp of last update auto-generated auto-updated
deleted_at datetime|null Soft-delete timestamp null set on delete Medusa uses soft deletes

Core endpoints

List Users

  • Method: GET
  • URL: /admin/users
  • Watch out for: Returns only admin (dashboard) users, not storefront customers. Customer records live under /admin/customers.

Request example

GET /admin/users?limit=20&offset=0
Authorization: Bearer <token>

Response example

{
  "users": [{"id":"user_01","email":"admin@example.com","first_name":"Jane"}],
  "count": 1,
  "offset": 0,
  "limit": 20
}

Get User

  • Method: GET
  • URL: /admin/users/{id}

Request example

GET /admin/users/user_01
Authorization: Bearer <token>

Response example

{
  "user": {
    "id": "user_01",
    "email": "admin@example.com",
    "first_name": "Jane",
    "last_name": "Doe"
  }
}

Create User

  • Method: POST
  • URL: /admin/users
  • Watch out for: In Medusa v2, creating a user via this endpoint does not automatically create auth credentials. A separate auth identity must be registered via the Auth module (POST /auth/user/emailpass/register) to allow login.

Request example

POST /admin/users
Authorization: Bearer <token>
{
  "email": "newuser@example.com",
  "first_name": "John",
  "last_name": "Smith"
}

Response example

{
  "user": {
    "id": "user_02",
    "email": "newuser@example.com",
    "first_name": "John"
  }
}

Update User

  • Method: POST
  • URL: /admin/users/{id}
  • Watch out for: Medusa v2 Admin API uses POST (not PATCH) for updates on some resource types. Verify against the versioned API reference for your Medusa version.

Request example

POST /admin/users/user_02
Authorization: Bearer <token>
{
  "first_name": "Jonathan",
  "metadata": {"department": "ops"}
}

Response example

{
  "user": {
    "id": "user_02",
    "first_name": "Jonathan",
    "metadata": {"department": "ops"}
  }
}

Delete User

  • Method: DELETE
  • URL: /admin/users/{id}
  • Watch out for: Soft-delete only; deleted_at is set. Auth identities linked to the user are not automatically removed.

Request example

DELETE /admin/users/user_02
Authorization: Bearer <token>

Response example

{
  "id": "user_02",
  "object": "user",
  "deleted": true
}

Get Logged-in User (Me)

  • Method: GET
  • URL: /admin/users/me

Request example

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

Response example

{
  "user": {
    "id": "user_01",
    "email": "admin@example.com"
  }
}

Authenticate (Login)

  • Method: POST
  • URL: /auth/user/emailpass
  • Watch out for: This endpoint is on the /auth prefix, not /admin. The returned JWT must be passed as Bearer token to all admin endpoints.

Request example

POST /auth/user/emailpass
{
  "email": "admin@example.com",
  "password": "supersecret"
}

Response example

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Invite User

  • Method: POST
  • URL: /admin/invites
  • Watch out for: Invite tokens expire. The invitee must POST /admin/invites/accept with the token and their credentials to complete registration.

Request example

POST /admin/invites
Authorization: Bearer <token>
{
  "email": "invite@example.com"
}

Response example

{
  "invite": {
    "id": "invite_01",
    "email": "invite@example.com",
    "token": "abc123...",
    "accepted": false
  }
}

Rate limits, pagination, and events

  • Rate limits: No built-in rate limiting in the open-source Medusa core. Rate limiting must be implemented at the infrastructure layer (e.g., reverse proxy, API gateway). Medusa Cloud tiers may impose limits not publicly documented.

  • Rate-limit headers: No

  • Retry-After header: No

  • Rate-limit notes: Self-hosted deployments have no default rate limits. Implement via middleware or reverse proxy (nginx, Cloudflare, etc.).

  • Pagination method: offset

  • Default page size: 20

  • Max page size: Not documented

  • Pagination pointer: offset / limit

  • Webhooks available: Yes

  • Webhook notes: Medusa v2 supports subscribing to events via its event bus module. Webhooks to external URLs are not natively built-in but can be implemented using the Notification Module or custom subscribers.

  • Alternative event strategy: Use Medusa's Subscriber pattern in custom modules to react to user events programmatically, or integrate a notification provider (e.g., SendGrid plugin) to trigger external calls.

  • Webhook events: user.created, user.updated, user.deleted, invite.created, invite.accepted, invite.resent

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: Not documented
  • Endpoint: Not documented

Limitations:

  • No native SCIM 2.0 support in Medusa core or Medusa Cloud as of 2025
  • SSO is not natively supported; requires custom Auth Module provider implementation
  • SCIM provisioning would require a fully custom implementation using Medusa's User Module service and Auth Module

Common scenarios

Three scenarios cover the primary provisioning lifecycle.

First, programmatic admin provisioning requires two sequential calls: register auth credentials via the Auth Module, then create the user record, then explicitly link the auth identity if auto-linking does not occur-skipping any step produces a user who exists in the identity graph but cannot authenticate.

Second, the invite flow (POST /admin/invites) generates a token that must be delivered out-of-band; Medusa does not send email natively, so teams must attach a subscriber on the invite. created event or use a notification plugin.

Third, offboarding via DELETE /admin/users/{id} is a soft delete only-deleted_at is set but the auth identity remains active and existing JWTs are not invalidated, so token revocation or short expiry windows must be enforced separately at the infrastructure layer to guarantee immediate access termination.

Provision a new admin user programmatically

  1. POST /auth/user/emailpass/register with {email, password} to create auth credentials
  2. POST /admin/users with {email, first_name, last_name} to create the user record
  3. Link the auth identity to the user record using the Auth Module's linkIdentities workflow if not auto-linked
  4. Verify by GET /admin/users/{id}

Watch out for: Auth identity and user record creation are separate steps in v2. Skipping the auth registration means the user cannot log in even though a user record exists.

Invite an external user to the admin dashboard

  1. POST /admin/invites with {email} to generate an invite token
  2. Deliver the token to the invitee (Medusa does not send email natively; use a notification plugin or custom subscriber on invite.created event)
  3. Invitee POSTs /admin/invites/accept with {token, first_name, last_name, password} to complete registration
  4. Verify user appears in GET /admin/users

Watch out for: Invite tokens expire. If the invitee does not accept in time, POST /admin/invites/{id}/resent to issue a new token.

Soft-delete and clean up a departed admin user

  1. DELETE /admin/users/{id} to soft-delete the user record (sets deleted_at)
  2. Optionally remove the associated auth identity via the Auth Module service (deleteAuthIdentity) to prevent any residual login capability
  3. Confirm deletion by attempting GET /admin/users/{id} - should return 404 or empty

Watch out for: Soft-delete alone does not invalidate existing JWT tokens. Implement token revocation or short JWT expiry windows to ensure immediate access termination.

Why building this yourself is a trap

The most dangerous assumption when automating Medusa user management is treating the identity graph as a single object. In v2, a user record, an auth identity, and any linked session tokens are three distinct entities that must each be managed independently-create, update, and delete operations on /admin/users do not cascade to the Auth Module.

There is no native SCIM 2.0 support and no native SSO; any identity provider integration requires a fully custom Auth Module provider implementation. The open-source core has no built-in rate limiting, so automated provisioning scripts running against self-hosted instances must implement their own throttling at the reverse proxy or API gateway layer.

Medusa Cloud API behavior and any cloud-specific rate limits are not fully publicly documented, adding an additional caveat for teams building against hosted deployments.

Automate Medusa 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 11, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

Abnormal Security logo

Abnormal Security

API Only
AutomationAPI only
Last updatedMar 2026

Abnormal Security is an enterprise email security platform focused on detecting and investigating threats such as phishing, account takeover (ATO), and vendor email compromise. It does not support SCIM provisioning, which means every app in your stack

ActiveCampaign logo

ActiveCampaign

API Only
AutomationAPI only
Last updatedFeb 2026

ActiveCampaign uses a group-based permission model: every user belongs to exactly one group, and all feature-area access (Contacts, Campaigns, Automations, Deals, Reports, Templates) is configured at the group level, not per individual. The default Adm

ADP logo

ADP

API Only
AutomationAPI only
Last updatedFeb 2026

ADP Workforce Now is a mid-market to enterprise HCM platform that serves as the HR source of record for employee data — payroll, benefits, time, and talent. User access is governed by a hybrid permission model: predefined security roles (Security Maste