メインコンテンツまでスキップ

Updating Marketplace Controls

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 recipe covers ongoing edits to marketplace controls on an already-onboarded merchant. The pattern is: GET, modify locally, PUT the full result.

警告

PUT replaces full state. Controls endpoints (MCL, status) use PUT-replace — there's no PATCH or merge on this surface. Always GET first, modify locally, and PUT the modified full list. Anything you omit from the PUT becomes unblocked. The layout-edit endpoint (PATCH /v1/partnership/accounts/{id}/layouts/{layout_id}) is the one PATCH endpoint in the partnership API — it does not apply to controls. See SET Semantics.

  1. GET the current state

    Fetch the current MCL and capture the contentHash for optimistic concurrency in step 3.

    curl https://accounts.rokt.com/v1/partnership/accounts/<your-account-id>/marketplacecontrolslists \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Platform-Parent-Account-Id: $PARENT"
    {
    "status": 200,
    "error": null,
    "message": "ok",
    "request_id": "0e3a1b9c-...",
    "data": {
    "accountId": "<your-account-id>",
    "marketplaceControlsListId": "8c6f2a1e-...",
    "name": "Acme Network Controls",
    "verticals": [ /* current blocks in Rokt taxonomy */ ],
    "translatedVerticals": [ /* same list in partner taxonomy */ ],
    "domains": [ { "domain": "competitor.example.com", "policy": "Block" } ],
    "contentHash": "v7-1a9e3f4c"
    }
    }
  2. Modify locally

    Append a new blocked vertical while preserving everything you already had. Build the request body off the GET response's translatedVerticals.

    const envelope = await getMcl(accountId); // GET above
    const current = envelope.data; // unwrap the envelope

    const next = {
    name: current.name,
    blockedVerticals: [
    ...current.translatedVerticals.map(v => ({
    partnerVerticalId: v.partner_vertical_id,
    partnerSubVerticalId: v.partner_sub_vertical_id,
    policy: "Block",
    position1Policy: "Block",
    })),
    // append the new one
    { partnerVerticalId: 1500, partnerSubVerticalId: 1612, policy: "Block", position1Policy: "Block" },
    ],
    domains: current.domains,
    contentHash: current.contentHash, // pass back for optimistic concurrency
    };
  3. PUT the modified list

    Send the full desired state. Include contentHash so the server can reject the write if anyone else updated the row between your GET and your PUT.

    curl -X PUT https://accounts.rokt.com/v1/partnership/accounts/<your-account-id>/marketplacecontrolslists \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Platform-Parent-Account-Id: $PARENT" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d @next.json

    If the server returns a contentHash error, someone modified the row between your GET and PUT. Re-GET, re-apply your change to the fresh state, and retry. See Idempotency Keys for why you can safely retry with the same key.

    注記

    End-to-end stale-hash rejection is preview-grade — verified through the schema but not yet observed live on this partner surface. Treat the 409 path as best-effort until GA.

  4. Optionally dry-run first

    Append ?dry_run=true to validate the payload — full validation and taxonomy translation — without committing. No state is persisted.

    curl -X PUT 'https://accounts.rokt.com/v1/partnership/accounts/<your-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 @next.json
    注記

    When you re-call without dry_run for the real write, use a fresh Idempotency-Key. The dry-run key is now cached. See Dry-Run Mode.

  5. Verify

    GET again and confirm the new vertical is present, your previous blocks are still there, and domains is unchanged.

    curl https://accounts.rokt.com/v1/partnership/accounts/<your-account-id>/marketplacecontrolslists \
    -H "Authorization: Bearer $TOKEN" \
    -H "X-Platform-Parent-Account-Id: $PARENT"

Common gotchasCommon gotchas への直接リンク

I sent one new vertical and lost all my previous blocks

SET semantics. PUT is desired-state, not a patch. Always GET-modify-PUT the full list. There is no merge on the server. If you only send [{ vertical: 1612 }], you've told the server "1612 is the entire list" and unblocked everything else.

PUT returns 409 with a contentHash error

Someone else (or another instance of your service) modified the row between your GET and your PUT. The contentHash you sent no longer matches the server's current state.

Resolution: re-GET, re-apply your change to the fresh state, and retry the PUT. You can keep the same Idempotency-Key — the server will treat the new payload as a new operation because the prior attempt was rejected, not committed.

Server returns 400 — 'no partnership vertical mapping'

Your partner-taxonomy partnerVerticalId / partnerSubVerticalId pair isn't in Rokt's vertical mapping table. The PUT is rejected atomically — no partial writes.

Resolution: email smb-partnerships@rokt.com with the unmapped IDs and we'll add the row. In the meantime, omit the unmapped vertical from your PUT.

I want to clear all blocks

Send blockedVerticals: [] and domains: []. The server treats an empty array as "no blocks" — that's the SET semantics fixed point.

この記事は役に立ちましたか?
Last updated Jun 8, 2026