Generated OpenAPI reference
API for managing A/B testing experiments, variations, goals, webhooks, and screenshots.
Assignments
Get deterministic server-side assignments
/assign
Parameters
shop_idin query requireduser_idin query requiredurlin queryenvironmentin queryexperimentsin query
Responses
200Assignments and program cohort returned400Invalid request, including a customer identifier supplied in the query string instead of a POST body.401429503
curl \
https://app.drip-apex.com/api/v1/assign \
-H "Authorization: Bearer <apex-secret-key>"Get deterministic assignments with commerce proof inputs
/assign
Request body
{
shop_id: string
user_id?: string
logged_in_customer_id?: string
customer_id?: string
decision_use?: "aggregate" | "individual"
url?: string (uri)
environment?: string
experiments?: string[]
cart_token?: string
persist_function_handoff?: boolean
exclusion_group_selections?: object[]
}Responses
200Assignments, program cohort, and commerce authorization returned400401403A logged-in customer assignment was requested for an individual-level decision.429503
curl -X POST \
https://app.drip-apex.com/api/v1/assign \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"shop_id": "example_shop_id"
}'Runtime
Verify a signed cross-domain bucketing handover token
/handover/verify
Worker runtime endpoint. Verifies the token signature, expiry, and shop binding without requiring ingest credentials.
Parameters
X-Drip-Shopin header required
Request body
{
verifyToken: string
}Responses
200Verified handover payload400Missing or invalid shop identifier401Unsigned, forged, expired, or cross-shop handover token500Handover verification is unavailable
curl -X POST \
https://app.drip-apex.com/api/v1/handover/verify \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"verifyToken": "example_verifyToken"
}'Analytics
Show dashboard analytics stats
/analytics/stats
Parameters
daysin queryshop_currencyin query
Responses
200Analytics data400401403422429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/stats \
-H "Authorization: Bearer <apex-secret-key>"Show analytics timeseries
/analytics/timeseries
Parameters
daysin query
Responses
200Analytics data401403422429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/timeseries \
-H "Authorization: Bearer <apex-secret-key>"Show traffic sources
/analytics/traffic
Parameters
daysin query
Responses
200Analytics data401403429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/traffic \
-H "Authorization: Bearer <apex-secret-key>"Show page analytics
/analytics/pages
Parameters
daysin queryplanningDaysin query - Planning window in days (planning_days is also accepted)limitin query
Responses
200Analytics data401403429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/pages \
-H "Authorization: Bearer <apex-secret-key>"Show daily visitor series
/analytics/visitor-series
Parameters
daysin query
Responses
200Daily visitors and pageviews401403429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/visitor-series \
-H "Authorization: Bearer <apex-secret-key>"Show URL inventory
/analytics/url-inventory
Returns a shaped Tinybird pageview URL inventory for the API key's shop. Requires a secret API key with analytics:read.
Parameters
daysin queryhostin querypathContainsin querylimitin queryoffsetin query
Responses
200URL inventory401403429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/url-inventory \
-H "Authorization: Bearer <apex-secret-key>"Show geography and device analytics
/analytics/geo
Parameters
daysin query
Responses
200Analytics data401403429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/geo \
-H "Authorization: Bearer <apex-secret-key>"Show session analytics
/analytics/sessions
Parameters
daysin query
Responses
200Analytics data401403429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/sessions \
-H "Authorization: Bearer <apex-secret-key>"Show realtime analytics
/analytics/realtime
Responses
200Analytics data401403429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/realtime \
-H "Authorization: Bearer <apex-secret-key>"Show entry and exit page analytics
/analytics/entry-exit
Parameters
daysin query
Responses
200Analytics data401403429503Analytics is temporarily unavailable
curl \
https://app.drip-apex.com/api/v1/analytics/entry-exit \
-H "Authorization: Bearer <apex-secret-key>"Suggest goals and funnels
/analytics/suggest-goals
Requires a secret API key with the analytics:read scope. The endpoint only reads analytics and returns suggestions — it creates no goals — but it spends model budget, so publishable keys receive 403 Forbidden and a per-shop 24-hour spend guard applies on top of the normal API rate limit.
Responses
200Suggested goals and funnels401403413Request body is too large429502The suggestion model returned unusable output503
curl -X POST \
https://app.drip-apex.com/api/v1/analytics/suggest-goals \
-H "Authorization: Bearer <apex-secret-key>"Other
List assets
/assets
Parameters
include_archivedin query - Include archived assets.limitin querycursorin query
Responses
200Assets with cursor pagination400401403429503
curl \
https://app.drip-apex.com/api/v1/assets \
-H "Authorization: Bearer <apex-secret-key>"Upload assets
/assets
Responses
201Uploaded assets400401403413Too many files or a file exceeds the upload size limit.429503
curl -X POST \
https://app.drip-apex.com/api/v1/assets \
-H "Authorization: Bearer <apex-secret-key>"Get asset
/assets/{id}
Responses
200Asset401403404429503
curl \
https://app.drip-apex.com/api/v1/assets/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Archive asset
/assets/{id}
Archives the asset without deleting its stored file; it can be restored.
Responses
200Deleted401403404429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/assets/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Restore asset
/assets/{id}/restore
Parameters
idin path required
Responses
200Restored asset404
curl -X POST \
https://app.drip-apex.com/api/v1/assets/exp_123/restore \
-H "Authorization: Bearer <apex-secret-key>"List landing pages
/landing-pages
Requires the Apex Labs feature for the shop; shops without it receive 404 Not Found.
Parameters
limitin querycursorin querystatusin query
Responses
200Landing pages with cursor pagination400401403404Apex Labs is not enabled for this shop, so landing pages are unavailable.429503
curl \
https://app.drip-apex.com/api/v1/landing-pages \
-H "Authorization: Bearer <apex-secret-key>"Get landing page
/landing-pages/{id}
Responses
200Landing page401403404429503
curl \
https://app.drip-apex.com/api/v1/landing-pages/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Export personal data
/data-export
Parameters
request_idin queryvisitor_idin query
Responses
200Data export400401403404429503
curl \
https://app.drip-apex.com/api/v1/data-export \
-H "Authorization: Bearer <apex-secret-key>"Request a personal data export
/data-export
Request body
{
visitor_id: string
limit?: integer
}Responses
200Completed data export400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/data-export \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"visitor_id": "example_visitor_id",
"limit": 1
}'Read data-deletion status
/data-deletion
Parameters
request_idin queryvisitor_idin query
Responses
200Deletion status400401403404429503
curl \
https://app.drip-apex.com/api/v1/data-deletion \
-H "Authorization: Bearer <apex-secret-key>"Request data deletion
/data-deletion
Request body
{
visitor_id: string
}Responses
202Deletion accepted400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/data-deletion \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"visitor_id": "example_visitor_id"
}'Inspect experiment conflicts
/experiments/conflicts
Request body
{
selectors: string[]
exclude_experiment_id?: string (uuid)
}Responses
200Conflict analysis400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/conflicts \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"selectors": [],
"exclude_experiment_id": "uuid-here"
}'Update experiment QA
/experiments/{id}/qa
Responses
200QA updated400401403404409429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/experiments/exp_123/qa \
-H "Authorization: Bearer <apex-secret-key>"Reset experiment QA
/experiments/{id}/qa
Responses
200QA reset400401403404409429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/experiments/exp_123/qa \
-H "Authorization: Bearer <apex-secret-key>"Read QA run
/experiments/{id}/qa/run
Responses
200QA run, including QA destination URLs for goals on pages outside experiment targeting (goal-page entries in urls, and goalPageDestinations evidence on the qa_url_coverage checklist item)400401403404429503
curl \
https://app.drip-apex.com/api/v1/experiments/exp_123/qa/run \
-H "Authorization: Bearer <apex-secret-key>"Update QA run
/experiments/{id}/qa/run
Request body
{
runId: string
itemId?: string
status?: "pending" | "pass" | "warning" | "fail" | "accepted" | "skipped"
notes?: string
evidence?: object
runNotes?: string
acceptanceCriteriaSummary?: string,null
}Responses
200QA run updated400401403404429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/experiments/exp_123/qa/run \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"runId": "example_runId"
}'Add a custom QA checklist item
/experiments/{id}/qa/run
Request body
{
runId: string
title: string
description?: string
category?: string
required?: boolean
}Responses
201QA checklist item created400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/qa/run \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"runId": "example_runId",
"title": "example_title"
}'Delete custom QA checklist item
/experiments/{id}/qa/run
Parameters
runIdin queryitemIdin query
Request body
{
runId?: string
itemId?: string
}Responses
200QA run deleted400401403404429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/experiments/exp_123/qa/run \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"runId": "example_runId",
"itemId": "example_itemId"
}'Retired experiment launch endpoint
/experiments/{id}/start
This endpoint is gone. Launch traffic through the dashboard approval workflow.
Responses
410Launch is dashboard-only
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/start \
-H "Authorization: Bearer <apex-secret-key>"Create harness session
/harness/sessions
Request body
{
experimentId?: string
variationId?: string
experimentSlug: string
experimentName: string
variationSlug: string
variationName: string
targetUrl: string (uri)
resetJs?: string,null
antiFlickerSelectors?: string[]
ttlSeconds?: integer
}Responses
201Harness session created400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/harness/sessions \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"experimentSlug": "example_experimentSlug",
"experimentName": "example_experimentName",
"variationSlug": "example_variationSlug",
"variationName": "example_variationName",
"targetUrl": "https://example.com"
}'Create harness session version
/harness/sessions/{id}/versions
Responses
201Version created400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/harness/sessions/exp_123/versions \
-H "Authorization: Bearer <apex-secret-key>"Generate external purchase pixel snippet
/external-pixels/snippet
Requires a secret API key with the external_pixels:write scope; the response embeds a signed ingest credential, so read-scoped and publishable keys receive 403 Forbidden.
Request body
{
provider?: string
handoverParam?: string
globalName?: string
}Responses
200Generated snippet400401403429503
curl -X POST \
https://app.drip-apex.com/api/v1/external-pixels/snippet \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"provider": "example_provider",
"handoverParam": "example_handoverParam",
"globalName": "example_globalName"
}'List backlog
/backlog
Parameters
limitin querycursorin queryinclude_archivedin query - Include archived backlog items when true.
Responses
200Paginated backlog400401403429503
curl \
https://app.drip-apex.com/api/v1/backlog \
-H "Authorization: Bearer <apex-secret-key>"Create a backlog item
/backlog
Request body
{ $ref: "BacklogCreate" }Responses
201Created400401403409429503
curl -X POST \
https://app.drip-apex.com/api/v1/backlog \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get a backlogitem
/backlog/{id}
Responses
200Resource401403404429503
curl \
https://app.drip-apex.com/api/v1/backlog/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update a backlogitem
/backlog/{id}
Request body
{ $ref: "BacklogUpdate" }Responses
200Updated400401403404409429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/backlog/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Archive a backlog item
/backlog/{id}
Archives the backlog item instead of destroying it.
Responses
200Deleted401403404429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/backlog/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Archive a backlog item and reject its roadmap decision
/backlog/{id}/archive
Request body
{
feedback?: string,null
reason?: string,null
}Responses
200Archived backlog item401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/backlog/exp_123/archive \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Restore an archived backlog item and reset its roadmap decision to proposed
/backlog/{id}/restore
Responses
200Restored backlog item401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/backlog/exp_123/restore \
-H "Authorization: Bearer <apex-secret-key>"List signals
/signals
The first page includes the built-in signal catalog before paginated custom signals. Built-ins do not participate in cursor pagination.
Parameters
limitin querycursorin queryinclude_archivedin query - Include archived custom signals when true. Built-in signals are always active.
Responses
200Paginated signals400401403429503
curl \
https://app.drip-apex.com/api/v1/signals \
-H "Authorization: Bearer <apex-secret-key>"Create a signal
/signals
Request body
{ $ref: "SignalCreate" }Responses
201Created400401403409429503
curl -X POST \
https://app.drip-apex.com/api/v1/signals \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get a signal
/signals/{id}
Responses
200Resource401403404429503
curl \
https://app.drip-apex.com/api/v1/signals/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update a signal
/signals/{id}
Request body
{ $ref: "SignalUpdate" }Responses
200Updated400401403404409429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/signals/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Delete or archive a signal
/signals/{id}
Responses
200Deleted or archived401403404429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/signals/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"List flags
/flags
Parameters
limitin querycursorin query
Responses
200Flags with cursor pagination400401403429503
curl \
https://app.drip-apex.com/api/v1/flags \
-H "Authorization: Bearer <apex-secret-key>"Create flag
/flags
Request body
{ $ref: "FeatureFlagInput" }Responses
201Created flag400401403429503
curl -X POST \
https://app.drip-apex.com/api/v1/flags \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get flag
/flags/{id}
Responses
200Flag401403404429503
curl \
https://app.drip-apex.com/api/v1/flags/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update flag
/flags/{id}
Request body
{ $ref: "FeatureFlagUpdateInput" }Responses
200Updated flag400401403404429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/flags/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Activate flag
/flags/{id}/activate
Responses
200Updated flag401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/flags/exp_123/activate \
-H "Authorization: Bearer <apex-secret-key>"Get flag edge publication status
/flags/{id}/status
Returns database publication metadata, the propagation worst-case window derived from the shop's effective runtime cache TTLs, and, for visual flags, the public edge config URL used to confirm propagation. Edge propagation does not apply to API-delivered flags.
Responses
200Flag publication status401403404429503
curl \
https://app.drip-apex.com/api/v1/flags/exp_123/status \
-H "Authorization: Bearer <apex-secret-key>"Pause flag
/flags/{id}/pause
Responses
200Updated flag401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/flags/exp_123/pause \
-H "Authorization: Bearer <apex-secret-key>"Archive flag
/flags/{id}/archive
Responses
200Updated flag401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/flags/exp_123/archive \
-H "Authorization: Bearer <apex-secret-key>"List personalizations
/personalizations
Parameters
limitin querycursorin query
Responses
200Personalizations with cursor pagination400401403429503
curl \
https://app.drip-apex.com/api/v1/personalizations \
-H "Authorization: Bearer <apex-secret-key>"Create personalization
/personalizations
Request body
{ $ref: "PersonalizationInput" }Responses
201Created personalization400401403429503
curl -X POST \
https://app.drip-apex.com/api/v1/personalizations \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get personalization
/personalizations/{id}
Responses
200Personalization401403404429503
curl \
https://app.drip-apex.com/api/v1/personalizations/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update personalization
/personalizations/{id}
Request body
{ $ref: "PersonalizationUpdateInput" }Responses
200Updated personalization400401403404429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/personalizations/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Activate personalization
/personalizations/{id}/activate
Responses
200Updated personalization401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/personalizations/exp_123/activate \
-H "Authorization: Bearer <apex-secret-key>"Pause personalization
/personalizations/{id}/pause
Responses
200Updated personalization401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/personalizations/exp_123/pause \
-H "Authorization: Bearer <apex-secret-key>"Archive personalization
/personalizations/{id}/archive
Responses
200Updated personalization401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/personalizations/exp_123/archive \
-H "Authorization: Bearer <apex-secret-key>"List pages
/pages
Parameters
limitin querycursorin query
Responses
200pages list400401403404429503
curl \
https://app.drip-apex.com/api/v1/pages \
-H "Authorization: Bearer <apex-secret-key>"Create pages
/pages
Request body
{ $ref: "PageInput" }Responses
201pages created400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/pages \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get page
/pages/{id}
Responses
200page returned400401403404429503
curl \
https://app.drip-apex.com/api/v1/pages/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update page
/pages/{id}
Request body
{ $ref: "PageUpdateInput" }Responses
200page returned400401403404409Conflict. A live-consumer acknowledgement conflict returns the PageLiveImpactError shape — repeat the request with confirm_live_impact and confirmed_consumer_ids carrying every id listed. A trigger-propagation race or duplicate API name returns the generic Error shape.422429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/pages/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Delete page
/pages/{id}
Responses
200page deleted400401403404409429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/pages/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"List segments
/segments
Parameters
limitin querycursorin query
Responses
200segments list400401403404429503
curl \
https://app.drip-apex.com/api/v1/segments \
-H "Authorization: Bearer <apex-secret-key>"Create segments
/segments
Request body
{ $ref: "SegmentInput" }Responses
201segments created400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/segments \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Update segment
/segments/{id}
Request body
{ $ref: "SegmentUpdateInput" }Responses
200segment returned400401403404409422429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/segments/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Delete segment
/segments/{id}
Responses
200segment deleted400401403404409429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/segments/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"List exclusion groups
/exclusion-groups
Parameters
limitin querycursorin queryinclude_archivedin query - Include archived exclusion groups.
Responses
200exclusion groups list400401403404429503
curl \
https://app.drip-apex.com/api/v1/exclusion-groups \
-H "Authorization: Bearer <apex-secret-key>"Create exclusion groups
/exclusion-groups
Request body
{ $ref: "ExclusionGroupInput" }Responses
201exclusion groups created400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/exclusion-groups \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get exclusion group
/exclusion-groups/{id}
Responses
200exclusion group returned400401403404429503
curl \
https://app.drip-apex.com/api/v1/exclusion-groups/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update exclusion group
/exclusion-groups/{id}
Request body
{ $ref: "ExclusionGroupUpdateInput" }Responses
200exclusion group returned400401403404409422429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/exclusion-groups/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Archive exclusion group
/exclusion-groups/{id}
Archives the group while preserving membership.
Responses
200exclusion group deleted400401403404409429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/exclusion-groups/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Restore exclusion group
/exclusion-groups/{id}/restore
Parameters
idin path required
Responses
200Exclusion group restored400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/exclusion-groups/exp_123/restore \
-H "Authorization: Bearer <apex-secret-key>"List funnels
/funnels
Parameters
limitin querycursorin queryinclude_archivedin query - Include archived funnels.
Responses
200funnels list400401403404429503
curl \
https://app.drip-apex.com/api/v1/funnels \
-H "Authorization: Bearer <apex-secret-key>"Create funnels
/funnels
Request body
{ $ref: "FunnelInput" }Responses
201funnels created400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/funnels \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get funnel
/funnels/{id}
Responses
200funnel returned400401403404429503
curl \
https://app.drip-apex.com/api/v1/funnels/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update funnel
/funnels/{id}
Request body
{ $ref: "FunnelUpdateInput" }Responses
200funnel returned400401403404409422429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/funnels/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Archive funnel
/funnels/{id}
Archives the funnel instead of destroying it.
Responses
200funnel deleted400401403404409429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/funnels/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Restore funnel
/funnels/{id}/restore
Parameters
idin path required
Responses
200Restored funnel400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/funnels/exp_123/restore \
-H "Authorization: Bearer <apex-secret-key>"Replace exclusion group members
/exclusion-groups/{id}/members
Request body
{ $ref: "ExclusionGroupMembersInput" }Responses
200Exclusion group members replaced400401403404409422429503
curl -X PUT \
https://app.drip-apex.com/api/v1/exclusion-groups/exp_123/members \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Experiments
Attach or upload QA evidence
/experiments/{id}/qa/evidence
Attaches a terminal screenshot job, writes typed evidence records, or uploads QA evidence images. Exactly one request form is accepted per call.
Request body
unknownResponses
200Signed QA run with the updated evidence400401403404409429502Evidence upload failed503
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/qa/evidence \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Create an artifact-injecting proxy preview session
/preview-sessions
Requires a secret API key with experiments:write. The returned short-lived URL is a bearer capability that renders the selected draft variation without a dashboard session or installed Apex snippet.
Request body
{
experiment_id: string
variation_id?: string
target_url?: string (uri)
ttl_hours?: integer = 168
}Responses
200Preview session400401403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/preview-sessions \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"experiment_id": "example_experiment_id",
"variation_id": "example_variation_id",
"target_url": "https://example.com",
"ttl_hours": 168
}'List experiments
/experiments
Returns a paginated list of experiments. Supports cursor-based pagination and optional status filter.
Parameters
statusin queryarchivedin query - Set to 1 to include archived experimentslimitin querycursorin query - ID of the last item from the previous page
Responses
200Paginated list of experiments401Unauthorized429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/experiments \
-H "Authorization: Bearer <apex-secret-key>"Create experiment
/experiments
Creates a new experiment. Default control and variant are created if variations are not provided. Omitted statistical settings use the shop testing defaults. Experiments authenticated with a user API key default owner_user_id to that key's user; organization- and shop-scoped keys have no user and leave the owner null.
Request body
{
name: string
slug?: string | null
description?: string | null
owner_user_id?: string,null (uuid)
counting_type?: "standard" | "setup_test" | "aa_test" | "non_program"
delivery_type?: "mutation" | "redirect"
type?: "standard" | "setup_test" | "aa_test" | "non_program"
experiment_type?: "mutation" | "redirect"
traffic_allocation?: number = 1
experiment_js?: string | null
experiment_reset_js?: string | null
experiment_css?: string | null
sequential_testing_enabled?: boolean
significance_level?: number
statistical_power?: number
store_url?: string (uri)
auto_stop_override?: AutoStopOverride
guardian_override?: GuardianOverride
targeting?: any
variations?: object[]
primary_goal_id?: string (uuid)
goal_ids?: string[]
}Responses
201Experiment created400Validation error401Unauthorized429Rate limit exceeded503
curl -X POST \
https://app.drip-apex.com/api/v1/experiments \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "example_name"
}'Get experiment
/experiments/{id}
Returns a single experiment by ID with variations and goals.
Parameters
idin path required
Responses
200Experiment details404Experiment not found
curl \
https://app.drip-apex.com/api/v1/experiments/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update experiment
/experiments/{id}
Partially updates an experiment. Cannot update completed experiments.
Parameters
idin path required
Request body
{
name?: string
slug?: string | null
description?: string | null
owner_user_id?: string,null (uuid)
counting_type?: "standard" | "setup_test" | "aa_test" | "non_program"
type?: "standard" | "setup_test" | "aa_test" | "non_program"
traffic_allocation?: number
experiment_js?: string | null
experiment_reset_js?: string | null
experiment_css?: string | null
sequential_testing_enabled?: boolean
store_url?: string (uri)
auto_stop_override?: AutoStopOverride
guardian_override?: GuardianOverride
targeting?: any
confirmTargetingReplace?: boolean
}Responses
200Experiment updated400Cannot update completed experiment404Experiment not found409Targeting replacement requires confirmation (error.code confirm_targeting_replace_required): the update would replace the experiment's author-explicit URL targeting with a page-entity rule. Retry with confirmTargetingReplace: true.
curl -X PATCH \
https://app.drip-apex.com/api/v1/experiments/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Archive experiment
/experiments/{id}
Archives an experiment while preserving its variations and results history.
Parameters
idin path required
Responses
200Experiment deleted404Experiment not found
curl -X DELETE \
https://app.drip-apex.com/api/v1/experiments/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Read experiment filesystem
/experiments/{id}/filesystem
Returns the complete canonical filesystem snapshot for an experiment. File hashes can be used to detect changes before planning a write.
Parameters
idin path required
Responses
200Canonical experiment filesystem401Unauthorized404Experiment not found429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/experiments/exp_123/filesystem \
-H "Authorization: Bearer <apex-secret-key>"Plan an experiment filesystem apply
/experiments/{id}/filesystem/plan
Validates a complete filesystem snapshot and reports the changes without writing them. Draft experiments accept all supported filesystem changes. Paused experiments accept treatment-content changes and redirect destinations. Running experiments accept treatment-content changes only; redirect destinations remain draft/paused-only. Structural changes remain draft-only and are reported with the offending file paths.
Parameters
idin path required
Request body
{
files: object[]
}Responses
200Filesystem apply plan400Invalid request body401Unauthorized404Experiment not found429Rate limit exceeded503
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/filesystem/plan \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"files": []
}'Apply an experiment filesystem
/experiments/{id}/filesystem/apply
Atomically applies experiment, goal, variation, and variation-artifact changes to draft experiments. Paused experiments accept treatment-content changes and redirect destinations. Running experiments accept treatment-content changes only; redirect destinations remain draft/paused-only. Structural changes remain draft-only and fail closed with the offending file paths. Running artifact writes republish the storefront configuration. A successful response with applied=true means every database change committed. applied=false means no changes from this request committed, except when saved=true reports a committed artifact whose storefront publication failed. Identically re-applying an already committed snapshot is safe and converges on the same final state.
Parameters
idin path required
Request body
{
files: object[]
}Responses
200Atomic apply outcome400Invalid request body401Unauthorized404Experiment not found429Rate limit exceeded500Unexpected failure; the atomic database transaction was rolled back and no filesystem changes committed.503
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/filesystem/apply \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"files": []
}'Get experiment results
/experiments/{id}/results
Returns the canonical experiment results read model, including totals, arms, decision, metrics, timeseries, warnings, and delivery health.
Parameters
idin path requiredcurrencyin query - Optional ISO currency code for revenue diagnostics.
Responses
200Experiment results401Unauthorized403API key is missing experiment read permission404Experiment not found429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/experiments/exp_123/results \
-H "Authorization: Bearer <apex-secret-key>"Get experiment by slug
/experiments/by-slug/{slug}
Fetch a single experiment by slug (scoped to the API key's shop).
Parameters
slugin path required
Responses
200Experiment details401Unauthorized404Experiment not found429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/experiments/by-slug/example_slug \
-H "Authorization: Bearer <apex-secret-key>"Upsert experiment by slug
/experiments/by-slug/{slug}
Idempotently create or update a draft experiment by slug. New experiments use the shop testing defaults for omitted statistical settings and default owner_user_id to the authenticated user for user API keys; organization- and shop-scoped keys leave the owner null. If an experiment exists with this slug and is not in draft status, returns 409.
Parameters
slugin path required
Request body
{
name: string
description?: string | null
counting_type?: "standard" | "setup_test" | "aa_test" | "non_program"
delivery_type?: "mutation" | "redirect"
type?: "standard" | "setup_test" | "aa_test" | "non_program"
experiment_type?: "mutation" | "redirect"
traffic_allocation?: number = 1
experiment_js?: string | null
experiment_reset_js?: string | null
experiment_css?: string | null
sequential_testing_enabled?: boolean
significance_level?: number
statistical_power?: number
store_url?: string (uri)
auto_stop_override?: AutoStopOverride
targeting?: any
variations: object[]
primary_goal_id?: string (uuid)
goal_ids?: string[]
}Responses
200Experiment updated201Experiment created400Validation error401Unauthorized409Conflict (experiment not in draft status or slug already exists)429Rate limit exceeded503
curl -X PUT \
https://app.drip-apex.com/api/v1/experiments/by-slug/example_slug \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "example_name",
"variations": []
}'Pause experiment
/experiments/{id}/pause
Pauses a running experiment.
Parameters
idin path required
Responses
200Experiment paused400Only running experiments can be paused404Experiment not found502Commerce configuration failed before commit, or the lifecycle change committed but storefront publication failed503Publication lock contended; retry after the Retry-After interval
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/pause \
-H "Authorization: Bearer <apex-secret-key>"Complete experiment
/experiments/{id}/complete
Marks a running or paused experiment as completed. Sets ended_at timestamp.
Parameters
idin path required
Responses
200Experiment completed400Only running or paused experiments can be completed404Experiment not found502Commerce configuration failed before commit, or the lifecycle change committed but storefront publication failed503Publication lock contended; retry after the Retry-After interval
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/complete \
-H "Authorization: Bearer <apex-secret-key>"Duplicate experiment
/experiments/{id}/duplicate
Creates a faithful copy of the experiment in draft status with its configuration, variation artifacts, landing-page bindings, and goal associations. Review, scheduling, runtime, and result state do not carry over.
Parameters
idin path required
Responses
201Duplicate experiment created400A variation artifact could not be copied; no duplicate is created404Experiment not found409A concurrent write caused a temporary transaction conflict (error code tx_write_conflict); retry the request.
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/duplicate \
-H "Authorization: Bearer <apex-secret-key>"Generate experiment with AI
/experiments/generate
Uses AI to generate an experiment configuration based on a store URL and prompt.
Request body
{
store_url: string (uri)
prompt: string
primary_goal_id?: string (uuid)
goal_ids?: string[]
traffic_allocation?: number = 1
targeting?: any
screenshot_devices?: string[]
}Responses
201AI-generated experiment created400Validation error
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/generate \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"store_url": "https://example.com",
"prompt": "example_prompt"
}'Platform admin
Read allowlisted platform settings
/admin/settings
Requires an admin:read user API key and a live PlatformAccess row; environment email grants do not apply.
Responses
200Settings401403429503
curl \
https://app.drip-apex.com/api/v1/admin/settings \
-H "Authorization: Bearer <apex-secret-key>"Update allowlisted platform settings
/admin/settings
Only guardian_enabled and srm_check_enabled are accepted.
Request body
{
guardian_enabled?: boolean
srm_check_enabled?: boolean
}Responses
200Settings updated400401403429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/admin/settings \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"guardian_enabled": false,
"srm_check_enabled": false
}'List tracking quarantine events
/admin/tracking/quarantine
Read-only platform view requiring a live PlatformAccess row.
Parameters
shopIdin queryreasonCodein queryverdictin querylimitin query
Responses
200Quarantine rows401403429503
curl \
https://app.drip-apex.com/api/v1/admin/tracking/quarantine \
-H "Authorization: Bearer <apex-secret-key>"Account
Get the current user's profile
/account/profile
Responses
200Account profile401403429503
curl \
https://app.drip-apex.com/api/v1/account/profile \
-H "Authorization: Bearer <apex-secret-key>"Update the current user's profile
/account/profile
Request body
{
displayName?: string
avatarDataUrl?: string,null
}Responses
200Updated account profile400401403429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/account/profile \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"displayName": "example_displayName"
}'API keys
List a shop's API keys
/keys
Parameters
shop_idin query required
Responses
200API key metadata; hashes and secrets are never included400403404429503
curl \
https://app.drip-apex.com/api/v1/keys \
-H "Authorization: Bearer <apex-secret-key>"Create a shop API key
/keys
Request body
{
shop_id: string (uuid)
name: string
type: "live_secret" | "test_secret" | "publishable"
permissions?: string[]
rate_limit?: integer
expires_at?: string,null (date-time)
}Responses
201Created key, including its secret exactly once400403404429503
curl -X POST \
https://app.drip-apex.com/api/v1/keys \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"shop_id": "uuid-here",
"name": "example_name",
"type": "live_secret"
}'Revoke a shop API key
/keys/{id}
Parameters
idin path requiredshop_idin query required
Responses
200Revoked400403404429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/keys/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"User keys
Inspect the current user API key identity
/me
Responses
200User key identity and live organization role401403429503
curl \
https://app.drip-apex.com/api/v1/me \
-H "Authorization: Bearer <apex-secret-key>"List every organization and shop available to a user API key
/me/context
Responses
200User key context with effective organization and shop roles401403429503
curl \
https://app.drip-apex.com/api/v1/me/context \
-H "Authorization: Bearer <apex-secret-key>"Consent
Read consent gating settings
/consent
Responses
200Consent settings401403429503
curl \
https://app.drip-apex.com/api/v1/consent \
-H "Authorization: Bearer <apex-secret-key>"Update consent gating settings
/consent
Request body
{
consentMode?: object
applyCanonicalSplit?: "true"
}Responses
200Updated consent settings400401403429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/consent \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"consentMode": {},
"applyCanonicalSplit": true
}'Install Domains
Read install domains and storefront origins
/install-domains
Responses
200Install domains401403429503
curl \
https://app.drip-apex.com/api/v1/install-domains \
-H "Authorization: Bearer <apex-secret-key>"Replace install domains
/install-domains
Request body
{
domains: string[]
ifRevision?: string
}Responses
200Updated install domains and edge precompile outcome400401403409Install domains changed since the supplied revision was read; re-read and retry.429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/install-domains \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"domains": [],
"ifRevision": "example_ifRevision"
}'External tracking
Read cross-domain identity handover settings
/external-tracking
Responses
200External tracking settings401403429503
curl \
https://app.drip-apex.com/api/v1/external-tracking \
-H "Authorization: Bearer <apex-secret-key>"Update cross-domain identity handover settings
/external-tracking
Request body
{
externalTracking?: any
ifRevision?: string (date-time)
}Responses
200Updated handover settings and edge precompile outcome400401403409429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/external-tracking \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"ifRevision": "example_ifRevision"
}'Runtime settings
Read public runtime settings
/runtime-settings
Responses
200Parsed runtime settings with shop identity401403429503
curl \
https://app.drip-apex.com/api/v1/runtime-settings \
-H "Authorization: Bearer <apex-secret-key>"Update data layer triggers or setup capture
/runtime-settings
Request body
{
dataLayerTriggers?: DataLayerTrigger[]
setupCapture?: object
expectedVersion?: string (date-time)
}Responses
200Updated runtime settings and precompile result400409
curl -X PATCH \
https://app.drip-apex.com/api/v1/runtime-settings \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"dataLayerTriggers": [],
"setupCapture": {},
"expectedVersion": "example_expectedVersion"
}'Apply a server-owned runtime integration recipe
/runtime-settings/recipes
Request body
{
recipeId: "customDataLayerPurchase" | "ga4Ecommerce"
params?: object
expectedVersion?: string (date-time)
}Responses
200Updated runtime settings and precompile result400409
curl -X POST \
https://app.drip-apex.com/api/v1/runtime-settings/recipes \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"recipeId": "customDataLayerPurchase",
"params": {},
"expectedVersion": "example_expectedVersion"
}'Environments
List runtime environments and domain mappings
/environments
Responses
200Environment settings401403429503
curl \
https://app.drip-apex.com/api/v1/environments \
-H "Authorization: Bearer <apex-secret-key>"Update runtime environments and domain mappings
/environments
Request body
{
environments?: Environments
expected_version?: string (date-time)
}Responses
200Updated environment settings and edge precompile outcome400The environment patch is invalid, including when the active key is absent from the effective environment items.401403409Runtime settings changed since the supplied version was read; re-read and retry.429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/environments \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"expected_version": "example_expected_version"
}'Roadmap
List approved roadmap ideas
/roadmap/approved
Returns approved backlog/roadmap ideas ready to build in Apex. This is the API used by `apex roadmap approved`.
Parameters
limitin querycursorin queryqin query - Search title, description, hypothesis, brief, and research notes.has_experimentin query - When false, only returns approved ideas without a linked experiment. When true, only returns ideas with a linked experiment.
Responses
200Approved roadmap ideas401Unauthorized403API key is missing backlog read permission429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/roadmap/approved \
-H "Authorization: Bearer <apex-secret-key>"Get roadmap build handoff
/roadmap/items/{id}/handoff
Returns the full build brief for an approved roadmap item, including hypothesis, target page, visual references, scoring, and Apex CLI workspace commands.
Parameters
idin path required
Responses
200Roadmap build handoff401Unauthorized403API key is missing backlog read permission404Roadmap item not found429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/roadmap/items/exp_123/handoff \
-H "Authorization: Bearer <apex-secret-key>"Variations
Generate variation with AI
/experiments/{id}/variations/generate
Uses AI to generate a new variation for an existing experiment.
Parameters
idin path required - Experiment ID
Request body
{
prompt: string
}Responses
201AI-generated variation created400Validation error404Experiment not found
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/variations/generate \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"prompt": "example_prompt"
}'Create variation
/variations
Creates a new variation for a draft experiment. Requires experiment_id in the body.
Request body
{
experiment_id: any
name: string
weight: number
is_control?: boolean = false
redirect_url?: string (uri)
mutations?: Mutation[]
url_blocks?: UrlBlocks
custom_css?: string | null
custom_js?: string | null
}Responses
201Variation created400Validation error or experiment not in draft status404Experiment not found
curl -X POST \
https://app.drip-apex.com/api/v1/variations \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "example_name",
"weight": 1
}'Get variation
/variations/{id}
Returns a single variation by ID.
Parameters
idin path required
Responses
200Variation details403Not authorized to access this variation404Variation not found
curl \
https://app.drip-apex.com/api/v1/variations/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update variation
/variations/{id}
Partially updates a variation. Treatment artifacts (mutations, URL blocks, and custom CSS/JavaScript) can change while the experiment is draft, paused, or running. Running artifact writes republish the storefront configuration. Other variation fields remain draft-only. Cannot update is_control.
Parameters
idin path required
Request body
{
name?: string
weight?: number
redirect_url?: string (uri)
expected_prior_redirect_url?: string (uri)
mutations?: Mutation[]
url_blocks?: UrlBlocks
custom_css?: string | null
custom_js?: string | null
}Responses
200Variation updated400The write was rejected, or treatment artifacts committed before a later publication step reported a failure403Not authorized404Variation not found409Treatment artifacts cannot change after the experiment finishes, the redirect destination changed since it was read, the experiment is no longer editable, or a price-test mutation targets a subscription-priced or bundle-component variant502The running treatment artifact was saved, but storefront publication failed
curl -X PATCH \
https://app.drip-apex.com/api/v1/variations/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Archive variation
/variations/{id}
Archives a non-control variation from a draft experiment. Minimum 2 active variations must remain, and remaining active weights are redistributed.
Parameters
idin path required
Responses
200Variation archived400Cannot delete control, non-draft experiment, or last two variations403Not authorized404Variation not found
curl -X DELETE \
https://app.drip-apex.com/api/v1/variations/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Restore variation
/variations/{id}/restore
Restores an archived variation and redistributes all active variation weights.
Parameters
idin path required
Responses
200Variation restored404Variation not found409Variation is already active or changed concurrently
curl -X POST \
https://app.drip-apex.com/api/v1/variations/exp_123/restore \
-H "Authorization: Bearer <apex-secret-key>"Apex Workspace
Read variation workspace
/experiments/{id}/variations/{variationId}/workspace
Returns the canonical Apex workspace for an exact experiment variation. Used by `apex workspace checkout`.
Parameters
idin path required - Experiment IDvariationIdin path required - Variation ID
Responses
200Canonical workspace payload401Unauthorized403Not authorized to access this variation404Experiment variation workspace not found429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/workspace \
-H "Authorization: Bearer <apex-secret-key>"List variation workspace files
/experiments/{id}/variations/{variationId}/files
Lists canonical workspace files for an exact experiment variation.
Parameters
idin path requiredvariationIdin path required
Responses
200Workspace files401Unauthorized403Not authorized to access this variation404Experiment variation workspace not found429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/files \
-H "Authorization: Bearer <apex-secret-key>"Read variation workspace file
/experiments/{id}/variations/{variationId}/files/{path}
Reads one canonical workspace file. URL-encode the file path, for example src%2Findex.js.
Parameters
idin path requiredvariationIdin path requiredpathin path required - Canonical workspace path, URL-encoded. Supported roots: src, goals, segments, network, metrics.json, targeting.json, experiment.config.json, dev-doc.md.
Responses
200Workspace file401Unauthorized403Not authorized to access this variation404Workspace file not found429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/files/example_path \
-H "Authorization: Bearer <apex-secret-key>"Write variation workspace file
/experiments/{id}/variations/{variationId}/files/{path}
Writes one canonical workspace file and records a workspace revision. Used by `apex workspace publish`.
Parameters
idin path requiredvariationIdin path requiredpathin path required - Canonical workspace path, URL-encoded. Supported roots: src, goals, segments, network, metrics.json, targeting.json, experiment.config.json, dev-doc.md.
Request body
{
content: string
source?: "manual" | "operator" | "build" | "system"
title?: string
}Responses
200Workspace file write result400Validation error or unsupported workspace path401Unauthorized403Not authorized to edit this variation404Experiment variation workspace not found429Rate limit exceeded503
curl -X PUT \
https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/files/example_path \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"content": "example_content",
"source": "manual",
"title": "example_title"
}'Build variation workspace
/experiments/{id}/variations/{variationId}/build
Projects canonical workspace files into Apex runtime state: mutations, CSS, JS, targeting, goals, and segments.
Parameters
idin path requiredvariationIdin path required
Request body
{
mode?: "full" | "validate_only"
allowGoalWrites?: boolean = false
}Responses
200Workspace build succeeded400Workspace build failed401Unauthorized403Not authorized to edit this variation404Experiment variation workspace not found409Workspace build conflicted with a concurrent artifact save429Rate limit exceeded503
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/build \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"mode": "full",
"allowGoalWrites": false
}'List variation workspace revisions
/experiments/{id}/variations/{variationId}/revisions
Lists recent workspace revisions for an exact experiment variation.
Parameters
idin path requiredvariationIdin path required
Responses
200Workspace revisions401Unauthorized403Not authorized to access this variation404Experiment variation workspace not found429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/revisions \
-H "Authorization: Bearer <apex-secret-key>"Tracking
Verify live tracking events
/tracking/verify
Returns recent Tinybird events for the API key's shop so agents can verify revenue, pageview, and custom tracking setup from the CLI.
Parameters
minutesin querylimitin queryexperiment_idin queryevent_typein query - Comma-separated event type filter.
Responses
200Tracking verification summary401Unauthorized403API key is missing experiment read permission429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/tracking/verify \
-H "Authorization: Bearer <apex-secret-key>"Discover the observed tracking schema
/tracking/discovery
Aggregates consented-session QA diagnostic events (qa_mode=1) and normal-traffic pageview denominators (qa_mode=0) for the authenticated API key's shop.
Parameters
minutesin querylimitin query
Responses
200Observed tracking schema report with URL push/pageview counts, timing percentiles, type-collision flags, and ranked storage keys401Unauthorized403API key is missing experiment read permission429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/tracking/discovery \
-H "Authorization: Bearer <apex-secret-key>"Simulate data-layer triggers
/tracking/simulate-trigger
Pure dry run of dataLayerTriggers against payloads. Does not persist or emit events.
Request body
{
triggers: object[]
payloads: array
}Responses
200Side-effect-free simulation verdict400401403413Request body exceeds 64KB429503
curl -X POST \
https://app.drip-apex.com/api/v1/tracking/simulate-trigger \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"triggers": [],
"payloads": []
}'Targeting
Test URL targeting
/targeting/test
Evaluates the API key shop's experiment targeting rules against one URL and returns all matching experiments for parallel-experiment awareness.
Parameters
urlin query requiredstatusin query - Comma-separated statuses or all. Defaults to draft,qa,running,paused.
Responses
200Targeting evaluation400Invalid URL401Unauthorized403API key is missing experiment read permission429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/targeting/test \
-H "Authorization: Bearer <apex-secret-key>"SOS
Create SOS ticket
/sos
Creates an Apex SOS ticket for QA, design, development, config, bug, or handover assistance. A request that links an experiment is appended to that experiment's open ticket of the same type when one exists; a request without an experiment always creates its own ticket.
Request body
{
experiment_id?: string (uuid)
type: "full_handover" | "design" | "development" | "qa" | "config" | "bug"
sub_class?: string | null
loom_url?: string (uri)
description: string
}Responses
200Appended to the linked experiment's open SOS ticket of the same type201SOS ticket created401Unauthorized403API key is missing experiment write permission429Rate limit exceeded502Jira create failed503SOS is disabled
curl -X POST \
https://app.drip-apex.com/api/v1/sos \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"type": "full_handover",
"description": "example_description"
}'List my SOS tickets
/sos/mine
Lists SOS tickets created by the current API key.
Responses
200SOS tickets401Unauthorized403API key is missing experiment read permission429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/sos/mine \
-H "Authorization: Bearer <apex-secret-key>"Brand
Get brand context
/brand-context
Returns the compiled shop brand context for external agents and developer workflows. Internal Apex notes are never included.
Responses
200Compiled brand context401Unauthorized403API key is missing experiment read permission429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/brand-context \
-H "Authorization: Bearer <apex-secret-key>"Goals
List goals
/goals
Returns a paginated list of goals for the shop.
Parameters
limitin querycursorin queryinclude_archivedin query - Include archived goals.
Responses
200Paginated list of goals401Unauthorized429Rate limit exceeded503
curl \
https://app.drip-apex.com/api/v1/goals \
-H "Authorization: Bearer <apex-secret-key>"Create goal
/goals
Creates a new goal. Click goals require page_id plus selector or text_match. Pageview goals require page_id or url_pattern. Custom goals require event_name. Line-item filters are accepted for revenue goals and custom checkout_started/add_to_cart funnel-event goals.
Request body
{
name: string
type: "click" | "pageview" | "custom" | "revenue"
measurement?: "conversion" | "value"
value_property?: string | null
value_unit?: "currency" | "number" | "duration_seconds" | "percent"
selector?: string | null
text_match?: string | null
url_pattern?: string | null
page_id?: string (uuid)
event_name?: string | null
filter?: any
count_once?: boolean = false
capture?: GoalCapture[]
}Responses
201Goal created400Validation error
curl -X POST \
https://app.drip-apex.com/api/v1/goals \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "example_name",
"type": "click"
}'Get goal
/goals/{id}
Returns a single goal by ID.
Parameters
idin path required
Responses
200Goal details404Goal not found
curl \
https://app.drip-apex.com/api/v1/goals/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update goal
/goals/{id}
Partially updates a goal. Line-item filters are accepted for revenue goals and custom checkout_started/add_to_cart funnel-event goals. Custom goals may not listen on reserved wire event names (purchase, pageview, ...): the resulting type/event_name combination is validated against the stored row and rejected with 400 (funnel-event goal names are the sanctioned exception).
Parameters
idin path required
Request body
{
name?: string
type?: "click" | "pageview" | "custom" | "revenue"
measurement?: "conversion" | "value"
value_property?: string | null
value_unit?: "currency" | "number" | "duration_seconds" | "percent"
selector?: string | null
text_match?: string | null
url_pattern?: string | null
page_id?: string (uuid)
event_name?: string | null
filter?: any
count_once?: boolean
capture?: GoalCapture[]
}Responses
200Goal updated404Goal not found
curl -X PATCH \
https://app.drip-apex.com/api/v1/goals/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Archive goal
/goals/{id}
Archives a goal while preserving its experiment and personalization links.
Parameters
idin path required
Responses
200Goal deleted404Goal not found
curl -X DELETE \
https://app.drip-apex.com/api/v1/goals/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Restore goal
/goals/{id}/restore
Parameters
idin path required
Responses
200Goal restored404Goal not found
curl -X POST \
https://app.drip-apex.com/api/v1/goals/exp_123/restore \
-H "Authorization: Bearer <apex-secret-key>"Harness
Publish harness session
/harness/sessions/{id}/publish
Publishes reviewed harness artifacts to the session variation.
Parameters
idin path required
Responses
200Harness session published400Artifact review blocked publish404Harness session not found409Experiment is not in draft status
curl -X POST \
https://app.drip-apex.com/api/v1/harness/sessions/exp_123/publish \
-H "Authorization: Bearer <apex-secret-key>"Screenshots
Create screenshot job
/experiments/{id}/screenshots
Queues a screenshot capture job for the specified variations and devices.
Parameters
idin path required - Experiment ID
Request body
{
devices: string[]
variation_ids: array
}Responses
202Screenshot job queued400Validation error404Experiment not found
curl -X POST \
https://app.drip-apex.com/api/v1/experiments/exp_123/screenshots \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"devices": [],
"variation_ids": []
}'Get screenshot job status
/screenshots/{jobId}
Returns the current status and results of a screenshot job.
Parameters
jobIdin path required
Responses
200Screenshot job details404Job not found
curl \
https://app.drip-apex.com/api/v1/screenshots/job_123 \
-H "Authorization: Bearer <apex-secret-key>"Webhooks
List webhooks
/webhooks
Returns all webhooks for the shop.
Parameters
include_archivedin query - Include archived webhooks.
Responses
200List of webhooks401Unauthorized
curl \
https://app.drip-apex.com/api/v1/webhooks \
-H "Authorization: Bearer <apex-secret-key>"Create webhook
/webhooks
Registers a new webhook endpoint. URL must use HTTPS. Events: experiment.started, experiment.completed, experiment.significant, experiment.guardian_triggered, experiment.guardian_paused, variation.winning, screenshots.completed, project.published.
Request body
{
url: string (uri)
events: string[]
}Responses
201Webhook created400Validation error
curl -X POST \
https://app.drip-apex.com/api/v1/webhooks \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"events": []
}'Get webhook
/webhooks/{id}
Parameters
idin path required
Responses
200Webhook404Webhook not found
curl \
https://app.drip-apex.com/api/v1/webhooks/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update webhook
/webhooks/{id}
Parameters
idin path required
Request body
{
url?: string (uri)
events?: string[]
active?: boolean
}Responses
200Webhook404Webhook not found
curl -X PATCH \
https://app.drip-apex.com/api/v1/webhooks/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"events": [],
"active": false
}'Archive webhook
/webhooks/{id}
Archives a webhook registration while retaining delivery history.
Parameters
idin path required
Responses
200Webhook deleted404Webhook not found
curl -X DELETE \
https://app.drip-apex.com/api/v1/webhooks/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Restore webhook
/webhooks/{id}/restore
Parameters
idin path required
Responses
200Restored webhook404Webhook not found
curl -X POST \
https://app.drip-apex.com/api/v1/webhooks/exp_123/restore \
-H "Authorization: Bearer <apex-secret-key>"List webhook deliveries
/webhooks/{id}/deliveries
Returns recent delivery attempts for one webhook. Delivery IDs are also sent as the X-Apex-Delivery-Id header on outbound webhook requests.
Parameters
idin path requiredstatusin querylimitin query
Responses
200List of webhook delivery attempts404Webhook not found
curl \
https://app.drip-apex.com/api/v1/webhooks/exp_123/deliveries \
-H "Authorization: Bearer <apex-secret-key>"Send test webhook
/webhooks/{id}/test
Sends a signed test event and records the delivery.
Parameters
idin path required
Responses
200Test delivery404Webhook not found409Webhook is inactive
curl -X POST \
https://app.drip-apex.com/api/v1/webhooks/exp_123/test \
-H "Authorization: Bearer <apex-secret-key>"Audit logs
List audit logs
/audit-logs
Parameters
entity_typein queryentity_idin querylimitin queryoffsetin query
Responses
200Audit log page403
curl \
https://app.drip-apex.com/api/v1/audit-logs \
-H "Authorization: Bearer <apex-secret-key>"List audit logs for an authorized shop with a user API key
/shops/{id}/audit-logs
Parameters
entity_typein queryentity_idin querylimitin queryoffsetin query
Responses
200Audit log page403404
curl \
https://app.drip-apex.com/api/v1/shops/exp_123/audit-logs \
-H "Authorization: Bearer <apex-secret-key>"Inbox
List inbox messages
/inbox/messages
Parameters
experiment_idin query
Responses
200Inbox messages403
curl \
https://app.drip-apex.com/api/v1/inbox/messages \
-H "Authorization: Bearer <apex-secret-key>"Send an inbox message
/inbox/messages
Request body
{
thread_type?: "account" | "experiment"
experiment_id?: string,null (uuid)
body: string
}Responses
201Message created400403404
curl -X POST \
https://app.drip-apex.com/api/v1/inbox/messages \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"thread_type": "account",
"body": "example_body"
}'Mark inbox channels read
/inbox/read-state
Request body
unknownResponses
200Read state updated400403404
curl -X POST \
https://app.drip-apex.com/api/v1/inbox/read-state \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Organization
Get the credential organization
/org
Responses
200Dashboard organization detail shape, including a `members` array (id, userId, email, role, defaultShopRole, createdAt) and `_count.members`.401403429503
curl \
https://app.drip-apex.com/api/v1/org \
-H "Authorization: Bearer <apex-secret-key>"Update organization settings
/org
Request body
{
name?: string
slug?: string
billing_email?: string,null
logo_url?: string,null
sso_enabled?: boolean
sso_enforced?: boolean
sso_domain?: string,null
sso_provider_id?: string,null
}Responses
200Updated organization401403429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/org \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'List organization members
/org/members
Responses
200Members from the dashboard member source401429503
curl \
https://app.drip-apex.com/api/v1/org/members \
-H "Authorization: Bearer <apex-secret-key>"List organization invitations
/org/invitations
Responses
200Pending invitations401429503
curl \
https://app.drip-apex.com/api/v1/org/invitations \
-H "Authorization: Bearer <apex-secret-key>"Invite an organization member
/org/invitations
Request body
{
email: string (email)
org_role?: "admin" | "member"
default_shop_role?: "admin" | "editor" | "analyst" | "viewer"
}Responses
201Invitation created401429503
curl -X POST \
https://app.drip-apex.com/api/v1/org/invitations \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"email": "example_email",
"org_role": "admin",
"default_shop_role": "admin"
}'Revoke an organization invitation
/org/invitations/{id}
Parameters
idin path required
Responses
200Invitation revoked401404429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/org/invitations/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update an organization member
/org/members/{id}
Parameters
idin path required
Request body
{
role?: string
default_shop_role?: string
}Responses
200Member updated401429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/org/members/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"role": "example_role",
"default_shop_role": "example_default_shop_role"
}'Remove an organization member
/org/members/{id}
Parameters
idin path required
Responses
200Member removed401429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/org/members/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Team
List shop team members
/team/members
Parameters
shop_idin query required
Responses
200Team members401404429503
curl \
https://app.drip-apex.com/api/v1/team/members \
-H "Authorization: Bearer <apex-secret-key>"List shop invitations
/team/invitations
Parameters
shop_idin query required
Responses
200Invitations401429503
curl \
https://app.drip-apex.com/api/v1/team/invitations \
-H "Authorization: Bearer <apex-secret-key>"Invite a shop member
/team/invitations
Request body
{
email: string (email)
role: string
shop_id: string (uuid)
}Responses
201Invitation created401429503
curl -X POST \
https://app.drip-apex.com/api/v1/team/invitations \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"email": "example_email",
"role": "example_role",
"shop_id": "uuid-here"
}'Revoke a shop invitation
/team/invitations/{id}
Parameters
idin path required
Request body
{
shop_id: string (uuid)
}Responses
200Invitation revoked401429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/team/invitations/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"shop_id": "uuid-here"
}'Update a shop member
/team/members/{id}
Request body
{
shop_id: string (uuid)
role?: "admin" | "editor" | "viewer" | "analyst" | "client_viewer" | "client_approver"
permission_overrides?: object
}Responses
200Member updated401429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/team/members/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"shop_id": "uuid-here",
"role": "admin",
"permission_overrides": {}
}'Remove a shop member
/team/members/{id}
Request body
{
shop_id: string (uuid)
}Responses
200Member removed401429503
curl -X DELETE \
https://app.drip-apex.com/api/v1/team/members/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"shop_id": "uuid-here"
}'Shops
List organization shops
/shops
Responses
200Shop list
curl \
https://app.drip-apex.com/api/v1/shops \
-H "Authorization: Bearer <apex-secret-key>"Create a shop
/shops
Request body
{
name: string
domain: string
platform: "shopify" | "hydrogen" | "shopware" | "woocommerce" | "webflow" | "custom"
plan?: "managed" | "self_serve"
origin?: string,null
currency?: "AED" | "AFN" | "ALL" | "AMD" | "ANG" | "AOA" | "ARS" | "AUD" | "AWG" | "AZN" | "BAM" | "BBD" | "BDT" | "BGN" | "BHD" | "BIF" | "BMD" | "BND" | "BOB" | "BOV" | "BRL" | "BSD" | "BTN" | "BWP" | "BYN" | "BZD" | "CAD" | "CDF" | "CHE" | "CHF" | "CHW" | "CLF" | "CLP" | "CNY" | "COP" | "COU" | "CRC" | "CUP" | "CVE" | "CZK" | "DJF" | "DKK" | "DOP" | "DZD" | "EGP" | "ERN" | "ETB" | "EUR" | "FJD" | "FKP" | "GBP" | "GEL" | "GHS" | "GIP" | "GMD" | "GNF" | "GTQ" | "GYD" | "HKD" | "HNL" | "HRK" | "HTG" | "HUF" | "IDR" | "ILS" | "INR" | "IQD" | "IRR" | "ISK" | "JMD" | "JOD" | "JPY" | "KES" | "KGS" | "KHR" | "KMF" | "KPW" | "KRW" | "KWD" | "KYD" | "KZT" | "LAK" | "LBP" | "LKR" | "LRD" | "LSL" | "LYD" | "MAD" | "MDL" | "MGA" | "MKD" | "MMK" | "MNT" | "MOP" | "MRU" | "MUR" | "MVR" | "MWK" | "MXN" | "MXV" | "MYR" | "MZN" | "NAD" | "NGN" | "NIO" | "NOK" | "NPR" | "NZD" | "OMR" | "PAB" | "PEN" | "PGK" | "PHP" | "PKR" | "PLN" | "PYG" | "QAR" | "RON" | "RSD" | "RUB" | "RWF" | "SAR" | "SBD" | "SCR" | "SDG" | "SEK" | "SGD" | "SHP" | "SLE" | "SOS" | "SRD" | "SSP" | "STN" | "SVC" | "SYP" | "SZL" | "THB" | "TJS" | "TMT" | "TND" | "TOP" | "TRY" | "TTD" | "TWD" | "TZS" | "UAH" | "UGX" | "USD" | "USN" | "UYI" | "UYU" | "UYW" | "UZS" | "VES" | "VND" | "VUV" | "WST" | "XAF" | "XCD" | "XCG" | "XDR" | "XOF" | "XPF" | "XSU" | "YER" | "ZAR" | "ZMW" | "ZWG"
}Responses
201Shop created403409The domain already has a live binding. Owner details are included only when the caller may see the owning shop.
curl -X POST \
https://app.drip-apex.com/api/v1/shops \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "example_name",
"domain": "example_domain",
"platform": "shopify"
}'Get a shop
/shops/{id}
Responses
200Shop detail404
curl \
https://app.drip-apex.com/api/v1/shops/exp_123 \
-H "Authorization: Bearer <apex-secret-key>"Update a shop
/shops/{id}
Request body
{
name?: string
domain?: string
origin?: string,null
tier?: "self_managed" | "apex_managed" | "drip_managed" | "core" | "managed" | "enterprise"
operator_enabled?: boolean
holdout_pct?: number
holdout_v1_enabled?: boolean
currency?: "AED" | "AFN" | "ALL" | "AMD" | "ANG" | "AOA" | "ARS" | "AUD" | "AWG" | "AZN" | "BAM" | "BBD" | "BDT" | "BGN" | "BHD" | "BIF" | "BMD" | "BND" | "BOB" | "BOV" | "BRL" | "BSD" | "BTN" | "BWP" | "BYN" | "BZD" | "CAD" | "CDF" | "CHE" | "CHF" | "CHW" | "CLF" | "CLP" | "CNY" | "COP" | "COU" | "CRC" | "CUP" | "CVE" | "CZK" | "DJF" | "DKK" | "DOP" | "DZD" | "EGP" | "ERN" | "ETB" | "EUR" | "FJD" | "FKP" | "GBP" | "GEL" | "GHS" | "GIP" | "GMD" | "GNF" | "GTQ" | "GYD" | "HKD" | "HNL" | "HRK" | "HTG" | "HUF" | "IDR" | "ILS" | "INR" | "IQD" | "IRR" | "ISK" | "JMD" | "JOD" | "JPY" | "KES" | "KGS" | "KHR" | "KMF" | "KPW" | "KRW" | "KWD" | "KYD" | "KZT" | "LAK" | "LBP" | "LKR" | "LRD" | "LSL" | "LYD" | "MAD" | "MDL" | "MGA" | "MKD" | "MMK" | "MNT" | "MOP" | "MRU" | "MUR" | "MVR" | "MWK" | "MXN" | "MXV" | "MYR" | "MZN" | "NAD" | "NGN" | "NIO" | "NOK" | "NPR" | "NZD" | "OMR" | "PAB" | "PEN" | "PGK" | "PHP" | "PKR" | "PLN" | "PYG" | "QAR" | "RON" | "RSD" | "RUB" | "RWF" | "SAR" | "SBD" | "SCR" | "SDG" | "SEK" | "SGD" | "SHP" | "SLE" | "SOS" | "SRD" | "SSP" | "STN" | "SVC" | "SYP" | "SZL" | "THB" | "TJS" | "TMT" | "TND" | "TOP" | "TRY" | "TTD" | "TWD" | "TZS" | "UAH" | "UGX" | "USD" | "USN" | "UYI" | "UYU" | "UYW" | "UZS" | "VES" | "VND" | "VUV" | "WST" | "XAF" | "XCD" | "XCG" | "XDR" | "XOF" | "XPF" | "XSU" | "YER" | "ZAR" | "ZMW" | "ZWG"
}Responses
200Shop updated403
curl -X PATCH \
https://app.drip-apex.com/api/v1/shops/exp_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Pre-bind a Shopware store to an Apex shop
/shops/{id}/shopware/prebind
Request body
{
shopUrl: string (uri)
environmentKey?: string = "production"
}Responses
200Existing binding returned201Pending binding created400401403409429503
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/shopware/prebind \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"shopUrl": "https://example.com",
"environmentKey": "example_environmentKey"
}'Get auto-stop settings
/shops/{id}/auto-stop
Responses
200Settings
curl \
https://app.drip-apex.com/api/v1/shops/exp_123/auto-stop \
-H "Authorization: Bearer <apex-secret-key>"Update auto-stop settings
/shops/{id}/auto-stop
Request body
{
enabled?: boolean
mode?: "off" | "fixed_horizon_planned_end" | "sequential_significance"
min_runtime_minutes?: integer
sequential?: object
fixed_horizon?: object
}Responses
200Settings updated
curl -X PATCH \
https://app.drip-apex.com/api/v1/shops/exp_123/auto-stop \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get testing-defaults settings
/shops/{id}/testing-defaults
Responses
200Settings
curl \
https://app.drip-apex.com/api/v1/shops/exp_123/testing-defaults \
-H "Authorization: Bearer <apex-secret-key>"Update testing-defaults settings
/shops/{id}/testing-defaults
Request body
{
significanceLevel?: number
statisticalPower?: number
sequentialTestingEnabled?: boolean
}Responses
200Settings updated
curl -X PATCH \
https://app.drip-apex.com/api/v1/shops/exp_123/testing-defaults \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"significanceLevel": 1,
"statisticalPower": 1,
"sequentialTestingEnabled": false
}'Get guardian settings
/shops/{id}/guardian
Responses
200Settings
curl \
https://app.drip-apex.com/api/v1/shops/exp_123/guardian \
-H "Authorization: Bearer <apex-secret-key>"Update guardian settings
/shops/{id}/guardian
Request body
{
enabled?: boolean
pause_on_broken?: boolean
pause_on_harm?: boolean
alert_on_data_quality?: boolean
delivery_drift?: object
revenue_loss?: object,null
}Responses
200Settings updated
curl -X PATCH \
https://app.drip-apex.com/api/v1/shops/exp_123/guardian \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{}'Get the store profile
/shops/{id}/store-profile
Responses
200The complete dashboard Store Profile contract. When the store-profile schema is not yet migrated, the route degrades to `{ schemaReady: false }` with HTTP 200 instead of failing.503Store profile temporarily unavailable (database under pressure); retry shortly.
curl \
https://app.drip-apex.com/api/v1/shops/exp_123/store-profile \
-H "Authorization: Bearer <apex-secret-key>"Review a store-profile fact
/shops/{id}/store-profile/facts/{factId}
Request body
{
status: "suggested" | "confirmed" | "rejected" | "stale"
claim?: string
value?: any
}Responses
200Fact reviewed
curl -X PATCH \
https://app.drip-apex.com/api/v1/shops/exp_123/store-profile/facts/fact_123 \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"status": "suggested",
"claim": "example_claim"
}'Review a semantic finding
/shops/{id}/store-profile/findings/review
Request body
{
key: string
claim: string
status?: string
title?: string
category?: string
source?: string
confidence?: number
value?: any
}Responses
200Finding reviewed
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/store-profile/findings/review \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"key": "example_key",
"claim": "example_claim"
}'Start a store-profile learning run
/shops/{id}/store-profile/learning-runs
Request body
{
trigger?: string = "manual"
sources?: string[]
scope?: string[]
}Responses
201Learning run queued
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/store-profile/learning-runs \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"trigger": "example_trigger",
"sources": [],
"scope": []
}'Get engine state and guardrails
/shops/{id}/engine
Parameters
idin path required
Responses
200Engine state400401403404429503
curl \
https://app.drip-apex.com/api/v1/shops/exp_123/engine \
-H "Authorization: Bearer <apex-secret-key>"Get engine guardrails
/shops/{id}/engine/guardrails
Parameters
idin path required
Responses
200Engine guardrails400401403404429503
curl \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/guardrails \
-H "Authorization: Bearer <apex-secret-key>"Update engine guardrails with optimistic concurrency
/shops/{id}/engine/guardrails
Parameters
idin path required
Request body
{
expected_version: integer
allow?: object
auto_launch?: object
surfaces?: object
segments?: any
max_concurrent?: integer
max_per_page?: integer
}Responses
200Updated engine guardrails400401403404409422429503
curl -X PATCH \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/guardrails \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"expected_version": 1
}'Start engine
/shops/{id}/engine/start
Parameters
idin path required
Responses
200Engine state updated400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/start \
-H "Authorization: Bearer <apex-secret-key>"Pause engine
/shops/{id}/engine/pause
Parameters
idin path required
Responses
200Engine state updated400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/pause \
-H "Authorization: Bearer <apex-secret-key>"Stop engine
/shops/{id}/engine/stop
Parameters
idin path required
Responses
200Engine state updated400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/stop \
-H "Authorization: Bearer <apex-secret-key>"Approve engine proposal
/shops/{id}/engine/proposals/{pid}/approve
Parameters
idin path requiredpidin path required
Responses
200Engine proposal approve decision recorded400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/proposals/p_123/approve \
-H "Authorization: Bearer <apex-secret-key>"Reject engine proposal
/shops/{id}/engine/proposals/{pid}/reject
Parameters
idin path requiredpidin path required
Request body
{
reason: string
}Responses
200Engine proposal reject decision recorded400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/proposals/p_123/reject \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"reason": "example_reason"
}'Veto engine proposal
/shops/{id}/engine/proposals/{pid}/veto
Parameters
idin path requiredpidin path required
Responses
200Engine proposal veto decision recorded400401403404409422429503
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/proposals/p_123/veto \
-H "Authorization: Bearer <apex-secret-key>"Roll a certified Engine winner out to 100% of traffic
/shops/{id}/engine/interventions/{iid}/rollout
Sends all eligible traffic to the winning variation, freezes the certified interval, and starts the decay watch. The program holdout is untouched.
Parameters
idin path requirediidin path required
Request body
{
expected_updated_at: string (date-time)
}Responses
200Engine intervention rolled out400401403404409Rollout refused422429503Either the certified measurement could not be read (rollout refused, retriable) or the rate-limiting backend is unavailable. Both are plain error envelopes; only the first carries a rollout `code`.
curl -X POST \
https://app.drip-apex.com/api/v1/shops/exp_123/engine/interventions/i_123/rollout \
-H "Authorization: Bearer <apex-secret-key>" \
-H "Content-Type: application/json" \
-d '{
"expected_updated_at": "example_expected_updated_at"
}'Funnels
Run funnel analysis
/funnels/{id}/run
Responses
200Funnel run400401403404429502Analysis unavailable503
curl \
https://app.drip-apex.com/api/v1/funnels/exp_123/run \
-H "Authorization: Bearer <apex-secret-key>"