Roku is a TV streaming platform whose advertising business helps brands reach streaming households across Roku devices and ad-supported channels. Roku Ads Manager is Roku's self-serve platform for planning, buying, optimizing, and measuring connected TV (CTV) campaigns. The Roku Conversions API (CAPI) is a server-to-server integration that sends website, app, and offline conversion events directly to Roku. Roku uses these events for measurement, campaign optimization, and event-based custom audiences without relying on browser cookies.
Product Type: Advertising
Integration Type: Starter Kit
Event Source Type: Web, Mobile Browser, and Mobile App
Event Scope: Full-Funnel Events
- Sends full-funnel events from the server to Roku Ads Manager, from page and screen views through product views, carts, checkouts, and purchases.
- Connects CTV campaign performance to on-site and in-app business outcomes.
- Supports event-based custom audiences in Roku Ads Manager for retargeting and exclusion.
- Supports web and mobile app traffic, labeling app events and passing mobile advertising IDs for iOS and Android.
- Sends order value, currency, and product details for revenue and return on ad spend reporting.
- Normalizes and hashes personal information such as email, phone, and name before it is sent to Roku.
- Do not remove or add conditions to the event type, event name, event time, and user data mappings. If any of these is empty on a single event, Roku rejects the entire batch, and the batch is not retried.
- Use one starter kit per website or app. The same API key can be reused, but each property should have its own Event Group ID.
- Phone numbers must already be in international (E.164) format. The kit removes formatting and adds +1 only when no + is present, so numbers stored in formats like 1-234-... are hashed incorrectly. If you cannot guarantee E.164 phone numbers, remove the phone mapping.
- Currency defaults to USD only on Product Added and Product Added To Wishlist, because these standard events often lack a currency. All other events send the event's own currency.
- When a product has no quantity, the kit sends a quantity of 1, which matches how the total value is calculated.
- The partner name is sent as MetaRouter. Do not change this value unless advised by Roku, as the partner value must be allowlisted by Roku.
- Roku requires at least one of the following identifiers on every event: IP address, hashed email (
em), hashed phone (ph), Android advertising ID (aGA), Apple advertising ID (aID). This kit sends IP address, hashed email, hashed phone, and mobile advertising IDs when available.
- Roku recommends sending as many additional identifiers as possible to improve matching.
- Batches of up to 1,000 events are accepted. This kit sends batches of 500 by default.
- Roku applies 14-day view-through and click-through attribution windows.
- Sign in to Roku Ads Manager with an Organization Admin or Account Admin role. Only these roles can generate an API key.
- Event Group ID:
- Go to the Events page and select Back to event groups.
- Select the event group for your website or app, or select Add event group, name it, and choose Conversions API as the connection method.
- Copy the Event Group ID. Event Group IDs are case-sensitive.
- API Key:
- In the Events tab of Ads Manager, select CAPI.
- Select Generate an API key, then copy the key and store it securely.
- API keys do not expire. If a key is compromised, revoke it and generate a new one.
- From the integration library, add a Roku CAPI integration. Then, fill out the Connection Parameters:
| Connection Parameter | Description |
|---|
EVENT_GROUP_ID | Case-sensitive Event Group ID for one website or app, found on the Events page in Roku Ads Manager. |
API_KEY | Conversions API key generated under Events > CAPI in Roku Ads Manager. Used to authenticate requests. |
- MetaRouter provides all of the event mappings that Roku CAPI integrations typically require. You may add custom events, parameters, or mappings in accordance with Roku's API documentation.
- In the Pipelines tab, add your Roku CAPI integration.
- Select the correct integration revision.
- Click Add Integration and finalize deployment.
Global mappings will be applied to all events. If your parameter names do not match the Expected Inputs provided, you will need to overwrite the Inputs provided with your own.
| Output Key | Description | Expected Input |
|---|
event_type Required | String: Event type. Must never be null, or the entire batch is rejected. | Enrichment – 'conversion' |
partner_name | String: Name of the partner sending events. Informational only. | Enrichment – 'MetaRouter' |
event_id | String: Unique event ID used for deduplication with the Roku Pixel. | messageId |
event_source | String: Where the event occurred, 'mobile_app' or 'website'. | Expression – 'mobile_app' when context.device.type is iOS or Android, otherwise 'website' |
event_time Required | Integer: Event timestamp in epoch seconds. Must never be null. | Expression – converts timestamp to epoch seconds |
event_source_url | String: URL of the page where the event occurred. | context.page.url |
referrer_url | String: URL of the referring page. | context.page.referrer |
user_data.client_ip_address | String: Client IP address, unhashed. | context.ip |
user_data.client_user_agent | String: Client user agent, unhashed. | context.userAgent |
user_data.aFC | String: First-party cookie ID, unhashed. | anonymousId |
user_data.external_id | String: Advertiser user ID, unhashed. | userId |
user_data.em | String: SHA-256 hashed email, lowercased and trimmed with any +alias removed. | Expression – hashes normalized traits.email |
user_data.ph | String: SHA-256 hashed phone in E.164 format. Adds +1 when no + is present. | Expression – hashes E.164-normalized traits.phone |
user_data.fn | String: SHA-256 hashed first name, lowercased and trimmed. | Expression – hashes normalized traits.firstName |
user_data.ln | String: SHA-256 hashed last name, lowercased and trimmed. | Expression – hashes normalized traits.lastName |
user_data.ge | String: SHA-256 hashed gender, lowercased and trimmed. | Expression – hashes normalized traits.gender |
user_data.db | String: SHA-256 hashed date of birth in yyyy-mm-dd format. | Expression – hashes first 10 characters of traits.birthday |
user_data.aID | String: iOS mobile advertising ID (IDFA), unhashed. Sent for iOS devices only. | Expression – context.device.advertisingId when context.device.type is iOS |
user_data.aGA | String: Android mobile advertising ID, unhashed. Sent for Android devices only. | Expression – context.device.advertisingId when context.device.type is Android |
user_data.ct | String: City, unhashed. | traits.address.city |
user_data.st | String: State, unhashed. | traits.address.state |
user_data.zp | String: Zip or postal code, unhashed. | traits.address.postalCode |
user_data.country | String: Country, unhashed. | traits.address.country |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for a page view. Must never be null. | Enrichment – 'PAGE_VIEW' |
custom_data.content_name | String: Name of the page. | properties.name |
custom_data.content_category | String: Category of the page. | properties.category |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for an app screen view. Must never be null. | Enrichment – 'PAGE_VIEW' |
custom_data.content_name | String: Name of the screen. | properties.name |
custom_data.content_category | String: Category of the screen. | properties.category |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for a search. Must never be null. | Enrichment – 'SEARCH' |
custom_data.search_string | String: Search text entered by the user. | properties.query |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for a product view. Must never be null. | Enrichment – 'VIEW_CONTENT' |
custom_data.content_type | String: Type of IDs sent in content fields. | Enrichment – 'product' |
custom_data.content_name | String: Name of the product. | properties.name |
custom_data.content_category | String: Category of the product. | properties.category |
custom_data.content_ids | Array: Product ID of the viewed product. | Expression – wraps properties.product_id in an array |
custom_data.currency | String: ISO currency code, uppercased. No default applied. | properties.currency |
custom_data.value | Float: Total product value, price times quantity (quantity defaults to 1). | Expression – TOTAL_VALUE(properties) |
custom_data.contents | Array: Product object with id, quantity (defaults to 1), and price. | Expression – maps properties.product_id, properties.quantity, properties.price |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for add to cart. Must never be null. | Enrichment – 'ADD_TO_CART' |
custom_data.content_type | String: Type of IDs sent in content fields. | Enrichment – 'product' |
custom_data.content_name | String: Name of the product. | properties.name |
custom_data.content_category | String: Category of the product. | properties.category |
custom_data.content_ids | Array: Product ID of the added product. | Expression – wraps properties.product_id in an array |
custom_data.currency | String: ISO currency code, uppercased. Defaults to 'USD' when missing. | properties.currency |
custom_data.value | Float: Total product value, price times quantity (quantity defaults to 1). | Expression – TOTAL_VALUE(properties) |
custom_data.contents | Array: Product object with id, quantity (defaults to 1), and price. | Expression – maps properties.product_id, properties.quantity, properties.price |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for add to wishlist. Must never be null. | Enrichment – 'ADD_TO_WISHLIST' |
custom_data.content_type | String: Type of IDs sent in content fields. | Enrichment – 'product' |
custom_data.content_name | String: Name of the product. | properties.name |
custom_data.content_category | String: Category of the product. | properties.category |
custom_data.content_ids | Array: Product ID of the wishlisted product. | Expression – wraps properties.product_id in an array |
custom_data.currency | String: ISO currency code, uppercased. Defaults to 'USD' when missing. | properties.currency |
custom_data.value | Float: Total product value, price times quantity (quantity defaults to 1). | Expression – TOTAL_VALUE(properties) |
custom_data.contents | Array: Product object with id, quantity (defaults to 1), and price. | Expression – maps properties.product_id, properties.quantity, properties.price |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for checkout start. Must never be null. | Enrichment – 'INITIATE_CHECKOUT' |
custom_data.content_type | String: Type of IDs sent in content fields. | Enrichment – 'product' |
custom_data.order_id | String: Order identifier. | properties.order_id |
custom_data.content_ids | Array: Product IDs pulled from each product's product_id. | properties.products |
custom_data.currency | String: ISO currency code, uppercased. No default applied. | properties.currency |
custom_data.value | Float: Total value of all products (quantity defaults to 1). | Expression – TOTAL_VALUE(properties.products) |
custom_data.num_items | Integer: Total item quantity. Each product counts as 1 when quantity is missing. | Expression – sums quantities in properties.products |
custom_data.contents | Array: Product objects with id, quantity (defaults to 1), and price. | Expression – maps each item in properties.products |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for adding payment info. Must never be null. | Enrichment – 'ADD_PAYMENT_INFO' |
custom_data.order_id | String: Order identifier. | properties.order_id |
| Output Key | Description | Expected Input |
|---|
event_name Required | String: Roku event name for a purchase. Must never be null. | Enrichment – 'PURCHASE' |
custom_data.content_type | String: Type of IDs sent in content fields. | Enrichment – 'product' |
custom_data.order_id | String: Order identifier. | properties.order_id |
custom_data.content_ids | Array: Product IDs pulled from each product's product_id. | properties.products |
custom_data.currency | String: ISO currency code, uppercased. No default applied. | properties.currency |
custom_data.value | Float: Total order value (quantity defaults to 1). | Expression – TOTAL_VALUE(properties.products) |
custom_data.num_items | Integer: Total item quantity. Each product counts as 1 when quantity is missing. | Expression – sums quantities in properties.products |
custom_data.contents | Array: Product objects with id, quantity (defaults to 1), and price. | Expression – maps each item in properties.products |
These identifiers must be mapped to Roku in order for successful user matching to occur. Without these IDs, any events sent to Roku may not be accurately reflected in reporting.
| Attribute | Example | Sync Injector Required? |
|---|
em Recommended | f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a | No |
ph Recommended | 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b | No |
client_ip_address Recommended | 203.0.113.42 | No |
aID Recommended | 6D92078A-8246-4BA4-AE5B-76104861E7DC | No |
aGA Recommended | 5e2d9c1a-9e9c-4d5b-9c1a-9e9c4d5b9c1a | No |
client_user_agent | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 | No |
aFC | 3f7c2a91-5b8e-4d1a-9c6f-2e4b7d8a1c05 | No |
external_id | user_12345 | No |
fn | 96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a | No |
ln | 799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f | No |
-
Event data can take about four hours to appear in Roku Ads Manager reporting.
-
An incorrect API key or Event Group ID causes every batch to be dropped until it is fixed. A wrong API key returns a 401 error and a wrong Event Group ID returns a 403 error. Pipeline logs show only the status code, not a Roku validation message.
-
When some events in a batch fail, Roku returns a partial success response (HTTP 210), and MetaRouter counts the batch as delivered. Rejected events are not surfaced, so compare event counts in the Roku Ads Manager Events tab after setup and on a regular basis.
-
Roku accepts events with no usable identifier, and accepts unhashed personal information, without returning an error. A broken hashing mapping results in events that cannot be matched rather than failed deliveries.