Developer

Send conversions

One request sends a conversion. DataCops checks it, finds the ad click behind it, and delivers it to every platform you have connected.

What it does

You POST one event with your private key. DataCops reads it, skips it if it has seen the same messageId before, joins it to the visitor's browser session and past visits to recover click IDs, and sends it through the same delivery path as your website events. It reaches every ad platform you have connected: Meta, Google Ads, TikTok, LinkedIn, Microsoft Ads, Reddit, Pinterest and X.

This is the endpoint behind the DataCops Zapier action, and it works the same from Make, n8n or your own backend. To send a whole spreadsheet of past sales instead, see offline conversions.

How it works

  1. Auth. The x-dc-key header picks the website. See Authentication.
  2. Paused check. If the site is paused for billing, the request gets 402 and nothing is sent.
  3. Read. event is the only required field. A missing or empty event returns 422.
  4. Duplicate check. Each messageId is stored once per site. A repeat is skipped, never sent twice. See deduplication.
  5. Match. If you pass the DataCops session id or an email, DataCops looks for the visit and recovers click IDs like gclid, fbc, ttclid, li_fat_id, rdt_cid and epik.
  6. Deliver. The event runs through your Event Manager mapping, consent and bot rules, then goes to each connected platform. Each result lands in your delivery report.

The request

POST https://api.joindatacops.com/api/v1/conversions/zapier

cURL
curl -X POST https://api.joindatacops.com/api/v1/conversions/zapier \
  -H "x-dc-key: dcp_your_private_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "Purchase",
    "messageId": "order-1001",
    "timestamp": "2026-10-01T09:30:00Z",
    "properties": { "value": 49.0, "currency": "USD", "order_id": "1001" },
    "context": {
      "traits": { "email": "[email protected]", "phone": "+15551234567" },
      "identifiers": { "gclid": "Cj0KCQ..." }
    }
  }'

Use an event name your Event Manager knows. GET /api/v1/export/events lists them (see Export data). Standard names are Purchase, Lead, CompleteRegistration and Schedule.

The fields

FieldRequiredWhat it is
eventYesThe conversion name, like Purchase or Lead.
messageIdStrongly advisedYour unique id for this event. Without it DataCops makes one up, so a retry could be sent twice.
timestampNoISO string, unix seconds or unix ms. Defaults to now.
userId, anonymousIdNoYour own user id, and a pre-login visitor id.
propertiesNovalue, currency, order_id, items (sku, product_id, name, category, brand, quantity, price, currency), channel (online, in_store, phone, bopis).
context.traitsNoemail, phone, first_name, last_name, street, postal_code, city, state, country. Send plain text; DataCops hashes before sending to platforms.
context.identifiersNogclid, wbraid, gbraid, fbp, fbc, fbclid, ttclid, li_fat_id, rdt_cid, epik, customer_id, dc_session_id.
context.ip, context.userAgentNoThe buyer's IP and browser, if you have them.

The response

You get one result per event: whether the send worked, a short message, and what identity matching found.

202 Accepted
{
  "accepted": true,
  "source": "generic",
  "adapter_version": "v2026-05",
  "events": [
    {
      "messageId": "order-1001",
      "success": true,
      "message": "Conversion sent to 3 platform(s)",
      "identity": { "matched": 1, "created": 0, "enriched": ["gclid"] }
    }
  ],
  "duration_ms": 184
}

identity.matched and identity.created count the people DataCops matched or newly recorded for this event, and enriched lists the click IDs it recovered from earlier visits. Those recovered IDs are what let a platform tie an offline sale back to the ad that started it.

A repeat of the same messageId comes back with "message": "duplicate_delivery_skipped" and is not sent again.

Status codes

  • 202: accepted, every event processed without error.
  • 207: accepted, but at least one event could not be sent to any platform. Check message and errors on that event.
  • 401: missing or invalid x-dc-key.
  • 402: APP_INACTIVE, the site is paused. Upgrade to resume.
  • 422: the body is not a JSON object, or event is missing.

Retrying after a timeout or a 5xx is safe as long as you send the same messageId. For a sale that comes in through Shopify or another connected store, let that integration send it instead, so the same order is not posted twice under two different messageIds.

Was this page helpful?