Skip to main content
Use TypeScript SDK 0.20.0 or Python SDK 0.15.0 with an authorized organization API key. Computer executions use their injected current-user credentials. Both SDKs call the same campaign and promotion domain services as the application; browser cookies and internal application routes are unnecessary.

Choose the executing approver

campaigns.getOptions() / campaigns.get_options() returns actorId, eligible campaign actors in members, and exact connected stores. An organization API key acts as oauth:<clientId>. Explicitly name that eligible actor in a new campaign’s brief.ownerId and brief.approverId for headless approval. A key cannot approve on behalf of a named human. Current grants and named-approver checks remain enforced. Do not change an existing approver without authorization.

Import Excel

Upload the workbook with documents.upload and retain upload.data.document.id. Call campaigns.importBriefs({documentIds, preview: true}) or Python campaigns.import_briefs(document_ids=document_ids, preview=True). Inspect every warning and issue before repeating with preview=false to save. Owner/approver default to the executing actor. Supply exact connected stores when the workbook needs disambiguation. Uploading requires documents:write; importing requires documents:read and promotions:write. Re-upload one document with campaignId to update a campaign. Existing running campaigns receive a pending proposal, preserving their current execution.

Approve and run now with Full sync

These examples assume an authenticated client and the authorized saved campaignIds / campaign_ids. Validation returns a proposed shifted plan; saving it creates the revision that the named approver starts. The date shift preserves window/offer durations and relative gaps. Marketplace lead times still apply. Full sync prepares all eligible offers at campaign start; later windows retain their later sale dates.

TypeScript / JavaScript

Python

Python AsyncOmni exposes the same methods with await. Union-payload validators take a body dictionary with camelCase wire keys; other keyword arguments use snake_case.

Campaign controls

Lifecycle batches accept one action and 1–20 {campaignId, expectedRevision, expectedPendingVersion?} targets: approve, run, approve_and_run, end, resume, retry, approve_change, discard_change, archive, restore, or delete. Live-change decisions require the reviewed pending version. Duplicates run once, conflicting versions are rejected, and per-target failures remain explicit. Read every returned campaign ID with campaigns.get. Check executions, progress, failed/pending schedules and cleanup. A successful start means durable work was queued; it does not prove marketplace success. Ending starts cleanup. Resume is available only for eligible untouched future windows after cleanup; completed windows require a new campaign. Personal notification preferences require a member credential; API clients monitor campaign status and configured event workflows.

Promotion controls

Use promotions.getCapabilities() / get_capabilities() for every canonical marketplace and promotion kind, voucher subtypes and concrete unsupported limitations. Validate saved IDs or proposed definitions/products with promotions.validate (Python: body={...}). This catches canonical marketplace terms and targeting issues before publishing; provider-time rejections can still occur. Create drafts with promotions.create and status: "draft", assign qualifying products with addProducts / add_products, and publish with setStatuses({promotionIds, targetStatus: "active"}) / set_statuses(promotion_ids=..., target_status="active"). createBatch / create_batch creates promotions with products using the flat write contract; explicitly set promotion.status="draft" when preparing drafts, because the canonical batch creation flow otherwise activates them. Use update for changes, preview for effective prices, getProductOptions / get_product_options for eligibility, and listProducts/removeProducts (Python snake_case) for assignments. Pause/archive through setStatuses; delete through deleteBatch / delete_batch. Status and deletion batches accept up to 500 IDs. Read getDelivery({promotionIds}) / get_delivery(promotion_ids=...) for up to 50 IDs and inspect every exact store’s deliveryStatuses, errors and unavailable/unsupported states. retry returns durable job/correlation IDs: await all returned IDs and re-read delivery. Retain saved IDs after partial failures and retry those IDs instead of creating duplicates. See the generated API reference for canonical input bounds and schemas.

Apply an updated campaign workbook immediately

Change the discount value in its promotion row or remove qualifying SKU rows from Prices / Promotion Items. Products is a reference sheet, so deleting a reference row alone does not unassign a product. Removing the final qualifying row stops that offer. An omitted sheet preserves its existing membership; an unresolved SKU blocks the update.
Python uses apply_changes=True, expected_revision=review["revision"], and expected_pending_version=review["pendingChangeVersion"] in campaigns.import_briefs. A null pending version is explicit None. The named approver must have current publish permission. The server validates marketplace edit rules, saves the proposal, approves that exact version and queues durable sync immediately. Default uploads remain proposals. Closed windows and marketplace fields that cannot change live return validation errors before applying. A saved proposal remains identifiable if approval fails. applied:true means the approved revision committed. Inspect scheduling and campaign execution/delivery results to confirm every marketplace change. The API does not claim delivery success merely because work was queued.