Analytics & Conversions
Read Reddit ad analytics and send server-side events to a Reddit pixel through the Conversions API.
Analytics
Call GET /v1/ads/{adId}/analytics with the ad's id (Get ad analytics).
Zernio syncs impressions, clicks and spend per ad and day from Reddit, in the ad account's time zone, and derives CTR, CPC and CPM from them.
Ads created in Reddit Ads Manager sync too, so GET /v1/ads?platform=reddit lists every ad in the synced ad accounts.
curl "https://zernio.com/api/v1/ads/66f0a1b2c3d4e5f6a7b8c9d0/analytics?fromDate=2027-01-04&toDate=2027-01-11" \
-H "Authorization: Bearer $ZERNIO_API_KEY"Response (200), trimmed:
{
"ad": { "id": "66f0a1b2c3d4e5f6a7b8c9d0", "name": "Planner launch", "platform": "reddit", "status": "active", "currency": "USD" },
"analytics": {
"summary": { "spend": 318.4, "impressions": 142600, "clicks": 1870, "ctr": 1.31, "cpc": 0.17, "cpm": 2.23 },
"daily": [ { "date": "2027-01-04", "spend": 45.2, "impressions": 20100, "clicks": 262 } ]
}
}Those 3 metrics are the whole sync: reach, video and conversion metrics stay 0 on Reddit, and the demographic breakdowns parameter is Meta and TikTok only.
GET /v1/ads/tree rolls the same metrics up per campaign and ad group (Get campaign tree).
Conversions API
POST /v1/ads/conversions sends server-side events to a Reddit pixel. It needs the adsconversions permission on the connection (Reconnect if it is missing).
destinationId is the pixel id. List the pixels of every synced ad account with GET /v1/accounts/{accountId}/conversion-destinations:
{
"platform": "redditads",
"destinations": [
{ "id": "a2_gu5tcd9ah5se", "name": "Acme website", "status": "active", "adAccountId": "a2_gu5tcd9ah5se" }
]
}const { data: sent } = await zernio.conversions.sendConversions({
body: {
accountId: '66b2e19d8c3f5a7e9d0b1c2d',
destinationId: 'a2_gu5tcd9ah5se',
events: [{
eventName: 'Purchase',
eventTime: 1798804800,
eventId: 'order_12345',
sourceUrl: 'https://shop.example.com/checkout/confirmation',
value: 25.99,
currency: 'USD',
user: {
email: 'customer@example.com',
ipAddress: '203.0.113.7',
userAgent: 'Mozilla/5.0 ...',
clickIds: { rdt_cid: '1234567890abcdef' }
}
}]
}
});
console.log(sent.eventsReceived);Response (200):
{
"platform": "redditads",
"eventsReceived": 1,
"eventsFailed": 0,
"failures": []
}How Zernio maps each event
| Zernio field | Reddit field | Notes |
|---|---|---|
eventName | type.tracking_type | Purchase, Lead, CompleteRegistration (as SIGN_UP), AddToCart, AddToWishlist, ViewContent, Search and PageView (as PAGE_VISIT) map to Reddit's standard events; any other name is sent as a custom event with the name kept |
eventTime | event_at | Unix seconds. Reddit accepts events up to 7 days old |
eventId | metadata.conversion_id | Deduplicates against the same event fired by the pixel |
value, currency, items | metadata | items become products and item_count |
user.clickIds.rdt_cid | click_id | The Reddit click id from the landing URL |
user.clickIds.rdt_uuid | user.uuid | The pixel's first-party id (_rdt_uuid cookie) |
user.email, user.phone, user.externalId | user | Hashed with SHA-256 by Zernio: send plain values |
user.ipAddress, user.userAgent | user | Sent as is |
actionSource | action_source | web (the default) is WEBSITE, app is APP, anything else OTHER |
How it behaves
- Every event needs at least one match key:
rdt_cid,rdt_uuid, an email, a phone, an external id, or the IP address together with the user agent. consent.adUserData: "DENIED"drops the user identifiers, leaving only the click id.- Pass
testCodeto send the batch with Reddit'stest_id, so you can check it in Reddit's Events Manager. - Larger submissions are sent in chunks of 1,000 events.
- An event older than 7 days, timed more than an hour in the future (usually a millisecond timestamp) or with no match key is reported in
failures[]with codeINVALID_EVENT, and the rest still go. - A chunk Reddit rejects lands in
failures[]with codeREDDIT_REJECTEDand Reddit's message.
If it fails
| Status | Cause | Fix |
|---|---|---|
403 with code reconnect_required | The connection lacks adsconversions | Reconnect Reddit Ads. |
403 with code insufficient_permissions | The connected Reddit user has no role on the ad account that owns the pixel | Grant the user a role on that ad account in Reddit Ads Manager. |
401 with code reconnect_required | Reddit rejected the token | Reconnect. |
400 with code invalid_field_value | destinationId is not a Reddit pixel id | Use an id from conversion-destinations. |
Related
- Get ad analytics: metrics, date ranges and rollups.
- Send conversions and List conversion destinations.