Auth0’s Management API is designed to let you manipulate your Auth0 tenant’s entities – users, applications, rules, connections, etc. – via HTTP requests. Think of it as the administrative control plane for your Auth0 setup, accessible from your own applications or scripts.

Here’s a quick look at creating a user with the Management API. We’ll use curl for this example, assuming you’ve already set up a Machine to Machine application in Auth0 and obtained an access token.

# Get your access token (replace with your actual values)
AUTH0_DOMAIN="YOUR_AUTH0_DOMAIN.auth0.com"
M2M_CLIENT_ID="YOUR_M2M_CLIENT_ID"
M2M_CLIENT_SECRET="YOUR_M2M_CLIENT_SECRET"

ACCESS_TOKEN=$(curl -s -X POST \
  "https://${AUTH0_DOMAIN}/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "'"${M2M_CLIENT_ID}"'",
    "client_secret": "'"${M2M_CLIENT_SECRET}"'",
    "audience": "https://'"${AUTH0_DOMAIN}"'/api/v2/",
    "grant_type": "client_credentials"
  }' | jq -r .access_token)

# Create a user
USER_EMAIL="testuser@example.com"
USER_PASSWORD="A_Very_Secure_Password_123!"

curl -s -X POST \
  "https://${AUTH0_DOMAIN}/api/v2/users" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "'"${USER_EMAIL}"'",
    "password": "'"${USER_PASSWORD}"'",
    "connection": "YOUR_AUTH0_CONNECTION_NAME",
    "email_verified": true
  }'

This curl command hits the /api/v2/users endpoint, sending a JSON payload with the user’s email, password, the connection to use (like Username-Password-Authentication), and whether their email is already verified. The Authorization header contains the access_token we obtained earlier, which grants our script permission to manage users. The connection field is crucial; it tells Auth0 where to store this user’s credentials. Without it, the user can’t log in.

The Management API allows you to manage virtually every aspect of your Auth0 tenant. You can create, read, update, and delete users (CRUD operations), manage applications, configure identity providers (connections), set up rules and hooks for custom logic, generate API tokens, and even retrieve analytics. It’s the backbone for any automation or custom integration involving user lifecycle management or tenant configuration. The API is RESTful, using standard HTTP methods (GET, POST, PATCH, DELETE) and returning JSON responses. Each entity (users, applications, etc.) has its own set of endpoints, typically under the /api/v2/ path.

Internally, when you make a request to create a user, the Management API validates your access token, checks your tenant’s permissions, and then interacts with Auth0’s core user directory service. If you specify email_verified: true and provide a password for a password-based connection, Auth0 creates the user record, hashes the password using a strong algorithm (like bcrypt), and stores it. If the user already exists with that email, the API will return a 409 Conflict error. The connection parameter is fundamental; it links the user to a specific authentication source, whether it’s Auth0’s own database, a social provider like Google, or an enterprise directory like Active Directory via SAML or WS-Fed.

When you’re dealing with user profiles, you often need to store custom data beyond just email and name. The Management API supports this through the user_metadata and app_metadata fields. user_metadata is intended for data that the user can update themselves (e.g., their preferred language, avatar URL), while app_metadata is for data that your application manages (e.g., subscription level, internal user ID). You can update these fields by sending a PATCH request to the specific user’s endpoint (/api/v2/users/{user_id}). For example, to add a custom field to user_metadata:

USER_ID="auth0|abcdef1234567890" # Replace with actual user ID
CUSTOMER_TIER="premium"

curl -s -X PATCH \
  "https://${AUTH0_DOMAIN}/api/v2/users/${USER_ID}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "user_metadata": {
      "customer_tier": "'"${CUSTOMER_TIER}"'"
    }
  }'

This operation directly modifies the user’s record in Auth0’s database. The user_metadata object is merged if it already exists, meaning you don’t have to resend existing metadata keys every time you update. This is extremely useful for personalizing user experiences or enabling role-based access control managed by your application.

The granularity of permissions you can grant to a Machine to Machine application is surprisingly fine-grained. You don’t just give it "all user management" access. Instead, you can select specific scopes, like read:users, create:users, update:users, delete:users, and even down to specific user metadata fields if you enable that feature. This means you can create an M2M application that only has the ability to create users, or one that can only read user profiles. This principle of least privilege is critical for security, ensuring that compromised credentials for an M2M application have a limited blast radius.

The next hurdle you’ll likely encounter is handling rate limits, especially if you’re performing bulk operations or experiencing high traffic.

Want structured learning?

Take the full Auth0 course →