Deliver to a Partner Endpoint
Activate an Audience covers the shape of an activation. This guide is the per-partner version of that journey: taking one completed audience and landing it at one specific destination, with the exact ids, streams and account details that destination expects.
The pattern is always the same, whichever partner you deliver to. You read the connection, read what its partner offers, fill in that partner’s inputs, and send one activation. Nothing about the partner is guessed or typed from memory.
Before you start
- A bearer token (Authentication).
- An audience in status
104Completed that passes every activation eligibility gate (device-count floor, Affinity SCID coverage, retention - see the gate table in Read an Audience). The audience read returns an explicitis_activation_allowedboolean and, when it isfalse,eligibility.reasons[]explains which gate blocked it - check it before you build the request. - An endpoint connection for the destination you want.
Step 1 - Find the endpoint connection
Everything else in this journey hangs off the connection. It is the anchor of the activation: the platform resolves the partner, the pricing options and the datastreams from it, server-side.
curl "https://console.intuizi.com/api/v2/analyses/reference/common/endpoint-connections" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Accept: application/json"Each entry carries the connection id, its name, and the partner behind it - including that partner’s input definitions:
{
"id": 12,
"name": "Acme Production",
"partner": {
"id": 3,
"name": "Acme DSP",
"inputs": [
{ "name": "Account ID", "type": "text", "required": true, "description": "Partner account id", "placeholder": "Account ID", "default_value": null },
{ "name": "Account Credentials", "type": "file", "required": true, "description": "Service Account .json file", "placeholder": "Service Account .json file", "default_value": null }
]
}
}Keep three things from this response: the connection id (for
endpoint_connection_id), the partner.id (the next two reads need it), and
the partner.inputs array in the order it arrives - that order is the
contract for Step 4.
Use search to narrow a long list by connection name. The full field contract
is in
Get Endpoint Connections;
the read never returns stored credentials or stored input values.
Step 2 - Read that partner’s pricing models
Pricing is per partner, so this read takes the partner_id you just kept:
curl "https://console.intuizi.com/api/v2/analyses/reference/common/pricing-models?partner_id=3" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Accept: application/json"{ "data": [ { "id": 9, "name": "CPM", "price": "2.50", "dataset_types": ["poi", "competitors"] } ] }Pick one id whose dataset_types include one of your audience’s dataset
types - that is your pricing_model_id. See
Get Pricing Models.
partner_id, partner_name and pricing_model; sending any
of them returns 422. Identity always comes from the connection.Step 3 - Read that partner’s datastreams
Datastreams are the outputs the partner exposes. Same partner_id:
curl "https://console.intuizi.com/api/v2/analyses/reference/common/datastreams?partner_id=3" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Accept: application/json"{ "data": [ { "id": 7, "name": "Match File" } ] }Keep the id of every stream you want delivered. See Get Datastreams.
A stream is only delivered when you enable it explicitly:
"datastreams": [ { "id": 7, "status": true } ]An entry without "status": true is not activated, so an activation whose
streams are all left disabled has nothing to deliver.
Step 4 - Map the partner’s account inputs
Most partners need account details alongside the audience - an account id, a
seat id, a folder prefix, a service-account key. Those are the partner.inputs
definitions from Step 1. Each definition carries a name, a type (text or
file), a required flag and UI hints, and the array order is meaningful.
You send values, not names, and they are matched to the definitions by index:
audience_inputs- one array for the whole activation.datastreams[].inputs- one array per stream, for streams that need different values. A per-stream value wins over the top-level one at the same index.- A
textdefinition flaggedrequiredmust resolve to a value for every enabled datastream, from the per-stream array, the top-level array, or the definition’sdefault_value. One left empty is rejected with a422naming that input. Adefault_valuepasses this check but is not copied into the delivery, so send the value explicitly. Afiledefinition travels separately (below).
For the example connection in Step 1, the mapping is:
| Index | name | type | required | Where its value goes |
|---|---|---|---|---|
| 0 | Account ID | text | Yes | audience_inputs[0] or datastreams[].inputs[0] |
| 1 | Account Credentials | file | Yes | datastreams[].service_account |
Read your own connection’s definitions the same way: walk the array, note the
index of each one, and place your values at those indexes. Keep positions
aligned by sending null at an index whose value travels elsewhere (a file
input, below) rather than shortening the array.
Delivery buckets and folders
A cloud storage destination takes its bucket and folder from the inputs:
Bucket Name and Folder Prefix, or GAM Upload Bucket. The bucket is a
standard bucket name, with or without s3:// or gs://, and has no path,
access point alias, or ARN. The folder prefix has no quote, backslash, control
character, or .. segment.
Intuizi buckets are not a destination. A bucket whose name starts with
intuizi counts as an Intuizi bucket, and so do an S3 bucket whose name starts
with aws-intuizi- and a bucket named after Intuizi’s own AWS account or Google
Cloud project. The one exception is an Intuizi delivery bucket with a folder
prefix that starts with the delivery folder Intuizi set up for your
organization. Any other Intuizi bucket, another folder of an Intuizi
delivery bucket, and a bucket or folder prefix that breaks the rules above are
rejected with 422 (see Errors).
Deliveries without access keys
A delivery that carries no access keys or service account key of your own is written with Intuizi’s own cloud identity. Such a delivery goes only to a bucket that Intuizi registered for your organization, and only under the folder registered with it, if there is one. A delivery that sends both of your own access keys, or your own service account key, for every enabled datastream can go to any bucket the rules above allow.
A bucket that is not registered takes no delivery without keys. Create
Activation and Create Schedule answer it with 422 and this message:
This delivery has no access keys or service account of your own, so it can only go to a bucket registered for your organization. Add your own access keys or service account, or ask your Account Manager to register the bucket.
To deliver there, ask your Account Manager to register the bucket, or send your
own access keys in the partner inputs (Step 4) or your own service account key
as datastreams[].service_account (below). A schedule is checked again at
every cycle, and a cycle to a bucket that is no longer registered creates no
activation. See Errors.
Service-account keys
A file-type definition is the destination’s service-account JSON key
(GCP-style destinations). It does not travel in the input arrays. Send the
decoded JSON object as datastreams[].service_account on each enabled stream.
It is accepted only for partners that define a file input - sending it to a
partner that does not is rejected with 422.
Step 5 - The credentials object
When the partner takes a destination or access details (a bucket, keys, a
service account), the delivery reads them from the partner inputs of Step 4. A
partner that takes none delivers to its own destination. The credentials stored on the endpoint connection are
never copied into the activation. The credentials object is optional, and if
neither it nor stored credentials exist the activation is rejected with 422.
Step 6 - Send the activation
POST /api/v2/analyses/activations/create
One request carries the audience, the connection, the pricing model, the enabled streams and the partner inputs.
curl -X POST "https://console.intuizi.com/api/v2/analyses/activations/create" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Idempotency-Key: <UNIQUE_KEY>" \
-d '{
"audience_id": 88,
"endpoint_connection_id": 12,
"pricing_model_id": 9,
"description": "Q1 retail delivery",
"audience_inputs": ["ACME-4471", null],
"datastreams": [
{
"id": 7,
"status": true,
"service_account": { "type": "service_account", "project_id": "acme-delivery" }
}
]
}'The response returns the new activation with its id and an opening lifecycle
status. Field by field, the body contract is in
API Reference - Activations,
including the optional delivery tuning fields (limit, compression,
frequency and distance caps, project_id, notification).
Idempotency-Key is optional and you generate it yourself - one unique string
per logical delivery. Resend the same key only when retrying that exact request:
the retry replays the original response instead of launching a second delivery.
See Idempotency.Step 7 - Poll the delivery
Delivery is asynchronous (see The Async Model). Poll
the activation until its lifecycle status reaches 104 Completed:
curl "https://console.intuizi.com/api/v2/analyses/activations/501" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Accept: application/json"100-103,108,109- still processing. Poll again shortly.105DataStreaming - the delivery to the destination is in flight.105happens before104, so keep polling.104Completed - the only terminal success state.107Additional Info - the export stopped and will not continue. Stop polling. Audience Manager shows the reason on the activation.4xxlifecycle ids - an error state. Stop polling and inspect the resource.
Each entry in the datastreams array of the read reports that stream’s name,
its status, a results object (carrying a uri when an output file is
available) and an error string only when that stream failed - so a partial
delivery is visible per stream, not just per activation. Data delivered to the
destination lands there directly, and the API does not proxy it. See
Read an Activation for the full
response, and Polling and Rate Limits for
sensible intervals.
Delivering again
Activations are point-in-time. To deliver a refreshed audience, build the new
audience and create a new activation against the same connection with a new
Idempotency-Key; to deliver the same audience to a second destination, repeat
Steps 1-6 with that destination’s connection id and its own partner inputs.
Checklist
- Connection id read from
endpoint-connections, not hardcoded. pricing_model_idand every datastream id read for that connection’spartner.id.- Each stream you want delivered carries
"status": true. - Every
requiredinput definition resolves to a value for every enabled stream, index-matched topartner.inputs. service_accountsent only when the partner defines afileinput.- Credentials either stored on the connection or supplied in the body.
- No
partner_id,partner_nameorpricing_modelin the request.
Rejection shapes and status codes are documented once, on Errors.
Reference
- Concept: Endpoint Connections & Partners
- Journey: Activate an Audience
- Reference reads: Working with Reference Data
- Field-level contract: API Reference - Activations
- Shared catalogs: API Reference - Common
- Driving this flow from an agent: Automate with an AI Agent