---
title: "Record a conversion"
method: POST
path: "/api/v1/conversions"
tags: ["conversions"]
---

# Record a conversion

`POST /api/v1/conversions`

## Request

- Base URL: `https://app.blueticked.com`
- URL: `https://app.blueticked.com/api/v1/conversions`
- Auth: HTTP bearer

Report a conversion (an order, booking or any success event). Blueticked attributes it to the contact's most recent email click (falling back to the most recent delivery) within a 7-day window, and rolls the value up on the campaign and reports surfaces.

The JSON request body is limited to 32 KiB (32,768 bytes). A larger body answers 413 `payload_too_large`; invalid JSON answers 400 `validation_failed`.

Identify the contact with `contact_id` (UUID) or `contact_email` (matched case-insensitively). An unknown contact is stored UNATTRIBUTED and counted: never dropped, never an error.

`value_cents` is a non-negative integer in the currency's minor unit; `currency` is a 3-letter ISO code (default ZAR). Mixed-currency totals are always reported as a per-currency breakdown, never summed.

Attribution is last-touch: the most recent email CLICK in the 7 days before `occurred_at`, falling back to the most recent delivery. `attributed: false` means no email engagement fell inside the window.

`external_ref` makes ingestion idempotent: replaying the same reference returns the stored conversion (200) instead of double-counting.

Values are your own reported figures. Blueticked attributes them but never verifies them, and they are unrelated to Blueticked billing.

## Request body

- object
  - `contact_email` string, email
  - `value_cents` number, required
  - `currency` string
  - `occurred_at` string, date-time
  - `source` string
  - `external_ref` string

## Response `200`

Existing conversion returned for a deduplicated external_ref

- object
  - `conversion` object, required
    - `id` string, uuid, required
    - `contact_id` string, uuid, nullable, required
    - `campaign_id` string, uuid, nullable, required
    - `message_id` string, uuid, nullable, required
    - `value_cents` number, required
    - `currency` string, required
    - `occurred_at` string, date-time, required
    - `source` string, nullable, required
    - `external_ref` string, nullable, required
    - `attributed` boolean, required
  - `deduplicated` boolean, required
  - `request_id` string, required

## Other responses

- `201`: Success
- `400`: Validation failed
- `401`: Unauthorized: missing or invalid API key
- `402`: Insufficient wallet balance
- `403`: Forbidden: scope, plan limit, or suspension
- `404`: Not found
- `409`: Conflict (idempotency-key reuse or resource in use)
- `413`: Request body above the endpoint's size limit
- `422`: Understood but refused: the request is well-formed, the action is not permitted for this resource
- `429`: Rate limited
- `500`: Internal error
- `502`: An upstream provider refused or failed the request
- `503`: Channel or send queue unavailable

---

[API](https://skmtc.dev/blueticked/apis/blueticked-api.md) · [All operations](https://skmtc.dev/blueticked/apis/blueticked-api/llms.txt) · [OpenAPI document](https://skmtc.dev/blueticked/apis/blueticked-api/revisions/07132284f4ff?raw)
