Skip to main content
This guide shows you how to build an unattended integration that uploads an audience to Narrative and delivers it to The Trade Desk (TTD) marketplace, where buyers you choose can purchase it. A person signs in once to create an API key, and the integration uses that key from then on. Third-party audiences are sold from a taxonomy that TTD reviews before anything sells. This guide attaches your data to that taxonomy and delivers it. To build and price the taxonomy itself, see Managing your taxonomy via the API. To deliver into one advertiser’s own seat instead, see First-party delivery via the API. Before you start, complete the prerequisites and set up API access.

1. Create the dataset

Your schema decides whether The Trade Desk will accept the audience, so settle it before you upload anything.

Required columns

first_party and third_party_v2 take the same schema. The dataset needs at least one of these identifier columns: Each identifier column is named after its Rosetta Stone attribute, and the connector matches on that column name. A column holds either a plain string or an object. In the dataset schema, declare a string column with "type": "string", and declare an object column with "type": "object" and its properties:
Send an object column as an object in each row:
See your connector’s reference page for the attributes it accepts and their exact shapes. A row with one identifier looks like this:
See Supported identifiers for how The Trade Desk matches each identifier.

Check the schema first

The connector’s validation endpoint takes the schema you plan to use and answers 200 with an empty body when The Trade Desk would accept it. It needs no authorization header, and id can be any number:
A schema with no recognized identifier comes back 400, with one entry for each identifier the connector looked for:

Create it

write_mode is overwrite or append. file_config.type is json for JSON Lines, parquet, or flat for CSV. Record the dataset id from the response.
You do not need to supply UID2. The connector generates UID2 tokens from hashed email addresses automatically.

2. Activate the dataset

Activation locks the schema. You cannot change it afterward, so activate only once the shape is settled.

3. Upload and ingest your file

Each line of the file is one row that matches the schema you declared in step 1. For the columns The Trade Desk accepts and their shapes, see Supported identifiers and Required columns. You can load a file into a dataset over the API in two ways:
  • Signed-URL upload. Your integration uploads one file of up to 3 GB, then asks Narrative to ingest it.
  • Managed S3 bucket. You write files to an S3 bucket that Narrative manages, and Narrative ingests each batch on its own. Use a managed bucket for files larger than 3 GB, or for files that another system delivers on a schedule.

Choose a file format

The dataset’s file_config.type sets the format of every file you load into it. Parquet and JSON Lines both hold object columns, which nest properties inside one column:
  • Parquet (parquet) is the most compatible format for connector datasets. It stores nested struct columns and their types natively, and Narrative matches columns to the schema by name at every level.
  • JSON Lines (json) holds one JSON object per line. Narrative matches each nested object to the schema by name.
CSV datasets (flat) hold only scalar columns, so they can’t carry object columns.

Upload a file with a signed URL

Request an upload URL, then send the file straight to storage:
The upload URL is valid for 30 minutes and carries its own signature, so send no authorization header with the PUT.
Keep the path from the response. Narrative assigns its own storage path, which does not match the name you requested, and the ingest request needs Narrative’s path rather than yours.
Then ingest the file into the dataset, passing that path as source_file:
Ingestion runs in the background. Watch the record count on the dataset to know when it has finished:
The count moves from zero to your row count, typically within a couple of minutes. Each ingested file adds a new snapshot to the dataset, and every active connection on the dataset delivers that snapshot.

Write files to a managed S3 bucket

A managed bucket is an S3 bucket that Narrative creates for your company. You write each batch of files into its own folder under the dataset’s path in the bucket, then write an empty _NIO_COMMIT file into that batch folder. Narrative ingests every file in the batch folder when the commit file appears, so you make no upload or ingest request. A file can be as large as S3 accepts. See Ingesting Files from a Managed S3 Bucket to create the bucket, grant your AWS account access, and lay out the folders.

4. Confirm The Trade Desk accepts the dataset

Before you create a connection, ask Narrative which connector interfaces the dataset satisfies:
The response checks the dataset’s schema against every interface of the connectors your company has installed, and sorts the results into two lists:
  • accepted lists each interface you can connect the dataset to, by the connector’s app_id and the interface_id.
  • errors lists each interface the schema does not satisfy. Its details hold the reason, such as "required property '<column>' not found".
Add ?tags=<tag> to check only the interfaces that carry that tag. When the interface you want is under errors, the dataset’s schema doesn’t meet what the interface needs, for example a missing column or property. Activation locks the schema, so create a new dataset that fixes what the error names. For The Trade Desk, look for "app_id": 11 in accepted, under the interface your delivery model uses: first_party for first-party, third_party_v2 for third-party. See Delivery interfaces for what each interface does.

5. Find your connector profile

Your connector profile holds your Brand ID and Sub-Provider ID, and every delivery names it. The connector’s /profiles endpoint returns it:
Record the profile id. Its status must be enabled. GET /profiles/{profile_id} returns the same record on its own. If you have no profile yet, create one in the Narrative UI under Objects → Installed Apps → Trade Desk Connector and enter your Brand ID there.

6. Attach the dataset to a taxonomy element

Every audience you sell is a buyable taxonomy element with your dataset in its datasets list. For a new audience, create the element with your dataset ID in datasets, as shown in Create an audience. For a draft element that already exists, send it back with your dataset added. PUT replaces the whole element, so send every field, including the rates it already has:
The element comes back with the dataset under connections as {"type": "connection_draft", "dataset_id": 12345, "status": "draft", ...}. The connector checks the dataset’s schema against The Trade Desk when you attach it, and rejects a dataset TTD would not accept.

7. Synchronize

Attaching a dataset records the link in Narrative. Synchronizing sends it to The Trade Desk and creates the delivery connection for you.
The list holds your whole synchronization history, so pick out your request by its id. The request moves through pending and in-progress to completed or failed. Once it is completed, jobs.create_connections.completed counts the delivery connections it created. Each connection it creates uses the third_party_v2 interface, a membership duration of 90 days, and delivers the data already in the dataset as well as new rows. To choose different values, see Creating the connection yourself. A synchronization publishes every draft in your account, not only the element you changed, and only one can run at a time. See Synchronize for both rules.
The audience sells only once its element is active and TTD has approved it. See Wait for approval.

8. Confirm delivery

Check that the connection exists:
Then watch the element’s delivery statistics:
Each element reports a statistics object, which is null while the element is still a draft: The ratio of active_ids_count to received_ids_count is your match rate.

Creating the connection yourself

The connection that synchronization creates always uses a 90-day membership duration and delivers existing data. To set targeting_time_to_live_in_minutes or historical_data_enabled yourself, leave the dataset off the element, synchronize the element, and create the connection once the element is active:
The response is 201 with the connection and "status": "active". GET /v2/connections/{connection_id} returns it on its own. The outer type identifies what you are connecting, and quick_settings.type selects the delivery interface. provider_elements takes one or more elements. Use each element’s element_id from /taxonomies and its current display_name. What the connection does describes every field, its allowed values, and its default, along with what the connection does with existing and new rows. historical_data_enabled takes effect when the connection is created.

Keeping the audience current

Write new data to the dataset. The connection keeps running, so new rows reach The Trade Desk without further calls, and you do not touch the element or its price. Refresh the dataset more often than the membership duration, or members lapse between deliveries. Your source dataset must refresh at least every 90 days. To add another audience, repeat steps 1 through 7. Attach several datasets before you synchronize, so one synchronization publishes all of them.

Stopping a delivery

Delete the connection to stop delivering the dataset:

Troubleshooting

Dataset and upload problems

Delivery problems

Getting help

Contact your Narrative relationship manager with your company ID, the dataset ID, the element ID, the connection ID, and the failing request and response. For Trade Desk review status and Brand ID questions, your TTD account representative is the faster path.

Managing your taxonomy via the API

Build, price, and maintain the elements audiences are sold from

First-party delivery via the API

Deliver into one advertiser’s own seat instead

The Trade Desk Connector

Full settings reference, identifiers, and status vocabularies

API Keys

Create and rotate keys for programmatic access