developer

Generated OpenAPI reference

API for managing A/B testing experiments, variations, goals, webhooks, and screenshots.

Assignments

GET

Get deterministic server-side assignments

/assign

Parameters

  • shop_id in query required
  • user_id in query required
  • url in query
  • environment in query
  • experiments in query

Responses

  • 200 Assignments and program cohort returned
  • 400 Invalid request, including a customer identifier supplied in the query string instead of a POST body.
  • 401
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/assign \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 200 Assignments, program cohort, and commerce authorization returned
  • 400
  • 401
  • 403 A logged-in customer assignment was requested for an individual-level decision.
  • 429
  • 503
cURL
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

POST

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-Shop in header required

Request body

{
  verifyToken: string
}

Responses

  • 200 Verified handover payload
  • 400 Missing or invalid shop identifier
  • 401 Unsigned, forged, expired, or cross-shop handover token
  • 500 Handover verification is unavailable
cURL
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

GET

Show dashboard analytics stats

/analytics/stats

Parameters

  • days in query
  • shop_currency in query

Responses

  • 200 Analytics data
  • 400
  • 401
  • 403
  • 422
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/stats \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Show analytics timeseries

/analytics/timeseries

Parameters

  • days in query

Responses

  • 200 Analytics data
  • 401
  • 403
  • 422
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/timeseries \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Show traffic sources

/analytics/traffic

Parameters

  • days in query

Responses

  • 200 Analytics data
  • 401
  • 403
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/traffic \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Show page analytics

/analytics/pages

Parameters

  • days in query
  • planningDays in query - Planning window in days (planning_days is also accepted)
  • limit in query

Responses

  • 200 Analytics data
  • 401
  • 403
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/pages \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Show daily visitor series

/analytics/visitor-series

Parameters

  • days in query

Responses

  • 200 Daily visitors and pageviews
  • 401
  • 403
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/visitor-series \
  -H "Authorization: Bearer <apex-secret-key>"
GET

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

  • days in query
  • host in query
  • pathContains in query
  • limit in query
  • offset in query

Responses

  • 200 URL inventory
  • 401
  • 403
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/url-inventory \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Show geography and device analytics

/analytics/geo

Parameters

  • days in query

Responses

  • 200 Analytics data
  • 401
  • 403
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/geo \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Show session analytics

/analytics/sessions

Parameters

  • days in query

Responses

  • 200 Analytics data
  • 401
  • 403
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/sessions \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Show realtime analytics

/analytics/realtime

Responses

  • 200 Analytics data
  • 401
  • 403
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/realtime \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Show entry and exit page analytics

/analytics/entry-exit

Parameters

  • days in query

Responses

  • 200 Analytics data
  • 401
  • 403
  • 429
  • 503 Analytics is temporarily unavailable
cURL
curl \
  https://app.drip-apex.com/api/v1/analytics/entry-exit \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 200 Suggested goals and funnels
  • 401
  • 403
  • 413 Request body is too large
  • 429
  • 502 The suggestion model returned unusable output
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/analytics/suggest-goals \
  -H "Authorization: Bearer <apex-secret-key>"

Other

GET

List assets

/assets

Parameters

  • include_archived in query - Include archived assets.
  • limit in query
  • cursor in query

Responses

  • 200 Assets with cursor pagination
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/assets \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Upload assets

/assets

Responses

  • 201 Uploaded assets
  • 400
  • 401
  • 403
  • 413 Too many files or a file exceeds the upload size limit.
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/assets \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Get asset

/assets/{id}

Responses

  • 200 Asset
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/assets/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
DELETE

Archive asset

/assets/{id}

Archives the asset without deleting its stored file; it can be restored.

Responses

  • 200 Deleted
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/assets/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Restore asset

/assets/{id}/restore

Parameters

  • id in path required

Responses

  • 200 Restored asset
  • 404
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/assets/exp_123/restore \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List landing pages

/landing-pages

Requires the Apex Labs feature for the shop; shops without it receive 404 Not Found.

Parameters

  • limit in query
  • cursor in query
  • status in query

Responses

  • 200 Landing pages with cursor pagination
  • 400
  • 401
  • 403
  • 404 Apex Labs is not enabled for this shop, so landing pages are unavailable.
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/landing-pages \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Get landing page

/landing-pages/{id}

Responses

  • 200 Landing page
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/landing-pages/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Export personal data

/data-export

Parameters

  • request_id in query
  • visitor_id in query

Responses

  • 200 Data export
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/data-export \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Request a personal data export

/data-export

Request body

{
  visitor_id: string
  limit?: integer
}

Responses

  • 200 Completed data export
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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
}'
GET

Read data-deletion status

/data-deletion

Parameters

  • request_id in query
  • visitor_id in query

Responses

  • 200 Deletion status
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/data-deletion \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Request data deletion

/data-deletion

Request body

{
  visitor_id: string
}

Responses

  • 202 Deletion accepted
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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"
}'
POST

Inspect experiment conflicts

/experiments/conflicts

Request body

{
  selectors: string[]
  exclude_experiment_id?: string (uuid)
}

Responses

  • 200 Conflict analysis
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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"
}'
PATCH

Update experiment QA

/experiments/{id}/qa

Responses

  • 200 QA updated
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 503
cURL
curl -X PATCH \
  https://app.drip-apex.com/api/v1/experiments/exp_123/qa \
  -H "Authorization: Bearer <apex-secret-key>"
DELETE

Reset experiment QA

/experiments/{id}/qa

Responses

  • 200 QA reset
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/experiments/exp_123/qa \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Read QA run

/experiments/{id}/qa/run

Responses

  • 200 QA 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)
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/exp_123/qa/run \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

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

  • 200 QA run updated
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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"
}'
POST

Add a custom QA checklist item

/experiments/{id}/qa/run

Request body

{
  runId: string
  title: string
  description?: string
  category?: string
  required?: boolean
}

Responses

  • 201 QA checklist item created
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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

Delete custom QA checklist item

/experiments/{id}/qa/run

Parameters

  • runId in query
  • itemId in query

Request body

{
  runId?: string
  itemId?: string
}

Responses

  • 200 QA run deleted
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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"
}'
POST

Retired experiment launch endpoint

/experiments/{id}/start

This endpoint is gone. Launch traffic through the dashboard approval workflow.

Responses

  • 410 Launch is dashboard-only
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/experiments/exp_123/start \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 201 Harness session created
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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"
}'
POST

Create harness session version

/harness/sessions/{id}/versions

Responses

  • 201 Version created
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/harness/sessions/exp_123/versions \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 200 Generated snippet
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
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"
}'
GET

List backlog

/backlog

Parameters

  • limit in query
  • cursor in query
  • include_archived in query - Include archived backlog items when true.

Responses

  • 200 Paginated backlog
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/backlog \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Create a backlog item

/backlog

Request body

{ $ref: "BacklogCreate" }

Responses

  • 201 Created
  • 400
  • 401
  • 403
  • 409
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/backlog \
  -H "Authorization: Bearer <apex-secret-key>" \
  -H "Content-Type: application/json" \
  -d '{}'
GET

Get a backlogitem

/backlog/{id}

Responses

  • 200 Resource
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/backlog/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update a backlogitem

/backlog/{id}

Request body

{ $ref: "BacklogUpdate" }

Responses

  • 200 Updated
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 503
cURL
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 '{}'
DELETE

Archive a backlog item

/backlog/{id}

Archives the backlog item instead of destroying it.

Responses

  • 200 Deleted
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/backlog/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Archive a backlog item and reject its roadmap decision

/backlog/{id}/archive

Request body

{
  feedback?: string,null
  reason?: string,null
}

Responses

  • 200 Archived backlog item
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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 '{}'
POST

Restore an archived backlog item and reset its roadmap decision to proposed

/backlog/{id}/restore

Responses

  • 200 Restored backlog item
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/backlog/exp_123/restore \
  -H "Authorization: Bearer <apex-secret-key>"
GET

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

  • limit in query
  • cursor in query
  • include_archived in query - Include archived custom signals when true. Built-in signals are always active.

Responses

  • 200 Paginated signals
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/signals \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Create a signal

/signals

Request body

{ $ref: "SignalCreate" }

Responses

  • 201 Created
  • 400
  • 401
  • 403
  • 409
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/signals \
  -H "Authorization: Bearer <apex-secret-key>" \
  -H "Content-Type: application/json" \
  -d '{}'
GET

Get a signal

/signals/{id}

Responses

  • 200 Resource
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/signals/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update a signal

/signals/{id}

Request body

{ $ref: "SignalUpdate" }

Responses

  • 200 Updated
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 503
cURL
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

Delete or archive a signal

/signals/{id}

Responses

  • 200 Deleted or archived
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/signals/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List flags

/flags

Parameters

  • limit in query
  • cursor in query

Responses

  • 200 Flags with cursor pagination
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/flags \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Create flag

/flags

Request body

{ $ref: "FeatureFlagInput" }

Responses

  • 201 Created flag
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/flags \
  -H "Authorization: Bearer <apex-secret-key>" \
  -H "Content-Type: application/json" \
  -d '{}'
GET

Get flag

/flags/{id}

Responses

  • 200 Flag
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/flags/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update flag

/flags/{id}

Request body

{ $ref: "FeatureFlagUpdateInput" }

Responses

  • 200 Updated flag
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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 '{}'
POST

Activate flag

/flags/{id}/activate

Responses

  • 200 Updated flag
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/flags/exp_123/activate \
  -H "Authorization: Bearer <apex-secret-key>"
GET

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

  • 200 Flag publication status
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/flags/exp_123/status \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Pause flag

/flags/{id}/pause

Responses

  • 200 Updated flag
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/flags/exp_123/pause \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Archive flag

/flags/{id}/archive

Responses

  • 200 Updated flag
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/flags/exp_123/archive \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List personalizations

/personalizations

Parameters

  • limit in query
  • cursor in query

Responses

  • 200 Personalizations with cursor pagination
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/personalizations \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Create personalization

/personalizations

Request body

{ $ref: "PersonalizationInput" }

Responses

  • 201 Created personalization
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/personalizations \
  -H "Authorization: Bearer <apex-secret-key>" \
  -H "Content-Type: application/json" \
  -d '{}'
GET

Get personalization

/personalizations/{id}

Responses

  • 200 Personalization
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/personalizations/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update personalization

/personalizations/{id}

Request body

{ $ref: "PersonalizationUpdateInput" }

Responses

  • 200 Updated personalization
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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 '{}'
POST

Activate personalization

/personalizations/{id}/activate

Responses

  • 200 Updated personalization
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/personalizations/exp_123/activate \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Pause personalization

/personalizations/{id}/pause

Responses

  • 200 Updated personalization
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/personalizations/exp_123/pause \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Archive personalization

/personalizations/{id}/archive

Responses

  • 200 Updated personalization
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/personalizations/exp_123/archive \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List pages

/pages

Parameters

  • limit in query
  • cursor in query

Responses

  • 200 pages list
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/pages \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Create pages

/pages

Request body

{ $ref: "PageInput" }

Responses

  • 201 pages created
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/pages \
  -H "Authorization: Bearer <apex-secret-key>" \
  -H "Content-Type: application/json" \
  -d '{}'
GET

Get page

/pages/{id}

Responses

  • 200 page returned
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/pages/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update page

/pages/{id}

Request body

{ $ref: "PageUpdateInput" }

Responses

  • 200 page returned
  • 400
  • 401
  • 403
  • 404
  • 409 Conflict. 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.
  • 422
  • 429
  • 503
cURL
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

Delete page

/pages/{id}

Responses

  • 200 page deleted
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/pages/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List segments

/segments

Parameters

  • limit in query
  • cursor in query

Responses

  • 200 segments list
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/segments \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Create segments

/segments

Request body

{ $ref: "SegmentInput" }

Responses

  • 201 segments created
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/segments \
  -H "Authorization: Bearer <apex-secret-key>" \
  -H "Content-Type: application/json" \
  -d '{}'
PATCH

Update segment

/segments/{id}

Request body

{ $ref: "SegmentUpdateInput" }

Responses

  • 200 segment returned
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
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

Delete segment

/segments/{id}

Responses

  • 200 segment deleted
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/segments/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List exclusion groups

/exclusion-groups

Parameters

  • limit in query
  • cursor in query
  • include_archived in query - Include archived exclusion groups.

Responses

  • 200 exclusion groups list
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/exclusion-groups \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Create exclusion groups

/exclusion-groups

Request body

{ $ref: "ExclusionGroupInput" }

Responses

  • 201 exclusion groups created
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
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

Get exclusion group

/exclusion-groups/{id}

Responses

  • 200 exclusion group returned
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/exclusion-groups/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update exclusion group

/exclusion-groups/{id}

Request body

{ $ref: "ExclusionGroupUpdateInput" }

Responses

  • 200 exclusion group returned
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
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 '{}'
DELETE

Archive exclusion group

/exclusion-groups/{id}

Archives the group while preserving membership.

Responses

  • 200 exclusion group deleted
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/exclusion-groups/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Restore exclusion group

/exclusion-groups/{id}/restore

Parameters

  • id in path required

Responses

  • 200 Exclusion group restored
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/exclusion-groups/exp_123/restore \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List funnels

/funnels

Parameters

  • limit in query
  • cursor in query
  • include_archived in query - Include archived funnels.

Responses

  • 200 funnels list
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/funnels \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Create funnels

/funnels

Request body

{ $ref: "FunnelInput" }

Responses

  • 201 funnels created
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/funnels \
  -H "Authorization: Bearer <apex-secret-key>" \
  -H "Content-Type: application/json" \
  -d '{}'
GET

Get funnel

/funnels/{id}

Responses

  • 200 funnel returned
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/funnels/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update funnel

/funnels/{id}

Request body

{ $ref: "FunnelUpdateInput" }

Responses

  • 200 funnel returned
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
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 '{}'
DELETE

Archive funnel

/funnels/{id}

Archives the funnel instead of destroying it.

Responses

  • 200 funnel deleted
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/funnels/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Restore funnel

/funnels/{id}/restore

Parameters

  • id in path required

Responses

  • 200 Restored funnel
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/funnels/exp_123/restore \
  -H "Authorization: Bearer <apex-secret-key>"
PUT

Replace exclusion group members

/exclusion-groups/{id}/members

Request body

{ $ref: "ExclusionGroupMembersInput" }

Responses

  • 200 Exclusion group members replaced
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
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

POST

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

unknown

Responses

  • 200 Signed QA run with the updated evidence
  • 400
  • 401
  • 403
  • 404
  • 409
  • 429
  • 502 Evidence upload failed
  • 503
cURL
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 '{}'
POST

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

  • 200 Preview session
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
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
}'
GET

List experiments

/experiments

Returns a paginated list of experiments. Supports cursor-based pagination and optional status filter.

Parameters

  • status in query
  • archived in query - Set to 1 to include archived experiments
  • limit in query
  • cursor in query - ID of the last item from the previous page

Responses

  • 200 Paginated list of experiments
  • 401 Unauthorized
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 201 Experiment created
  • 400 Validation error
  • 401 Unauthorized
  • 429 Rate limit exceeded
  • 503
cURL
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

Get experiment

/experiments/{id}

Returns a single experiment by ID with variations and goals.

Parameters

  • id in path required

Responses

  • 200 Experiment details
  • 404 Experiment not found
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update experiment

/experiments/{id}

Partially updates an experiment. Cannot update completed experiments.

Parameters

  • id in 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

  • 200 Experiment updated
  • 400 Cannot update completed experiment
  • 404 Experiment not found
  • 409 Targeting 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
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 '{}'
DELETE

Archive experiment

/experiments/{id}

Archives an experiment while preserving its variations and results history.

Parameters

  • id in path required

Responses

  • 200 Experiment deleted
  • 404 Experiment not found
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/experiments/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
GET

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

  • id in path required

Responses

  • 200 Canonical experiment filesystem
  • 401 Unauthorized
  • 404 Experiment not found
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/exp_123/filesystem \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • id in path required

Request body

{
  files: object[]
}

Responses

  • 200 Filesystem apply plan
  • 400 Invalid request body
  • 401 Unauthorized
  • 404 Experiment not found
  • 429 Rate limit exceeded
  • 503
cURL
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": []
}'
POST

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

  • id in path required

Request body

{
  files: object[]
}

Responses

  • 200 Atomic apply outcome
  • 400 Invalid request body
  • 401 Unauthorized
  • 404 Experiment not found
  • 429 Rate limit exceeded
  • 500 Unexpected failure; the atomic database transaction was rolled back and no filesystem changes committed.
  • 503
cURL
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

Get experiment results

/experiments/{id}/results

Returns the canonical experiment results read model, including totals, arms, decision, metrics, timeseries, warnings, and delivery health.

Parameters

  • id in path required
  • currency in query - Optional ISO currency code for revenue diagnostics.

Responses

  • 200 Experiment results
  • 401 Unauthorized
  • 403 API key is missing experiment read permission
  • 404 Experiment not found
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/exp_123/results \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Get experiment by slug

/experiments/by-slug/{slug}

Fetch a single experiment by slug (scoped to the API key's shop).

Parameters

  • slug in path required

Responses

  • 200 Experiment details
  • 401 Unauthorized
  • 404 Experiment not found
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/by-slug/example_slug \
  -H "Authorization: Bearer <apex-secret-key>"
PUT

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

  • slug in 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

  • 200 Experiment updated
  • 201 Experiment created
  • 400 Validation error
  • 401 Unauthorized
  • 409 Conflict (experiment not in draft status or slug already exists)
  • 429 Rate limit exceeded
  • 503
cURL
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": []
}'
POST

Pause experiment

/experiments/{id}/pause

Pauses a running experiment.

Parameters

  • id in path required

Responses

  • 200 Experiment paused
  • 400 Only running experiments can be paused
  • 404 Experiment not found
  • 502 Commerce configuration failed before commit, or the lifecycle change committed but storefront publication failed
  • 503 Publication lock contended; retry after the Retry-After interval
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/experiments/exp_123/pause \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Complete experiment

/experiments/{id}/complete

Marks a running or paused experiment as completed. Sets ended_at timestamp.

Parameters

  • id in path required

Responses

  • 200 Experiment completed
  • 400 Only running or paused experiments can be completed
  • 404 Experiment not found
  • 502 Commerce configuration failed before commit, or the lifecycle change committed but storefront publication failed
  • 503 Publication lock contended; retry after the Retry-After interval
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/experiments/exp_123/complete \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • id in path required

Responses

  • 201 Duplicate experiment created
  • 400 A variation artifact could not be copied; no duplicate is created
  • 404 Experiment not found
  • 409 A concurrent write caused a temporary transaction conflict (error code tx_write_conflict); retry the request.
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/experiments/exp_123/duplicate \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 201 AI-generated experiment created
  • 400 Validation error
cURL
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

GET

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

  • 200 Settings
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/admin/settings \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

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

  • 200 Settings updated
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
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
}'
GET

List tracking quarantine events

/admin/tracking/quarantine

Read-only platform view requiring a live PlatformAccess row.

Parameters

  • shopId in query
  • reasonCode in query
  • verdict in query
  • limit in query

Responses

  • 200 Quarantine rows
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/admin/tracking/quarantine \
  -H "Authorization: Bearer <apex-secret-key>"

Account

GET

Get the current user's profile

/account/profile

Responses

  • 200 Account profile
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/account/profile \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update the current user's profile

/account/profile

Request body

{
  displayName?: string
  avatarDataUrl?: string,null
}

Responses

  • 200 Updated account profile
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
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

GET

List a shop's API keys

/keys

Parameters

  • shop_id in query required

Responses

  • 200 API key metadata; hashes and secrets are never included
  • 400
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/keys \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 201 Created key, including its secret exactly once
  • 400
  • 403
  • 404
  • 429
  • 503
cURL
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"
}'
DELETE

Revoke a shop API key

/keys/{id}

Parameters

  • id in path required
  • shop_id in query required

Responses

  • 200 Revoked
  • 400
  • 403
  • 404
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/keys/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"

User keys

GET

Inspect the current user API key identity

/me

Responses

  • 200 User key identity and live organization role
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/me \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List every organization and shop available to a user API key

/me/context

Responses

  • 200 User key context with effective organization and shop roles
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/me/context \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Read consent gating settings

/consent

Responses

  • 200 Consent settings
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/consent \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update consent gating settings

/consent

Request body

{
  consentMode?: object
  applyCanonicalSplit?: "true"
}

Responses

  • 200 Updated consent settings
  • 400
  • 401
  • 403
  • 429
  • 503
cURL
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

GET

Read install domains and storefront origins

/install-domains

Responses

  • 200 Install domains
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/install-domains \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Replace install domains

/install-domains

Request body

{
  domains: string[]
  ifRevision?: string
}

Responses

  • 200 Updated install domains and edge precompile outcome
  • 400
  • 401
  • 403
  • 409 Install domains changed since the supplied revision was read; re-read and retry.
  • 429
  • 503
cURL
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

GET

Read cross-domain identity handover settings

/external-tracking

Responses

  • 200 External tracking settings
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/external-tracking \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update cross-domain identity handover settings

/external-tracking

Request body

{
  externalTracking?: any
  ifRevision?: string (date-time)
}

Responses

  • 200 Updated handover settings and edge precompile outcome
  • 400
  • 401
  • 403
  • 409
  • 429
  • 503
cURL
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

GET

Read public runtime settings

/runtime-settings

Responses

  • 200 Parsed runtime settings with shop identity
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/runtime-settings \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update data layer triggers or setup capture

/runtime-settings

Request body

{
  dataLayerTriggers?: DataLayerTrigger[]
  setupCapture?: object
  expectedVersion?: string (date-time)
}

Responses

  • 200 Updated runtime settings and precompile result
  • 400
  • 409
cURL
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"
}'
POST

Apply a server-owned runtime integration recipe

/runtime-settings/recipes

Request body

{
  recipeId: "customDataLayerPurchase" | "ga4Ecommerce"
  params?: object
  expectedVersion?: string (date-time)
}

Responses

  • 200 Updated runtime settings and precompile result
  • 400
  • 409
cURL
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

GET

List runtime environments and domain mappings

/environments

Responses

  • 200 Environment settings
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/environments \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update runtime environments and domain mappings

/environments

Request body

{
  environments?: Environments
  expected_version?: string (date-time)
}

Responses

  • 200 Updated environment settings and edge precompile outcome
  • 400 The environment patch is invalid, including when the active key is absent from the effective environment items.
  • 401
  • 403
  • 409 Runtime settings changed since the supplied version was read; re-read and retry.
  • 429
  • 503
cURL
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

GET

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

  • limit in query
  • cursor in query
  • q in query - Search title, description, hypothesis, brief, and research notes.
  • has_experiment in query - When false, only returns approved ideas without a linked experiment. When true, only returns ideas with a linked experiment.

Responses

  • 200 Approved roadmap ideas
  • 401 Unauthorized
  • 403 API key is missing backlog read permission
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/roadmap/approved \
  -H "Authorization: Bearer <apex-secret-key>"
GET

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

  • id in path required

Responses

  • 200 Roadmap build handoff
  • 401 Unauthorized
  • 403 API key is missing backlog read permission
  • 404 Roadmap item not found
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/roadmap/items/exp_123/handoff \
  -H "Authorization: Bearer <apex-secret-key>"

Variations

POST

Generate variation with AI

/experiments/{id}/variations/generate

Uses AI to generate a new variation for an existing experiment.

Parameters

  • id in path required - Experiment ID

Request body

{
  prompt: string
}

Responses

  • 201 AI-generated variation created
  • 400 Validation error
  • 404 Experiment not found
cURL
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"
}'
POST

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

  • 201 Variation created
  • 400 Validation error or experiment not in draft status
  • 404 Experiment not found
cURL
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

Get variation

/variations/{id}

Returns a single variation by ID.

Parameters

  • id in path required

Responses

  • 200 Variation details
  • 403 Not authorized to access this variation
  • 404 Variation not found
cURL
curl \
  https://app.drip-apex.com/api/v1/variations/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

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

  • id in 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

  • 200 Variation updated
  • 400 The write was rejected, or treatment artifacts committed before a later publication step reported a failure
  • 403 Not authorized
  • 404 Variation not found
  • 409 Treatment 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 variant
  • 502 The running treatment artifact was saved, but storefront publication failed
cURL
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 '{}'
DELETE

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

  • id in path required

Responses

  • 200 Variation archived
  • 400 Cannot delete control, non-draft experiment, or last two variations
  • 403 Not authorized
  • 404 Variation not found
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/variations/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Restore variation

/variations/{id}/restore

Restores an archived variation and redistributes all active variation weights.

Parameters

  • id in path required

Responses

  • 200 Variation restored
  • 404 Variation not found
  • 409 Variation is already active or changed concurrently
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/variations/exp_123/restore \
  -H "Authorization: Bearer <apex-secret-key>"

Apex Workspace

GET

Read variation workspace

/experiments/{id}/variations/{variationId}/workspace

Returns the canonical Apex workspace for an exact experiment variation. Used by `apex workspace checkout`.

Parameters

  • id in path required - Experiment ID
  • variationId in path required - Variation ID

Responses

  • 200 Canonical workspace payload
  • 401 Unauthorized
  • 403 Not authorized to access this variation
  • 404 Experiment variation workspace not found
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/workspace \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List variation workspace files

/experiments/{id}/variations/{variationId}/files

Lists canonical workspace files for an exact experiment variation.

Parameters

  • id in path required
  • variationId in path required

Responses

  • 200 Workspace files
  • 401 Unauthorized
  • 403 Not authorized to access this variation
  • 404 Experiment variation workspace not found
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/files \
  -H "Authorization: Bearer <apex-secret-key>"
GET

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

  • id in path required
  • variationId in path required
  • path in path required - Canonical workspace path, URL-encoded. Supported roots: src, goals, segments, network, metrics.json, targeting.json, experiment.config.json, dev-doc.md.

Responses

  • 200 Workspace file
  • 401 Unauthorized
  • 403 Not authorized to access this variation
  • 404 Workspace file not found
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/files/example_path \
  -H "Authorization: Bearer <apex-secret-key>"
PUT

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

  • id in path required
  • variationId in path required
  • path in 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

  • 200 Workspace file write result
  • 400 Validation error or unsupported workspace path
  • 401 Unauthorized
  • 403 Not authorized to edit this variation
  • 404 Experiment variation workspace not found
  • 429 Rate limit exceeded
  • 503
cURL
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"
}'
POST

Build variation workspace

/experiments/{id}/variations/{variationId}/build

Projects canonical workspace files into Apex runtime state: mutations, CSS, JS, targeting, goals, and segments.

Parameters

  • id in path required
  • variationId in path required

Request body

{
  mode?: "full" | "validate_only"
  allowGoalWrites?: boolean = false
}

Responses

  • 200 Workspace build succeeded
  • 400 Workspace build failed
  • 401 Unauthorized
  • 403 Not authorized to edit this variation
  • 404 Experiment variation workspace not found
  • 409 Workspace build conflicted with a concurrent artifact save
  • 429 Rate limit exceeded
  • 503
cURL
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
}'
GET

List variation workspace revisions

/experiments/{id}/variations/{variationId}/revisions

Lists recent workspace revisions for an exact experiment variation.

Parameters

  • id in path required
  • variationId in path required

Responses

  • 200 Workspace revisions
  • 401 Unauthorized
  • 403 Not authorized to access this variation
  • 404 Experiment variation workspace not found
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/experiments/exp_123/variations/variation_123/revisions \
  -H "Authorization: Bearer <apex-secret-key>"

Tracking

GET

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

  • minutes in query
  • limit in query
  • experiment_id in query
  • event_type in query - Comma-separated event type filter.

Responses

  • 200 Tracking verification summary
  • 401 Unauthorized
  • 403 API key is missing experiment read permission
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/tracking/verify \
  -H "Authorization: Bearer <apex-secret-key>"
GET

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

  • minutes in query
  • limit in query

Responses

  • 200 Observed tracking schema report with URL push/pageview counts, timing percentiles, type-collision flags, and ranked storage keys
  • 401 Unauthorized
  • 403 API key is missing experiment read permission
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/tracking/discovery \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 200 Side-effect-free simulation verdict
  • 400
  • 401
  • 403
  • 413 Request body exceeds 64KB
  • 429
  • 503
cURL
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

GET

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

  • url in query required
  • status in query - Comma-separated statuses or all. Defaults to draft,qa,running,paused.

Responses

  • 200 Targeting evaluation
  • 400 Invalid URL
  • 401 Unauthorized
  • 403 API key is missing experiment read permission
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/targeting/test \
  -H "Authorization: Bearer <apex-secret-key>"

SOS

POST

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

  • 200 Appended to the linked experiment's open SOS ticket of the same type
  • 201 SOS ticket created
  • 401 Unauthorized
  • 403 API key is missing experiment write permission
  • 429 Rate limit exceeded
  • 502 Jira create failed
  • 503 SOS is disabled
cURL
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"
}'
GET

List my SOS tickets

/sos/mine

Lists SOS tickets created by the current API key.

Responses

  • 200 SOS tickets
  • 401 Unauthorized
  • 403 API key is missing experiment read permission
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/sos/mine \
  -H "Authorization: Bearer <apex-secret-key>"

Brand

GET

Get brand context

/brand-context

Returns the compiled shop brand context for external agents and developer workflows. Internal Apex notes are never included.

Responses

  • 200 Compiled brand context
  • 401 Unauthorized
  • 403 API key is missing experiment read permission
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/brand-context \
  -H "Authorization: Bearer <apex-secret-key>"

Goals

GET

List goals

/goals

Returns a paginated list of goals for the shop.

Parameters

  • limit in query
  • cursor in query
  • include_archived in query - Include archived goals.

Responses

  • 200 Paginated list of goals
  • 401 Unauthorized
  • 429 Rate limit exceeded
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/goals \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 201 Goal created
  • 400 Validation error
cURL
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

Get goal

/goals/{id}

Returns a single goal by ID.

Parameters

  • id in path required

Responses

  • 200 Goal details
  • 404 Goal not found
cURL
curl \
  https://app.drip-apex.com/api/v1/goals/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

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

  • id in 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

  • 200 Goal updated
  • 404 Goal not found
cURL
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 '{}'
DELETE

Archive goal

/goals/{id}

Archives a goal while preserving its experiment and personalization links.

Parameters

  • id in path required

Responses

  • 200 Goal deleted
  • 404 Goal not found
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/goals/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Restore goal

/goals/{id}/restore

Parameters

  • id in path required

Responses

  • 200 Goal restored
  • 404 Goal not found
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/goals/exp_123/restore \
  -H "Authorization: Bearer <apex-secret-key>"

Harness

POST

Publish harness session

/harness/sessions/{id}/publish

Publishes reviewed harness artifacts to the session variation.

Parameters

  • id in path required

Responses

  • 200 Harness session published
  • 400 Artifact review blocked publish
  • 404 Harness session not found
  • 409 Experiment is not in draft status
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/harness/sessions/exp_123/publish \
  -H "Authorization: Bearer <apex-secret-key>"

Screenshots

POST

Create screenshot job

/experiments/{id}/screenshots

Queues a screenshot capture job for the specified variations and devices.

Parameters

  • id in path required - Experiment ID

Request body

{
  devices: string[]
  variation_ids: array
}

Responses

  • 202 Screenshot job queued
  • 400 Validation error
  • 404 Experiment not found
cURL
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

Get screenshot job status

/screenshots/{jobId}

Returns the current status and results of a screenshot job.

Parameters

  • jobId in path required

Responses

  • 200 Screenshot job details
  • 404 Job not found
cURL
curl \
  https://app.drip-apex.com/api/v1/screenshots/job_123 \
  -H "Authorization: Bearer <apex-secret-key>"

Webhooks

GET

List webhooks

/webhooks

Returns all webhooks for the shop.

Parameters

  • include_archived in query - Include archived webhooks.

Responses

  • 200 List of webhooks
  • 401 Unauthorized
cURL
curl \
  https://app.drip-apex.com/api/v1/webhooks \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 201 Webhook created
  • 400 Validation error
cURL
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

Get webhook

/webhooks/{id}

Parameters

  • id in path required

Responses

  • 200 Webhook
  • 404 Webhook not found
cURL
curl \
  https://app.drip-apex.com/api/v1/webhooks/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update webhook

/webhooks/{id}

Parameters

  • id in path required

Request body

{
  url?: string (uri)
  events?: string[]
  active?: boolean
}

Responses

  • 200 Webhook
  • 404 Webhook not found
cURL
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
}'
DELETE

Archive webhook

/webhooks/{id}

Archives a webhook registration while retaining delivery history.

Parameters

  • id in path required

Responses

  • 200 Webhook deleted
  • 404 Webhook not found
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/webhooks/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Restore webhook

/webhooks/{id}/restore

Parameters

  • id in path required

Responses

  • 200 Restored webhook
  • 404 Webhook not found
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/webhooks/exp_123/restore \
  -H "Authorization: Bearer <apex-secret-key>"
GET

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

  • id in path required
  • status in query
  • limit in query

Responses

  • 200 List of webhook delivery attempts
  • 404 Webhook not found
cURL
curl \
  https://app.drip-apex.com/api/v1/webhooks/exp_123/deliveries \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Send test webhook

/webhooks/{id}/test

Sends a signed test event and records the delivery.

Parameters

  • id in path required

Responses

  • 200 Test delivery
  • 404 Webhook not found
  • 409 Webhook is inactive
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/webhooks/exp_123/test \
  -H "Authorization: Bearer <apex-secret-key>"

Audit logs

GET

List audit logs

/audit-logs

Parameters

  • entity_type in query
  • entity_id in query
  • limit in query
  • offset in query

Responses

  • 200 Audit log page
  • 403
cURL
curl \
  https://app.drip-apex.com/api/v1/audit-logs \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List audit logs for an authorized shop with a user API key

/shops/{id}/audit-logs

Parameters

  • entity_type in query
  • entity_id in query
  • limit in query
  • offset in query

Responses

  • 200 Audit log page
  • 403
  • 404
cURL
curl \
  https://app.drip-apex.com/api/v1/shops/exp_123/audit-logs \
  -H "Authorization: Bearer <apex-secret-key>"

Inbox

GET

List inbox messages

/inbox/messages

Parameters

  • experiment_id in query

Responses

  • 200 Inbox messages
  • 403
cURL
curl \
  https://app.drip-apex.com/api/v1/inbox/messages \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Send an inbox message

/inbox/messages

Request body

{
  thread_type?: "account" | "experiment"
  experiment_id?: string,null (uuid)
  body: string
}

Responses

  • 201 Message created
  • 400
  • 403
  • 404
cURL
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"
}'
POST

Mark inbox channels read

/inbox/read-state

Request body

unknown

Responses

  • 200 Read state updated
  • 400
  • 403
  • 404
cURL
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

Get the credential organization

/org

Responses

  • 200 Dashboard organization detail shape, including a `members` array (id, userId, email, role, defaultShopRole, createdAt) and `_count.members`.
  • 401
  • 403
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/org \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

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

  • 200 Updated organization
  • 401
  • 403
  • 429
  • 503
cURL
curl -X PATCH \
  https://app.drip-apex.com/api/v1/org \
  -H "Authorization: Bearer <apex-secret-key>" \
  -H "Content-Type: application/json" \
  -d '{}'
GET

List organization members

/org/members

Responses

  • 200 Members from the dashboard member source
  • 401
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/org/members \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List organization invitations

/org/invitations

Responses

  • 200 Pending invitations
  • 401
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/org/invitations \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Invite an organization member

/org/invitations

Request body

{
  email: string (email)
  org_role?: "admin" | "member"
  default_shop_role?: "admin" | "editor" | "analyst" | "viewer"
}

Responses

  • 201 Invitation created
  • 401
  • 429
  • 503
cURL
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"
}'
DELETE

Revoke an organization invitation

/org/invitations/{id}

Parameters

  • id in path required

Responses

  • 200 Invitation revoked
  • 401
  • 404
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/org/invitations/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update an organization member

/org/members/{id}

Parameters

  • id in path required

Request body

{
  role?: string
  default_shop_role?: string
}

Responses

  • 200 Member updated
  • 401
  • 429
  • 503
cURL
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"
}'
DELETE

Remove an organization member

/org/members/{id}

Parameters

  • id in path required

Responses

  • 200 Member removed
  • 401
  • 429
  • 503
cURL
curl -X DELETE \
  https://app.drip-apex.com/api/v1/org/members/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"

Team

GET

List shop team members

/team/members

Parameters

  • shop_id in query required

Responses

  • 200 Team members
  • 401
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/team/members \
  -H "Authorization: Bearer <apex-secret-key>"
GET

List shop invitations

/team/invitations

Parameters

  • shop_id in query required

Responses

  • 200 Invitations
  • 401
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/team/invitations \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Invite a shop member

/team/invitations

Request body

{
  email: string (email)
  role: string
  shop_id: string (uuid)
}

Responses

  • 201 Invitation created
  • 401
  • 429
  • 503
cURL
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"
}'
DELETE

Revoke a shop invitation

/team/invitations/{id}

Parameters

  • id in path required

Request body

{
  shop_id: string (uuid)
}

Responses

  • 200 Invitation revoked
  • 401
  • 429
  • 503
cURL
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"
}'
PATCH

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

  • 200 Member updated
  • 401
  • 429
  • 503
cURL
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": {}
}'
DELETE

Remove a shop member

/team/members/{id}

Request body

{
  shop_id: string (uuid)
}

Responses

  • 200 Member removed
  • 401
  • 429
  • 503
cURL
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

GET

List organization shops

/shops

Responses

  • 200 Shop list
cURL
curl \
  https://app.drip-apex.com/api/v1/shops \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • 201 Shop created
  • 403
  • 409 The domain already has a live binding. Owner details are included only when the caller may see the owning shop.
cURL
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

Get a shop

/shops/{id}

Responses

  • 200 Shop detail
  • 404
cURL
curl \
  https://app.drip-apex.com/api/v1/shops/exp_123 \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

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

  • 200 Shop updated
  • 403
cURL
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 '{}'
POST

Pre-bind a Shopware store to an Apex shop

/shops/{id}/shopware/prebind

Request body

{
  shopUrl: string (uri)
  environmentKey?: string = "production"
}

Responses

  • 200 Existing binding returned
  • 201 Pending binding created
  • 400
  • 401
  • 403
  • 409
  • 429
  • 503
cURL
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

Get auto-stop settings

/shops/{id}/auto-stop

Responses

  • 200 Settings
cURL
curl \
  https://app.drip-apex.com/api/v1/shops/exp_123/auto-stop \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

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

  • 200 Settings updated
cURL
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

Get testing-defaults settings

/shops/{id}/testing-defaults

Responses

  • 200 Settings
cURL
curl \
  https://app.drip-apex.com/api/v1/shops/exp_123/testing-defaults \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update testing-defaults settings

/shops/{id}/testing-defaults

Request body

{
  significanceLevel?: number
  statisticalPower?: number
  sequentialTestingEnabled?: boolean
}

Responses

  • 200 Settings updated
cURL
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

Get guardian settings

/shops/{id}/guardian

Responses

  • 200 Settings
cURL
curl \
  https://app.drip-apex.com/api/v1/shops/exp_123/guardian \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

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

  • 200 Settings updated
cURL
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

Get the store profile

/shops/{id}/store-profile

Responses

  • 200 The 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.
  • 503 Store profile temporarily unavailable (database under pressure); retry shortly.
cURL
curl \
  https://app.drip-apex.com/api/v1/shops/exp_123/store-profile \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Review a store-profile fact

/shops/{id}/store-profile/facts/{factId}

Request body

{
  status: "suggested" | "confirmed" | "rejected" | "stale"
  claim?: string
  value?: any
}

Responses

  • 200 Fact reviewed
cURL
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"
}'
POST

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

  • 200 Finding reviewed
cURL
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"
}'
POST

Start a store-profile learning run

/shops/{id}/store-profile/learning-runs

Request body

{
  trigger?: string = "manual"
  sources?: string[]
  scope?: string[]
}

Responses

  • 201 Learning run queued
cURL
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

Get engine state and guardrails

/shops/{id}/engine

Parameters

  • id in path required

Responses

  • 200 Engine state
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/shops/exp_123/engine \
  -H "Authorization: Bearer <apex-secret-key>"
GET

Get engine guardrails

/shops/{id}/engine/guardrails

Parameters

  • id in path required

Responses

  • 200 Engine guardrails
  • 400
  • 401
  • 403
  • 404
  • 429
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/shops/exp_123/engine/guardrails \
  -H "Authorization: Bearer <apex-secret-key>"
PATCH

Update engine guardrails with optimistic concurrency

/shops/{id}/engine/guardrails

Parameters

  • id in path required

Request body

{
  expected_version: integer
  allow?: object
  auto_launch?: object
  surfaces?: object
  segments?: any
  max_concurrent?: integer
  max_per_page?: integer
}

Responses

  • 200 Updated engine guardrails
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
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
}'
POST

Start engine

/shops/{id}/engine/start

Parameters

  • id in path required

Responses

  • 200 Engine state updated
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/shops/exp_123/engine/start \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Pause engine

/shops/{id}/engine/pause

Parameters

  • id in path required

Responses

  • 200 Engine state updated
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/shops/exp_123/engine/pause \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Stop engine

/shops/{id}/engine/stop

Parameters

  • id in path required

Responses

  • 200 Engine state updated
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/shops/exp_123/engine/stop \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Approve engine proposal

/shops/{id}/engine/proposals/{pid}/approve

Parameters

  • id in path required
  • pid in path required

Responses

  • 200 Engine proposal approve decision recorded
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/shops/exp_123/engine/proposals/p_123/approve \
  -H "Authorization: Bearer <apex-secret-key>"
POST

Reject engine proposal

/shops/{id}/engine/proposals/{pid}/reject

Parameters

  • id in path required
  • pid in path required

Request body

{
  reason: string
}

Responses

  • 200 Engine proposal reject decision recorded
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
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"
}'
POST

Veto engine proposal

/shops/{id}/engine/proposals/{pid}/veto

Parameters

  • id in path required
  • pid in path required

Responses

  • 200 Engine proposal veto decision recorded
  • 400
  • 401
  • 403
  • 404
  • 409
  • 422
  • 429
  • 503
cURL
curl -X POST \
  https://app.drip-apex.com/api/v1/shops/exp_123/engine/proposals/p_123/veto \
  -H "Authorization: Bearer <apex-secret-key>"
POST

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

  • id in path required
  • iid in path required

Request body

{
  expected_updated_at: string (date-time)
}

Responses

  • 200 Engine intervention rolled out
  • 400
  • 401
  • 403
  • 404
  • 409 Rollout refused
  • 422
  • 429
  • 503 Either 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
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

GET

Run funnel analysis

/funnels/{id}/run

Responses

  • 200 Funnel run
  • 400
  • 401
  • 403
  • 404
  • 429
  • 502 Analysis unavailable
  • 503
cURL
curl \
  https://app.drip-apex.com/api/v1/funnels/exp_123/run \
  -H "Authorization: Bearer <apex-secret-key>"