Skip to main content

Documentation Index

Fetch the complete documentation index at: https://auth0-feat-experiment-center.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Prerequisites

To get started with Experiment Center, you need:
  • An Auth0 development tenant
  • A Machine-to-Machine application with the following Management API scopes:
    read:experimentation
    create:experimentation
    update:experimentation
    delete:experimentation
    
  • Auth0 CLI authenticated to your development tenant:
    brew install auth0
    auth0 login --domain your-test-tenant.us.auth0.com
    
  • Access to Auth0 tenant logs
  • Auth0 Dashboard: Monitoring > Logs on your development tenant
  • Log streaming: if you already stream tenant logs to an analytics tool (Datadog, Splunk, Segment, etc.), enriched experiment metadata flows through the same stream automatically

Step 1: Create a feature flag

A feature flag defines what you are testing and the possible variations. Use POST with the /api/v2/experimentation/feature-flags endpoint:
curl -X POST \
  "https://YOUR_TENANT.us.auth0.com/api/v2/experimentation/feature-flags" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "passkey-prompt",
    "description": "Controls whether to show a passkey enrollment prompt after login",
    "parameters": {
      "show_passkey_prompt": {
        "type": "boolean",
        "value": false,
        "description": "Show passkey enrollment prompt"
      },
      "prompt_style": {
        "type": "string",
        "value": "inline",
        "description": "Display style for the prompt"
      }
    }
  }'
Sample response
{
  "feature_flag_id": "flg_72jbvv7LfRKYp59gtRLtkn",
  "name": "passkey-prompt",
  "description": "Controls whether to show a passkey enrollment prompt after login",
  "type": "self",
  "status": "draft",
  "parameters": {
    "show_passkey_prompt": {
      "type": "boolean",
      "value": false,
      "description": "Show passkey enrollment prompt"
    },
    "prompt_style": {
      "type": "string",
      "value": "inline",
      "description": "Display style for the prompt"
    }
  },
  "created_at": "2026-06-01T10:00:00.000Z",
  "updated_at": "2026-06-01T10:00:00.000Z"
}
Note the feature_flag_id (flg_...) in the response. You will use it in subsequent steps. The flag starts in draft status. CLI alternative:
auth0 experimentation feature-flags create \
  --name "passkey-prompt" \
  --parameter "show_passkey_prompt:boolean:false" \
  --parameter "prompt_style:string:inline"

Step 2: Add two variations

The feature flag needs at least two variations before it can activate: a control and a treatment.

Create the control variation

The control variation has empty overrides. It represents the unchanged baseline.
curl -X POST \
  "https://YOUR_TENANT.us.auth0.com/api/v2/experimentation/feature-flags/flg_72jbvv7LfRKYp59gtRLtkn/variations" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "control",
    "description": "No passkey prompt (baseline behavior)",
    "overrides": {}
  }'
Sample response
{
  "variation_id": "var_4Nq8mR2xPkTv6wYjHs3fBn",
  "feature_flag_id": "flg_72jbvv7LfRKYp59gtRLtkn",
  "name": "control",
  "description": "No passkey prompt (baseline behavior)",
  "overrides": {},
  "created_at": "2026-06-01T10:01:00.000Z",
  "updated_at": "2026-06-01T10:01:00.000Z"
}
Note the variation_id (var_...) for the control. You will need it when setting up allocations.

Create the treatment variation

The treatment variation overrides the parameters you want to change.
curl -X POST \
  "https://YOUR_TENANT.us.auth0.com/api/v2/experimentation/feature-flags/flg_72jbvv7LfRKYp59gtRLtkn/variations" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "treatment-passkey-prompt",
    "description": "Shows passkey enrollment prompt after login",
    "overrides": {
      "show_passkey_prompt": { "value": true },
      "prompt_style": { "value": "modal" }
    }
  }'
Sample response
{
  "variation_id": "var_8Xp2qK5nWmJy9vDsHr4gAt",
  "feature_flag_id": "flg_72jbvv7LfRKYp59gtRLtkn",
  "name": "treatment-passkey-prompt",
  "description": "Shows passkey enrollment prompt after login",
  "overrides": {
    "show_passkey_prompt": { "value": true },
    "prompt_style": { "value": "modal" }
  },
  "created_at": "2026-06-01T10:02:00.000Z",
  "updated_at": "2026-06-01T10:02:00.000Z"
}

Step 3: Activate the feature flag

Now that you have two variations, activate the feature flag. An experiment cannot activate unless its referenced feature flag is in active status.
curl -X POST \
  "https://YOUR_TENANT.us.auth0.com/api/v2/experimentation/feature-flags/flg_72jbvv7LfRKYp59gtRLtkn/status" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": "active" }'
Sample response
{
  "feature_flag_id": "flg_72jbvv7LfRKYp59gtRLtkn",
  "name": "passkey-prompt",
  "status": "active",
  ...
}
Auth0 CLI alternative:
auth0 experimentation feature-flags activate flg_72jbvv7LfRKYp59gtRLtkn

Step 4: (Optional) Create a segment

If you want to target specific traffic, create a segment. Skip this step if you want a simple percentage split across all traffic. This example creates a segment that matches mobile users in the United States:
curl -X POST \
  "https://YOUR_TENANT.us.auth0.com/api/v2/experimentation/segments" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "mobile-us-users",
    "description": "Mobile users from the United States",
    "rules": [
      {
        "match_type": "all",
        "conditions": [
          { "attribute": "device_type", "operator": "equals", "value": "mobile" },
          { "attribute": "country", "operator": "equals", "value": "US" }
        ]
      }
    ]
  }'
Note the segment_id (seg_...) in the response if you create one.

Step 5: Create an experiment

Create an experiment that references your feature flag and defines how to split traffic. This example uses a 90/10 percentage split: 90% of users get the control, 10% get the treatment. This is a typical cautious rollout starting point.
curl -X POST \
  "https://YOUR_TENANT.us.auth0.com/api/v2/experimentation/experiments" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "passkey-prompt-q2-2026",
    "description": "Testing passkey prompt enrollment impact on post-login flow",
    "feature_flag_id": "flg_72jbvv7LfRKYp59gtRLtkn",
    "authentication_flow": "pre_authentication",
    "allocation_strategy": "percentage",
    "assignment_config": {
      "subject": "device"
    },
    "allocations": [
      {
        "variation_id": "var_4Nq8mR2xPkTv6wYjHs3fBn",
        "weight": 90,
        "is_control": true
      },
      {
        "variation_id": "var_8Xp2qK5nWmJy9vDsHr4gAt",
        "weight": 10,
        "is_control": false
      }
    ]
  }'
Sample response
{
  "experiment_id": "exp_9Km3nZ7vQwRx2yDjFs5gCp",
  "name": "passkey-prompt-q2-2026",
  "feature_flag_id": "flg_72jbvv7LfRKYp59gtRLtkn",
  "authentication_flow": "pre_authentication",
  "allocation_strategy": "percentage",
  "status": "draft",
  "is_valid": false,
  "allocations": [
    {
      "variation_id": "var_4Nq8mR2xPkTv6wYjHs3fBn",
      "weight": 90,
      "is_control": true
    },
    {
      "variation_id": "var_8Xp2qK5nWmJy9vDsHr4gAt",
      "weight": 10,
      "is_control": false
    }
  ],
  "assignment_config": { "subject": "device" },
  "created_at": "2026-06-01T10:05:00.000Z",
  "updated_at": "2026-06-01T10:05:00.000Z"
}
The experiment starts in draft status with is_valid: false. This is expected; the full readiness check runs in the next step.

Step 6: Validate the experiment

Before activating, confirm the experiment is ready. The validate endpoint returns the same checks that run on activation.
curl -X POST \
  "https://YOUR_TENANT.us.auth0.com/api/v2/experimentation/experiments/exp_9Km3nZ7vQwRx2yDjFs5gCp/validate" \
  -H "Authorization: Bearer YOUR_TOKEN"
Sample response
{
  "is_valid": true,
  "errors": []
}
Response when not valid (200 OK, but with errors):
Sample response with errors
{
  "is_valid": false,
  "errors": [
    {
      "code": "feature_flag_not_active",
      "message": "Feature flag flg_72jbvv7LfRKYp59gtRLtkn is in draft status; must be active"
    }
  ]
}
If is_valid is false, fix the listed errors before proceeding. Common blockers are covered in the troubleshooting guide. Once is_valid: true, you are ready to activate. Before going live, test both variations using query parameter overrides. This lets you verify that your ACUL components, Actions, or page templates render correctly for each variation. Test the control variation:
https://YOUR_TENANT.us.auth0.com/authorize
  ?client_id=YOUR_CLIENT_ID
  &response_type=code
  &redirect_uri=https://YOUR_APP/callback
  &experiment_id=exp_9Km3nZ7vQwRx2yDjFs5gCp
  &variation_id=var_4Nq8mR2xPkTv6wYjHs3fBn
Test the treatment variation:
https://YOUR_TENANT.us.auth0.com/authorize
  ?client_id=YOUR_CLIENT_ID
  &response_type=code
  &redirect_uri=https://YOUR_APP/callback
  &experiment_id=exp_9Km3nZ7vQwRx2yDjFs5gCp
  &variation_id=var_8Xp2qK5nWmJy9vDsHr4gAt
Query parameter overrides work on experiments in draft status. You do not need to activate before testing.

Step 8: Activate the experiment

When the experiment is valid and you have tested both variations, activate it.
curl -X POST \
  "https://YOUR_TENANT.us.auth0.com/api/v2/experimentation/experiments/exp_9Km3nZ7vQwRx2yDjFs5gCp/status" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": "active" }'
Sample response
{
  "experiment_id": "exp_9Km3nZ7vQwRx2yDjFs5gCp",
  "name": "passkey-prompt-q2-2026",
  "status": "active",
  "is_valid": true,
  "started_at": "2026-06-01T10:10:00.000Z",
  ...
}
The experiment is now live. started_at is set on first activation and does not change if you pause and reactivate.
One active experiment per tenant. If another experiment is already active, activation returns 400 experiment_active_limit_exceeded. Pause or complete the other experiment first.
Auth0 CLI alternative:
auth0 experimentation experiments activate exp_9Km3nZ7vQwRx2yDjFs5gCp

Step 9: Trigger an auth event and observe results

Trigger a test login through your test tenant. For example, open a browser and navigate to your /authorize URL without any override parameters:
https://YOUR_TENANT.us.auth0.com/authorize
  ?client_id=YOUR_CLIENT_ID
  &response_type=code
  &redirect_uri=https://YOUR_APP/callback
  &scope=openid
Complete the login flow. The Experiment Center resolves the active experiment, assigns a variation using deterministic hashing, injects the experiment context, and enriches the resulting auth event.

Step 10: Verify enriched logs

Open your tenant logs (Auth0 Dashboard > Monitoring > Logs) and find the auth event for your test login. The event should include experiment metadata under an experiment field.
Sample response
{
  "type": "s",
  "date": "2026-06-01T10:12:00.000Z",
  "description": "Successful login",
  "connection": "Username-Password-Authentication",
  "user_id": "auth0|abc123",
  "experiment": {
    "experiment_id": "exp_9Km3nZ7vQwRx2yDjFs5gCp",
    "variation_id": "var_4Nq8mR2xPkTv6wYjHs3fBn",
    "segment_id": null
  }
}
The experiment field appears on every auth event where an experiment was active during the transaction. The variation_id tells you which variation this user was assigned to. If you do not see the experiment field, check the troubleshooting guide.
You have successfully run your first experiment when:
  1. Your auth events in tenant logs include the experiment field with experiment_id and variation_id
  2. Both variations produce the correct behavior when tested with query parameter overrides
  3. The same device or user consistently gets the same variation_id across multiple auth events (deterministic assignment)

Learn more