Skip to main content

Quickstart

Audience

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 startDirect link to 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 fresh Idempotency-Key values on writes.
note

Two contracts every call follows.

  1. Every response is wrapped in { "status", "error", "message", "request_id", "data": { ... } }. Endpoint-specific payloads live inside data. Examples below show the full envelope.
  2. Every write needs X-Platform-Parent-Account-Id set to your partner platform's Rokt parent account ID. Missing it returns 422 on 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>"
  1. Get your API token

    If you don't already have one, see Authentication. For the rest of this guide, export it:

    export TOKEN="eyJhbGc..."
  2. Register a merchant

    POST /v1/accounts/register/partnership creates (or matches) a Rokt account for a merchant onboarded via your platform. The call is idempotent on external_account_id — your stable identifier for the merchant in your own system.

    store_identifier must be a valid URL (3–400 chars) including the scheme. https://acme.myshopify.com works; acme.myshopify.com returns 400.

    Capture data.account_id from the response. You'll use it in every subsequent call. If you also passed pages, capture each entry's page_identifier — you'll pass that string into the Web SDK's selectPlacements call to target each surface. See Pages and Layouts.

    note

    register is the one write that does not require an Idempotency-Key header — it's idempotent on external_account_id instead. All subsequent writes (controls, status, payout-setup, etc.) require Idempotency-Key.

    # 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" }
    ]
    }
    }
    tip

    Export it: export ACCOUNT_ID="<your-account-id>".

    Auth-propagation race — retry with backoff

    Token authentication for newly-created merchant accounts propagates asynchronously. Immediate calls to controls, status, or payout-setup endpoints on the new account_id can return 401 or 403 for 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
  3. Read current marketplace controls

    GET /v1/partnership/accounts/{account_id}/marketplacecontrolslists returns the merchant's current marketplace control configuration. On a fresh account, this reflects the default vertical block list inherited from your partnership preset.

    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, and data.contentHash. translatedVerticals shows the same blocks expressed in your partner taxonomy — useful for round-tripping back to your UI.

  4. Update marketplace controls (dry-run)

    PUT is desired-state — send the full list every time, anything you omit becomes unblocked. See SET semantics.

    • X-Platform-Parent-Account-Id is required on all writes — missing it returns 422.
    • Idempotency-Key is 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=true runs the full validation without persisting state — perfect for validating a payload. The response envelope adds dry_run: true alongside data.
    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) matches GET — same verticals, translatedVerticals, domains, and a fresh contentHash. On dry-run, the response describes what would be written.

  5. Activate the partnership (dry-run)

    PUT /v1/partnership/accounts/{account_id}/status cascades active/paused across every non-archived page variant on the account.

    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" }
    ]
    }
    }
  6. Verify status

    GET /v1/partnership/accounts/{account_id}/status returns the aggregate status plus the per-variant detail.

    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.status should match what you just PUT. If you see "mixed" after a PUT status=active, some variants failed to update — capture the request_id and 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 stepsDirect link to Next steps

Start here:

Then:

Was this article helpful?
Last updated Jun 8, 2026