Quickstart
This API surface is for integration partners building on top of the Rokt network. Rokt ecommerce partners integrating placements on their own checkout should use the Rokt Ecommerce developer docs instead.
This walkthrough takes you from zero to a registered merchant with verified controls and an active partnership — using dry_run=true so nothing persists. Drop the dry-run flag when you're ready to go live.
You'll need an API token and a terminal.
Before you startLien direct vers Before you start
Gather the following before running the calls below. Each one will be referenced by name in the steps that follow.
- API token — obtained via the white-glove onboarding channel. See Authentication.
- Partner platform's Rokt parent account ID — your platform's top-level account in Rokt's hierarchy. Your Rokt onboarding contact provides this.
- Rokt
vertical_id+sub_vertical_id— the canonical Rokt taxonomy values for the merchant. See Vertical taxonomy. - Store URL with scheme — e.g.
https://acme.myshopify.com. Bare hosts (acme.myshopify.com) are rejected with 400. - A stable
external_account_id— your platform's own identifier for this merchant. Register is idempotent on this value, so it must be stable across retries. uuidgen(or any UUID generator) — for producing freshIdempotency-Keyvalues on writes.
Two contracts every call follows.
- Every response is wrapped in
{ "status", "error", "message", "request_id", "data": { ... } }. Endpoint-specific payloads live insidedata. Examples below show the full envelope. - Every write needs
X-Platform-Parent-Account-Idset to your partner platform's Rokt parent account ID. Missing it returns422on writes. Reads accept it as optional but recommended.
Export both:
# Replace with YOUR partner platform's Rokt parent account ID (obtained from your Rokt onboarding contact).
export PARENT="<your-platform-parent-account-id>"
- Get your API token
If you don't already have one, see Authentication. For the rest of this guide, export it:
- bash
export TOKEN="eyJhbGc..." - Register a merchant
POST /v1/accounts/register/partnershipcreates (or matches) a Rokt account for a merchant onboarded via your platform. The call is idempotent onexternal_account_id— your stable identifier for the merchant in your own system.store_identifiermust be a valid URL (3–400 chars) including the scheme.https://acme.myshopify.comworks;acme.myshopify.comreturns 400.Capture
data.account_idfrom the response. You'll use it in every subsequent call. If you also passedpages, capture each entry'spage_identifier— you'll pass that string into the Web SDK'sselectPlacementscall to target each surface. See Pages and Layouts.remarqueregisteris the one write that does not require anIdempotency-Keyheader — it's idempotent onexternal_account_idinstead. All subsequent writes (controls, status, payout-setup, etc.) requireIdempotency-Key.- curl
# pages[].surface: confirmation | tracking | returns
# pages[].layout_type: Overlay | Embedded
# Every integration ships a default — omit `pages` to use it, or pass an array to override. See pages-and-layouts.
curl -X POST https://accounts.rokt.com/v1/accounts/register/partnership \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT" \
-H "Content-Type: application/json" \
-d '{
"brand": "Acme Apparel",
"vertical_id": 1500,
"sub_vertical_id": 1610,
"country_code": "US",
"platform_parent_account_id": "<your-platform-parent-account-id>",
"store_identifier": "https://acme-apparel.example.com",
"external_account_id": "partner-merchant-abc123",
"pages": [
{ "surface": "confirmation", "layout_type": "Overlay" },
{ "surface": "tracking", "layout_type": "Embedded" },
{ "surface": "returns", "layout_type": "Embedded" }
]
}'Response:
{
"status": 200,
"error": null,
"message": "ok",
"request_id": "0e3a1b9c-1234-4abc-9def-aaaabbbbcccc",
"data": {
"account_id": "<your-account-id>",
"pages": [
{ "surface": "confirmation", "page_id": "bfb5b9be-...", "layout_id": "9d11d8aa-...", "page_identifier": "confirmation_page" },
{ "surface": "tracking", "page_id": "2b9d8a5e-...", "layout_id": "f8700369-...", "page_identifier": "tracking_page" },
{ "surface": "returns", "page_id": "7a31963a-...", "layout_id": "4865f1ab-...", "page_identifier": "returns_page" }
]
}
}astuceExport it:
export ACCOUNT_ID="<your-account-id>".Auth-propagation race — retry with backoffToken authentication for newly-created merchant accounts propagates asynchronously. Immediate calls to controls, status, or payout-setup endpoints on the new
account_idcan return401or403for up to 1–2 minutes. Don't treat the first auth failure as terminal — retry with backoff:for attempt in 1 2 3 4 5; do
HTTP_CODE=$(curl -s -w "%{http_code}" -o /tmp/resp.json \
"https://accounts.rokt.com/v1/partnership/accounts/$ACCOUNT_ID/marketplacecontrolslists" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT")
if [[ "$HTTP_CODE" != "401" && "$HTTP_CODE" != "403" ]]; then break; fi
sleep $((attempt * 15))
done - Read current marketplace controls
GET /v1/partnership/accounts/{account_id}/marketplacecontrolslistsreturns the merchant's current marketplace control configuration. On a fresh account, this reflects the default vertical block list inherited from your partnership preset.- curl
curl https://accounts.rokt.com/v1/partnership/accounts/$ACCOUNT_ID/marketplacecontrolslists \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT"Look at
data.verticals,data.translatedVerticals, anddata.contentHash.translatedVerticalsshows the same blocks expressed in your partner taxonomy — useful for round-tripping back to your UI. - Update marketplace controls (dry-run)
PUTis desired-state — send the full list every time, anything you omit becomes unblocked. See SET semantics.X-Platform-Parent-Account-Idis required on all writes — missing it returns 422.Idempotency-Keyis required on all writes. Generate a fresh UUID per logical retry group. The 24-hour dedup window collapses retries with the same key into a single execution.dry_run=trueruns the full validation without persisting state — perfect for validating a payload. The response envelope addsdry_run: truealongsidedata.
- curl
curl -X PUT "https://accounts.rokt.com/v1/partnership/accounts/$ACCOUNT_ID/marketplacecontrolslists?dry_run=true" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "Acme Network Controls",
"blockedVerticals": [
{
"partnerVerticalId": 1500,
"partnerSubVerticalId": 1610,
"policy": "Block",
"position1Policy": "Block"
},
{
"partnerVerticalId": 1500,
"partnerSubVerticalId": 1611,
"policy": "Block",
"position1Policy": "Block"
}
],
"domains": [
{ "domain": "competitor.example.com", "policy": "Block" }
],
"contentHash": null
}'The response payload (inside
data) matchesGET— sameverticals,translatedVerticals,domains, and a freshcontentHash. On dry-run, the response describes what would be written. - Activate the partnership (dry-run)
PUT /v1/partnership/accounts/{account_id}/statuscascades active/paused across every non-archived page variant on the account.- curl
curl -X PUT "https://accounts.rokt.com/v1/partnership/accounts/$ACCOUNT_ID/status?dry_run=true" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "status": "active" }'Response
data.variants[]lists the per-variant breakdown:{
"status": 200,
"error": null,
"message": "ok",
"request_id": "0e3a1b9c-...",
"data": {
"accountId": "<your-account-id>",
"status": "active",
"variants": [
{ "pageVariantId": "bfb5b9be-...", "pageId": "9d11...", "name": "Thanks", "status": "active" }
]
}
} - Verify status
GET /v1/partnership/accounts/{account_id}/statusreturns the aggregate status plus the per-variant detail.- curl
curl https://accounts.rokt.com/v1/partnership/accounts/$ACCOUNT_ID/status \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT"In production (drop
dry_run=true),data.statusshould match what you justPUT. If you see"mixed"after aPUT status=active, some variants failed to update — capture therequest_idand file a support ticket.The aggregation rule:
"active"— every non-archived variant is enabled."paused"— every non-archived variant is disabled (or none exist)."mixed"— some enabled, some disabled.
Next stepsLien direct vers Next steps
Start here:
Then: