Skip to main content

Create Experiment

POST/v2/project/{project_key}/create-experiment

Create a new A/B experiment for a project. The experiment is created in draft status by default.

Required fields

FieldTypeDescription
test_namestringDisplay name for the experiment
urlstringThe page URL being tested
variantsarrayAt least two variant objects — one Control and at least one treatment (see Variants section)

Variants

Each variant in the variants array represents a treatment arm. The Control is always the first variant (the original page, shown unchanged). Every additional object is a treatment you want to test against the Control.

data is always required

Every variant object must include "data": []. For code-based experiments, pass an empty array. Only visual editor experiments populate the data array with DOM mutations.

Code-based experiments (most common via API)

Use customCSS and/or customJS to inject changes. Pass data as an empty array.

[
{
"name": "Control",
"data": []
},
{
"name": "Variant 1 — Red Button",
"customCSS": ".cta-button { background-color: #FF5733 !important; color: #fff !important; }",
"customJS": "document.querySelector('.cta').textContent = 'Get Started Free';",
"data": []
}
]

Visual DOM experiments

The data array holds DOM mutations produced by the Mida visual editor. Each entry replaces an element matched by a CSS selector with new HTML:

{
"name": "Variant 1",
"data": [
{
"target": "h1.hero-title",
"outerHTML": "<h1 class=\"hero-title\">New Headline Copy</h1>"
}
]
}

You can combine data mutations with customCSS/customJS in the same variant.

Goals

Pass primary_goal as an object to create the goal alongside the experiment. If a goal with the same goal_name and goal_type already exists for the project, it will be reused.

{
"primary_goal": {
"goal_name": "CTA Button Click",
"goal_type": "clickOnElement",
"goal_value": ".cta-button"
}
}

Reference an existing goal by key

{
"primary_goal_key": "my-existing-goal-key"
}

Goal types

goal_typeWhat it tracksgoal_value
clickOnElementClick on a CSS selector.buy-btn
clickOnTextClick on an element containing specific textAdd to cart
formSubmitForm submissionCSS selector of the <form>
pageviewURL path partial match/thank-you
pageviewExactExact URL matchhttps://example.com/thank-you
pageviewWildcardURL with * wildcards/products/*/confirm
pageviewRegexRegex URL pattern^/checkout/.+/success$
scriptCustom JS event — fires when your code calls the named eventEvent name string

Secondary goals

Pass secondary_goals as an array to track additional metrics alongside the primary goal:

{
"secondary_goals": [
{ "goal_name": "Newsletter Signup", "goal_type": "formSubmit", "goal_value": "#signup-form" },
{ "goal_name": "Pricing Page View", "goal_type": "pageview", "goal_value": "/pricing" }
]
}

Or reference existing goals by key array:

{ "secondary_goal_keys": ["signup-goal-key", "pricing-view-key"] }

Optional fields

Status

ValueBehaviour
9Draft — saved but not running (default)
1Live — starts traffic split immediately on creation
0Inactive — created in a deactivated state

Configuration

{
"configuration": {
"traffic_allocation": 100,
"confidence_interval": 95,
"start_test_date": "2026-04-01T00:00:00Z",
"end_test_date": "2026-04-30T23:59:59Z",
"completion_visitor": 1000,
"completion_conversion": 0,
"completion_after_period": 30,
"completion_stats_significant_flag": 1,
"is_autopilot": 0,
"is_mab": 0,
"bayesian": 0
}
}
FieldDefaultDescription
traffic_allocation100% of visitors included in the test (0–100)
confidence_interval95Statistical confidence threshold
start_test_datenullAuto-start date (ISO 8601)
end_test_datenullAuto-end date (ISO 8601)
completion_visitor0Stop when this many unique visitors reached (0 = disabled)
completion_conversion0Stop when this many conversions reached (0 = disabled)
completion_after_period0Stop after N days (0 = disabled)
completion_stats_significant_flag01 = auto-stop when statistical significance is reached
is_autopilot01 = enable autopilot (Mida auto-allocates traffic to the winning variant)
is_mab01 = enable Multi-Armed Bandit mode
bayesian01 = use Bayesian statistics instead of frequentist

Targeting

Restrict which visitors are included in the experiment. All rules are optional — omit any field to include all visitors of that type.

{
"targeting": {
"url_rules": [
{ "type": "contains", "value": "/pricing" },
{ "type": "exact", "value": "https://example.com/pricing" }
],
"device_rules": [
{ "type": "is", "value": "desktop" }
],
"country_rules": [
{ "type": "is", "value": "US" },
{ "type": "is", "value": "CA" }
]
}
}

url_rules — Filter by page URL:

typeBehaviour
containsURL contains the value string
exactURL exactly matches the value
starts_withURL starts with the value
regexURL matches the regex pattern

device_rules — Filter by device type. Supported value: "desktop", "mobile", "tablet".

country_rules — Filter by visitor country. Use ISO 3166-1 alpha-2 codes (e.g. "US", "GB", "DE").

Targeting after creation

After the experiment is created, you can update device, browser, and country targeting via the Update Experiment endpoint. URL-based targeting changes require recreating the experiment or using the dashboard.

Idempotency

Pass idempotency_key (or the x-idempotency-key header) to safely retry requests without creating duplicates. The same key returns the original response for 24 hours.

{ "idempotency_key": "deploy-2026-04-01-homepage-cta" }

Example

curl --request POST \
--url https://api-{region}.mida.so/v2/project/YOUR_PROJECT_KEY/create-experiment \
--header 'Authorization: Bearer YOUR_GENERATED_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"test_name": "Homepage CTA Button Color Test",
"status": 9,
"url": "https://example.com/",
"variants": [
{
"name": "Control",
"data": []
},
{
"name": "Variant 1 — Red Button",
"customCSS": ".cta-button { background-color: #FF5733 !important; color: #fff !important; }",
"customJS": "",
"data": []
}
],
"primary_goal": {
"goal_name": "CTA Button Click",
"goal_type": "clickOnElement",
"goal_value": ".cta-button"
},
"configuration": {
"traffic_allocation": 100,
"confidence_interval": 95
}
}'

Success response

{
"success": true,
"status": 9,
"test_id": 28222,
"company_id": 1001,
"goal_profile_id": 8936,
"secondary_goals_count": 0,
"warnings": []
}

Save the test_id — you will use it in every subsequent call for this experiment.

No goal provided?

If you omit primary_goal and primary_goal_key, the experiment is still created but warnings will include "No goal payload provided. Draft was created without a primary goal mapping." You can add a goal later via the Update Experiment endpoint.

Error responses

StatusMeaning
400Missing required field (test_name, url, or variants), invalid status value, or malformed request body
401Invalid or missing API key
403Plan limit reached — upgrade your plan to create more experiments
406Idempotency key conflict — a different experiment was already created with this key
500Server error
Next step

After creating your experiment, use Update Experiment Status to launch it (status: 1), or Get Experiment Details to verify the experiment was created correctly.