Skip to main content

Overview

Data Delivery is a standing subscription that pushes log-level data (LLD) from Scope3 into a destination you own — your cloud storage, your IAM, your data pipeline. Unlike /api/v2/buyer/reporting/metrics (which returns aggregates synchronously), Data Delivery runs on a schedule, writes objects, and never makes you pull. Two objects make it work, both scoped to an advertiser: Available data types: MB_DELIVERY, IMPRESSIONS, CLICKS, VAST_EVENTS, CAPI_ATTRIBUTION, MMP_POSTBACKS. Cadences: HOURLY (minute 0), DAILY (00:00 UTC), WEEKLY (00:00 UTC on syncWeeklyDay). Formats: JSONL, PARQUET, CSV. Limits: up to 20 credentials and 20 Outputs per advertiser. One Output per (dataDeliveryType, credentialName) pair per scope — to fan a data type out to two destinations, list one Output per destination.

End-to-end shape

The high-level flow is the same regardless of destination:
1

Grant Scope3 access on your cloud

Add a bucket/container that Scope3 can write into and grant the Scope3 principal the required permissions. Details per destination below.
2

Register the credential

PUT /advertisers/:advertiserId with a dataDelivery.credentials[] entry. The credential lands as status: PENDING.
3

Wait for the Probe

Scope3 asynchronously writes a sentinel object under _scope3-probe/ and deletes it. The credential flips to VALIDATED on success or FAILED (with statusError) on failure.
4

Attach Outputs

PUT /advertisers/:advertiserId with dataDelivery.outputs[] referencing the credential by credentialName. Optionally override per campaign via PUT /campaigns/:campaignId dataDelivery.outputs[].
5

Receive data on the cadence

Each Output fires on its schedule and lands objects under <destination>/<pathPrefix>/.... Open the bucket/container to confirm.
dataDelivery.credentials and dataDelivery.outputs are full-replace arrays. The request body is the new desired state — anything not listed is archived (credentials) or cleared (Outputs). Read the current state with GET /advertisers/:advertiserId before writing. A credential cannot be archived while any live Output (advertiser- or campaign-scoped) still references it — remove or repoint the Output first.

Destination setup

1. Grant access on your bucket

Scope3 authenticates to GCS with a single service account. Grant it roles/storage.objectCreator on the bucket you want data shipped into. No keys or secrets are exchanged.Scope3 service account:
Grant via gcloud:

2. Register the credential

name must be unique among live credentials on this advertiser. Outputs will reference it by this name.

Probe lifecycle

When a credential is created or its config changes, Scope3 kicks off an async Probe workflow keyed on the credential. The Probe writes a sentinel object to the destination, deletes it, and updates the credential row: Check status with:
Re-run the Probe without re-submitting the credential:
Outputs can reference a credential in any status. The shipping workflow re-checks at run time, so a credential that flips to FAILED will block its Outputs until you fix it; one that flips back to VALIDATED resumes automatically.

Attaching Outputs

Outputs live alongside credentials in the same dataDelivery block. The example below ships hourly impressions and daily clicks to the same GCS credential, with each data type writing under a distinct path prefix.

Rules to know

  • credentialName must point at a live credential on the same advertiser. The deliveryConfig.type must match the credential’s destinationType (you can’t ship to S3 through a GCS credential).
  • One Output per (dataDeliveryType, credentialName). To send the same data type to two destinations, list two Outputs with different credentials.
  • syncWeeklyDay is required when cadence: "WEEKLY" (0 = Sunday, 6 = Saturday). Ignored for HOURLY/DAILY.
  • pathPrefix is used verbatim — leading slashes are not stripped and the prefix is not templated. End it with / if you want a directory-like layout.
  • enabled: false pauses the schedule without removing the Output. In-flight runs complete; no new runs fire until you flip it back.

Campaign-scoped overrides

For a single campaign that needs a different cadence, format, or destination than its advertiser default, set dataDelivery.outputs on the campaign:
The override replaces the advertiser-scoped Output for the matching dataDeliveryType on this campaign only. Resolved Outputs in GET responses are tagged with source: "advertiser" or source: "campaign" so it’s clear which level produced each entry.

Rotation

GCS and S3

No rotating secret to manage — Scope3’s identity is fixed, so as long as the IAM grant stays in place the credential keeps working. Rotating means changing the bucket: submit a new credential with the new bucket and the existing credentials inline-array will update in place.

Azure Blob

SAS tokens carry an expiry. The expiry from the se= claim is parsed and exposed on the credential response as expiresAt — watch it and rotate ahead of time. To rotate, submit a fresh credential with the same name:
Updating in place preserves the credentialId, so any Output that references this credential by name keeps shipping without interruption. A fresh Probe runs against the new SAS; an in-flight Probe for the old SAS is cancelled.

Troubleshooting

Credential stuck on PENDING

The Probe workflow typically completes within seconds. If it’s been more than a minute:
  1. Re-fetch the advertiser — the row may have already flipped.
  2. Call the revalidate endpoint to force a fresh Probe.
  3. If it stays PENDING, contact Scope3 support — the Probe worker may be backed up.

status: FAILED — common statusError patterns

Output created but no objects landing

  1. Verify the referenced credential is VALIDATED.
  2. Check enabled on the Output — if false, the schedule is paused.
  3. For HOURLY cadence, allow a full hour boundary to pass before the first run. DAILY fires at 00:00 UTC, WEEKLY at 00:00 UTC on syncWeeklyDay.
  4. Confirm there is delivery data for the period — a campaign with zero impressions on a given day produces no objects, not an empty file.

Conflicting Outputs

If PUT returns a validation error about duplicate (dataDeliveryType, credentialName) pairs, it’s because the inline array contains two Outputs with the same data type pointing at the same credential. Use distinct credentials, or merge into a single entry.
  • Reporting Overview — pull-style aggregate metrics (the synchronous counterpart to Data Delivery).
  • Log Events — push events into Scope3 (the inbound counterpart to outbound Data Delivery).