> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Reddit Conversions API

<!-- -->

[Server](#)[ ](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/reddit)

<!-- -->

[Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/reddit)[ ](https://www.npmjs.com/package/@walkeros/server-destination-reddit)

<!-- -->

[Package](https://www.npmjs.com/package/@walkeros/server-destination-reddit)

<!-- -->

Beta

Server-side event delivery to Reddit's Conversions API v2.0 for enhanced conversion tracking, bypassing browser limitations and improving match quality for ad optimization.

<!-- -->

Where this fits

Reddit Conversions API is a **server destination** in the walkerOS flow:

Sends events server-side to Reddit's Conversions API using raw HTTP (no SDK). Identity fields (\`email\`, \`external\_id\`, \`ip\_address\`, \`user\_agent\`, \`idfa\`, \`aaid\`) are SHA-256 hashed before sending. Events include a stable \`event\_metadata.conversion\_id\` for deduplication with the Reddit Pixel.

## Installation[​](#installation "Direct link to Installation")

```
npm install @walkeros/server-destination-reddit
```

* Integrated
* Bundled

```
import { startFlow } from '@walkeros/collector';
import { destinationReddit } from '@walkeros/server-destination-reddit';

await startFlow({
  destinations: {
    reddit: {
      code: destinationReddit,
      config: {
        settings: {
          accessToken: 'YOUR_ACCESS_TOKEN',
          pixelId: 'YOUR_PIXEL_ID',
        },
      },
    },
  },
});
```

Add to your `flow.json` destinations:

```
"destinations": {
  "reddit": {
    "package": "@walkeros/server-destination-reddit",
    "import": "destinationReddit",
    "config": {
      "settings": {
        "accessToken": "YOUR_ACCESS_TOKEN",
        "pixelId": "YOUR_PIXEL_ID"
      }
    }
  }
}
```

[See bundled mode setup](https://www.walkeros.io/docs/getting-started/modes/bundled.md) | [CLI reference](https://www.walkeros.io/docs/apps/cli.md)

## Configuration[​](#configuration "Direct link to Configuration")

This <!-- -->destination<!-- --> uses the standard <!-- -->destination<!-- --> config wrapper (consent, data, env, id, ...). For the shared fields see [destination<!-- --> configuration](https://www.walkeros.io/docs/destinations.md#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to Settings")

| Property        | Type                               | Description                                                      | More |
| --------------- | ---------------------------------- | ---------------------------------------------------------------- | ---- |
| `accessToken*`  | `string`                           | Reddit Conversion Access Token for Bearer authentication         |      |
| `pixelId*`      | `string`                           | Reddit Pixel ID used as the API path parameter                   |      |
| `action_source` | `'WEBSITE' \| 'APP' \| 'PHYSICAL_` | Source of the event (WEBSITE, APP, PHYSICAL\_STORE)              |      |
| `doNotHash`     | `Array<string>`                    | Array of user fields that should not be hashed                   |      |
| `test_mode`     | `boolean`                          | Enable test mode by sending test\_mode: true in the request body |      |
| `url`           | `string`                           | Custom URL for Reddit Conversions API endpoint                   |      |
| `user_data`     | `Record<string, string>`           | Mapping configuration for user fields                            |      |

\* Required fields

## Mapping[​](#mapping "Direct link to Mapping")

This package does not define custom rule-level settings. For the standard rule fields (consent, condition, data, batch, name, policy) see [mapping](https://www.walkeros.io/docs/mapping.md).

## Examples

### Add to cart

A product add is sent to Reddit as an AddToCart conversion with value and product details.

Event

```
{
  "name": "product add",
  "data": {
    "id": "SKU-B2",
    "name": "Cool Cap",
    "category": "hats",
    "price": "42.00",
    "quantity": 1
  },
  "context": {
    "shopping": [
      "intent",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "user-456"
  },
  "nested": [],
  "consent": {
    "functional": true
  },
  "id": "ev-1700000901",
  "trigger": "click",
  "entity": "product",
  "action": "add",
  "timestamp": 1700000901,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "express",
    "platform": "server"
  }
}
```

Mapping

```
{
  "name": "AddToCart",
  "data": {
    "map": {
      "event_metadata": {
        "map": {
          "value_decimal": "data.price",
          "currency": {
            "value": "EUR"
          },
          "item_count": {
            "value": 1
          },
          "products": {
            "set": [
              {
                "map": {
                  "id": "data.id",
                  "name": "data.name",
                  "category": {
                    "key": "data.category",
                    "value": "uncategorized"
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
}
```

Out

```
sendServer("https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456", "{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.901Z\",\"event_at_ms\":1700000901,\"event_type\":{\"tracking_type\":\"AddToCart\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"ev-1700000901\",\"value_decimal\":\"42.00\",\"currency\":\"EUR\",\"item_count\":1,\"products\":[{\"id\":\"SKU-B2\",\"name\":\"Cool Cap\",\"category\":\"hats\"}]}}]}}", {
  "headers": {
    "Authorization": "Bearer s3cr3t"
  }
})
```

### Lead

A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.

Event

```
{
  "name": "form submit",
  "data": {
    "form": "contact"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "user-lead-1",
    "email": "lead@example.com"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "ev-1700000903",
  "trigger": "test",
  "entity": "form",
  "action": "submit",
  "timestamp": 1700000903,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "express",
    "platform": "server"
  }
}
```

Mapping

```
{
  "name": "Lead",
  "data": {
    "map": {
      "user": {
        "map": {
          "email": "user.email",
          "external_id": "user.id"
        }
      }
    }
  }
}
```

Out

```
sendServer("https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456", "{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.903Z\",\"event_at_ms\":1700000903,\"event_type\":{\"tracking_type\":\"Lead\"},\"user\":{\"email\":\"9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2\",\"external_id\":\"ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8\"},\"event_metadata\":{\"conversion_id\":\"ev-1700000903\"}}]}}", {
  "headers": {
    "Authorization": "Bearer s3cr3t"
  }
})
```

### Page visit

A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.

Event

```
{
  "name": "page view",
  "data": {
    "domain": "www.example.com",
    "title": "walkerOS documentation",
    "referrer": "https://www.walkeros.io/",
    "search": "?foo=bar",
    "hash": "#hash",
    "id": "/docs/"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "pagegroup": "docs"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "user-789"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "ev-1700000902",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000902,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "express",
    "platform": "server"
  }
}
```

Mapping

```
{
  "name": "PageVisit"
}
```

Out

```
sendServer("https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456", "{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.902Z\",\"event_at_ms\":1700000902,\"event_type\":{\"tracking_type\":\"PageVisit\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"ev-1700000902\"}}]}}", {
  "headers": {
    "Authorization": "Bearer s3cr3t"
  }
})
```

### Purchase

A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.

Event

```
{
  "name": "order complete",
  "data": {
    "id": "ORD-300",
    "total": 249.99,
    "currency": "EUR"
  },
  "context": {
    "shopping": [
      "complete",
      0
    ]
  },
  "globals": {
    "pagegroup": "shop"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "user-123",
    "device": "device-456"
  },
  "nested": [
    {
      "entity": "product",
      "data": {
        "id": "SKU-A1",
        "name": "Everyday Ruck Snack",
        "category": "bags",
        "price": "129.99",
        "quantity": 2
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "ev-1700000900",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000900,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "express",
    "platform": "server"
  }
}
```

Mapping

```
{
  "name": "Purchase",
  "data": {
    "map": {
      "event_metadata": {
        "map": {
          "value_decimal": "data.total",
          "currency": {
            "key": "data.currency",
            "value": "EUR"
          },
          "item_count": {
            "fn": {
              "$code": "e=>e.nested.filter(e=>\"product\"===e.entity).length"
            }
          },
          "products": {
            "loop": [
              "nested",
              {
                "condition": {
                  "$code": "e=>h(e)&&\"product\"===e.entity"
                },
                "map": {
                  "id": "data.id",
                  "name": "data.name",
                  "category": {
                    "key": "data.category",
                    "value": "uncategorized"
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
}
```

Out

```
sendServer("https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456", "{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.900Z\",\"event_at_ms\":1700000900,\"event_type\":{\"tracking_type\":\"Purchase\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"ev-1700000900\",\"value_decimal\":249.99,\"currency\":\"EUR\",\"item_count\":1,\"products\":[{\"id\":\"SKU-A1\",\"name\":\"Everyday Ruck Snack\",\"category\":\"bags\"}]}}]}}", {
  "headers": {
    "Authorization": "Bearer s3cr3t"
  }
})
```

### Search

A site search is sent to Reddit as a Search conversion with an item count in event\_metadata.

Event

```
{
  "name": "site search",
  "data": {
    "query": "walkerOS destinations"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "user-101"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "ev-1700000905",
  "trigger": "test",
  "entity": "site",
  "action": "search",
  "timestamp": 1700000905,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "express",
    "platform": "server"
  }
}
```

Mapping

```
{
  "name": "Search",
  "data": {
    "map": {
      "event_metadata": {
        "map": {
          "item_count": {
            "value": 1
          }
        }
      }
    }
  }
}
```

Out

```
sendServer("https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456", "{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.905Z\",\"event_at_ms\":1700000905,\"event_type\":{\"tracking_type\":\"Search\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"ev-1700000905\",\"item_count\":1}}]}}", {
  "headers": {
    "Authorization": "Bearer s3cr3t"
  }
})
```

### Sign up

A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.

Event

```
{
  "name": "user signup",
  "data": {
    "method": "email"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "new-user-1",
    "email": "new@example.com"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "ev-1700000904",
  "trigger": "test",
  "entity": "user",
  "action": "signup",
  "timestamp": 1700000904,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "express",
    "platform": "server"
  }
}
```

Mapping

```
{
  "name": "SignUp",
  "data": {
    "map": {
      "user": {
        "map": {
          "email": "user.email",
          "external_id": "user.id"
        }
      }
    }
  }
}
```

Out

```
sendServer("https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456", "{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.904Z\",\"event_at_ms\":1700000904,\"event_type\":{\"tracking_type\":\"SignUp\"},\"user\":{\"email\":\"f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716\",\"external_id\":\"b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde\"},\"event_metadata\":{\"conversion_id\":\"ev-1700000904\"}}]}}", {
  "headers": {
    "Authorization": "Bearer s3cr3t"
  }
})
```

## Event mapping[​](#event-mapping "Direct link to Event mapping")

Reddit uses a **rigid taxonomy**. Map walkerOS events to a standard `tracking_type` via each rule's `name` field:

| walkerOS Event     | Reddit `tracking_type` |
| ------------------ | ---------------------- |
| `page view`        | `PageVisit`            |
| `product view`     | `ViewContent`          |
| `site search`      | `Search`               |
| `product add`      | `AddToCart`            |
| `product wishlist` | `AddToWishlist`        |
| `order complete`   | `Purchase`             |
| `form submit`      | `Lead`                 |
| `user signup`      | `SignUp`               |

Any non-standard name becomes `{ tracking_type: 'Custom', custom_event_name: '<name>' }` automatically. Reddit's AI optimization is trained on the standard events, so prefer them when possible.

```
"mapping": {
  "order": {
    "complete": {
      "name": "Purchase",
      "data": {
        "map": {
          "event_metadata": {
            "map": {
              "value_decimal": "data.total",
              "currency": "data.currency",
              "item_count": { "value": 1 }
            }
          }
        }
      }
    }
  }
}
```

### event\_metadata structure[​](#event_metadata-structure "Direct link to event_metadata structure")

Unlike Meta's CAPI (which uses `custom_data`) and Pinterest (which also uses `custom_data`), Reddit places conversion details under `event_metadata`. Always map into `event_metadata.map`. Products belong in `event_metadata.products[]` with `{ id, name?, category }`.

### Payload envelope[​](#payload-envelope "Direct link to Payload envelope")

Reddit wraps events inside `{ data: { events: [...] } }` (nested), unlike Meta/Pinterest's flat `{ data: [...] }`. The destination handles this automatically.

## Hashing[​](#hashing "Direct link to Hashing")

The destination automatically SHA-256 hashes the 6 standard identity fields before sending: `email`, `external_id`, `ip_address`, `user_agent`, `idfa`, `aaid`. Pass raw values and hashing is handled for you.

Different from Meta/Pinterest

Reddit hashes `ip_address` and `user_agent`, which Meta CAPI and Pinterest CAPI pass through as plaintext. Be sure to pass the raw values, not pre-hashed ones, unless you use `doNotHash`.

Non-hashable fields pass through as-is: `uuid`, `opt_out`, `screen_dimensions`, `data_processing_options`.

If a value is already hashed or you want to skip hashing for a specific field, use `doNotHash`:

```
"settings": {
  "accessToken": "YOUR_ACCESS_TOKEN",
  "pixelId": "YOUR_PIXEL_ID",
  "doNotHash": ["email"]
}
```

## Deduplication[​](#deduplication "Direct link to Deduplication")

Each event is sent with `event_metadata.conversion_id` set to the walkerOS event `id`. If you also run the Reddit Pixel in the browser, Reddit deduplicates server and browser events that share the same `conversion_id`, so conversions are not double-counted.

## Test mode[​](#test-mode "Direct link to Test mode")

Set `test_mode: true` in settings to send `"test_mode": true` as a **top-level boolean in the request body** (not a query parameter, unlike Pinterest). Useful during development.

```
"settings": {
  "accessToken": "YOUR_ACCESS_TOKEN",
  "pixelId": "YOUR_PIXEL_ID",
  "test_mode": true
}
```

## Links[​](#links "Direct link to Links")

* [Reddit Conversions API documentation](https://ads-api.reddit.com/docs/v2/#tag/Conversions-API)
* [Reddit Ads Manager](https://ads.reddit.com/)
