Skip to main content
Upload and manage creative assets in a creative library. Supports bulk uploads, upsert semantics, and generative creatives. Implemented by any agent that hosts a creative library — creative agents (ad servers, creative management platforms) and sales agents that manage creatives. Response time: Instant to days (returns completed, or submitted for review that takes hours/days) Request Schema: creative/sync-creatives-request.json Response Schema: creative/sync-creatives-response.json

Quick start

Upload creative assets:
Note: Per-creative async review is surfaced via creatives[].status (e.g., pending_review) on the synchronous success response. When the whole operation is queued (batch ingestion, governance review gating the sync), the response is a submitted envelope with top-level status: "submitted" and a task_id. See Async approval workflow.

Request parameters

Creative object

Asset structure

Assets are keyed by role name. Each role contains the asset details:
test=false

Assignments structure

Assignments are at the request level, mapping creative IDs to package IDs. Standalone creative agents that do not manage media buys ignore this field.
test=false

Response

Responses use discriminated unions — a response has exactly one of three shapes, never mixed: 1. Synchronous success — per-creative results:
  • creatives - Results for each creative processed (includes both successful and failed items)
  • dry_run - Boolean indicating if this was a dry run (optional)
2. Terminal error — no creatives processed:
  • errors - Array of operation-level errors (auth failure, service unavailable)
3. Submitted task envelope — whole operation queued asynchronously (batch ingestion, governance review gating the sync):
  • status - Always "submitted"
  • task_id - Handle for polling via tasks/get or receiving a webhook on completion
  • message - Optional human-readable explanation of the queue state
The final per-creative creatives array lands on the task completion artifact, not on the submitted envelope. Per-item async review (one creative in pending_review while the rest of the sync resolves synchronously) belongs on the synchronous success branch with status: "pending_review" on that item, not here. Each creative in the success response includes:
  • All request fields
  • platform_id - Platform’s internal ID (when action is not failed)
  • action - Lifecycle operation performed by this sync: created, updated, unchanged, failed, deleted
  • status - Advisory review-lifecycle state (CreativeStatus): processing, pending_review, approved, rejected, archived. A UI hint and polling-scheduling signal — not a spend-authorization gate. Orthogonal to action — action describes what the sync did, status describes where the creative is in the review lifecycle. Values come from CreativeStatus only, never from CreativeAction (never put created/updated/failed in status). Sellers with async review return processing or pending_review; sellers with synchronous review MAY return a terminal value (approved/rejected). Buyers MUST NOT gate downstream spend or package activation on status: approved from this response — reconcile via list_creatives or a signed review webhook before committing spend. Authoritative state is always via list_creatives. MUST be omitted when action is failed or deleted — failed items have no meaningful review state (see errors); deleted items are gone from the library. The schema enforces the omission rule via a conditional constraint.
  • errors - Array of error messages (only when action: "failed")
  • warnings - Array of non-fatal warnings (optional)
See schema for complete field list: sync-creatives-response.json

Common scenarios

Bulk upload

Upload multiple creatives in one call:

Generative creatives

Use the creative agent to generate creatives from brand identity data. See the Generative Creatives guide for complete workflow details.

Dry run validation

Validate creative configuration without uploading:

Scoped update with creative_ids filter

Update only specific creatives from a large library without affecting others:
Why use creative_ids filter:
  • Scoped updates: Only specified creatives modified, even with 100+ in library
  • Error recovery: Retry only failed creatives after bulk sync validation failures
  • Performance: Publisher can optimize processing when scope is known upfront
  • Safety: Explicit targeting reduces risk of unintended changes

Async approval workflow

Two distinct async patterns — match the right one to the agent’s behavior: Per-creative async review (common): the sync operation itself resolves synchronously, but one or more creatives require downstream review (brand safety, policy compliance). Items in review come back on the synchronous success response with status: "pending_review" (or processing during ingestion). The buyer reconciles terminal state via list_creatives or a webhook. Operation-level async (less common): the whole sync is queued — the seller cannot return any per-item results before responding, because ingestion is batched or governance review gates the entire sync. The response is a submitted envelope:
  • Top-level status: "submitted" with task_id
  • message — optional human-readable explanation
  • No creatives array on this envelope
Poll tasks/get or wait for the webhook. The completion artifact carries the creatives array with per-item action/status results; operation-level failures surface as status: "failed" on the task. See: Webhooks for webhook configuration.

Sync modes

Upsert (default)

  • Creates new creatives or updates existing by creative_id
  • Merges package assignments (additive)
  • Updates provided fields, leaves others unchanged
  • Use creative_ids filter to limit scope to specific creatives

Dry run

  • Validates request without making changes
  • Returns errors and warnings
  • Does not process assets or create creatives
  • Use for pre-flight validation checks

Error handling

Best practices

  1. Use upsert semantics - Same creative_id updates existing creative rather than creating duplicates. This allows iterative creative development. Note: updates are blocked for creatives in active delivery (see #7).
  2. Validate first - Use dry_run: true to catch errors before actual upload. This saves bandwidth and processing time.
  3. Batch assignments - Include all package assignments in single sync call to avoid race conditions between updates.
  4. CDN-hosted assets - Use publicly accessible CDN URLs for faster processing. Platforms can fetch assets directly without proxy delays.
  5. Brand identity - For generative creatives, validate brand identity schema before syncing to avoid processing failures.
  6. Check format support - Use list_creative_formats to verify product supports your creative formats before uploading.
  7. Active delivery protection - Creatives assigned to active, non-paused packages cannot be updated or deleted via delete_missing. Pause the package first, unassign the creative via update_media_buy, or create a new creative with a different creative_id.