Skip to main content
This guide shows you how to build an unattended integration that uploads conversion events to Narrative and sends them to a Snap Pixel through Snapchat’s Conversions API. The examples send offline events, such as in-store purchases. Before you start, complete the prerequisites and set up API access. You need a profile ID and the ID of a Snap Pixel your Snapchat organization owns.

1. Create the dataset

A conversion-event dataset needs two columns:
  • snapchat_conversion_event, an object holding the event
  • at least one identifier Snapchat can match on, such as sha256_hashed_email
Column names are case sensitive, so keep them lowercase as shown. Activation locks the schema, so add every field you plan to send before you activate. Record the id in the response, then activate the dataset:

Required columns

The snapchat_conversion_event column is an object. These properties are required in every event: The optional properties are event_tag (string), data_processing_options (an array of strings), and custom_data. A PURCHASE event also needs custom_data.value and custom_data.currency, or the connector drops it. Every field in custom_data is optional: The dataset also 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 purchase row with the required properties and one identifier looks like this:

2. Confirm Snapchat 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 Snapchat, look for the Snapchat Connector ("app_id": 22) with the conversion_events interface in accepted.

3. Create the connection in test mode

Start with test_mode_enabled set to true. In test mode, Snapchat checks each event and records nothing, so test events stay out of your reporting.
The connection names no pixel. Each event names its own in snapchat_pixel_id, so one connection can send to every pixel your organization owns. What the connection does describes test_mode_enabled, historical_data_enabled, and their defaults.

4. Upload events

Each line of the file is one event, in a row that matches the schema you declared in step 1. For the columns Snapchat accepts and their shapes, see the Snapchat Connector reference 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.

5. Check the results

Subscribe to delivery notifications to hear about each delivery. The connector sends conversion.delivery.completed when a delivery of conversion events finishes, and conversion.delivery.failed when one fails. To read the connection back:

Going live

When the test deliveries look right, send real conversions:
  1. Create a connection on the dataset using the same request as step 3, but set test_mode_enabled to false:
  2. Delete the test connection with DELETE /v2/connections/{connection_id}.
Events sent through the new connection count as real conversions.

Keeping events flowing

Write new events to the dataset. The connection keeps running, so new rows reach Snapchat without further calls.

Stopping delivery

Deleting the connection archives it and stops further events from reaching Snapchat. Events already sent stay in Snapchat.

Troubleshooting

Getting help

Contact your Narrative relationship manager with your company ID, the dataset ID, and the failing request and response.

Delivering customer lists via the API

Deliver hashed identifiers into a Snapchat customer list

Snapchat Connector

Supported identifiers and profile setup

Connector Interfaces

Why a dataset connects to an interface rather than a connector

API Keys

Create and rotate keys for programmatic access