Documentation

Everything Oriva accepts, down to the field: the tracking code commands, the server API, the list of events and what each one becomes at each platform. To connect a platform step by step, use the Integrations pages, or Shopify if that is your store. If you code with an AI assistant, give it this page or its text version, /en/llms.txt.

Two ways to send an event

  • Key

    Tracking code (browser)
    pk_, public, in the page
    Server API
    sk_, secret, on your server
  • source

    Tracking code (browser)
    browser
    Server API
    server
  • Triggers an affiliate postback

    Tracking code (browser)
    No
    Server API
    Yes
  • ip and user_agent

    Tracking code (browser)
    Read by Oriva from the connection
    Server API
    Yours to provide (the visitor's)

A pk_ key can only send browser events, an sk_ key only server events. The affiliate postback only fires on a server sale: a public key is visible to everyone, so it must not be able to create a commission.

The tracking code

You'll find it, already filled in with your subdomain and key, in the “Tracking code” step of your workspace. It loads oriva.js from your tracking subdomain (t.<your-domain>) and exposes one function, oriva(command, …). You can call it before the script has loaded: calls are queued and replayed.

<script async src="https://t.<your-domain>/oriva.js"></script>
<script>window.oriva=window.oriva||function(){(oriva.q=oriva.q||[]).push(arguments)};oriva('init',{key:'pk_…'});</script>

oriva('init', options)

Already in the code you were given. Sends a page_view on load.

  • key

    What it does
    Your pk_ key. Required.
  • host

    What it does
    The tracking subdomain. Defaults to the one oriva.js is loaded from.
  • page_view

    What it does
    false to skip the automatic page_view.
  • consent_wait

    What it does
    Maximum time, in milliseconds, that events wait for your banner to give consent back when the page loads. 1500 by default, 0 to not wait.

Oriva starts without ad consent. Until you have called oriva('consent', { ads: true }), events are still sent, but without a visitor cookie, click id, email or phone, and nothing is sent to Meta, TikTok, Google Ads or ChatGPT Ads.

oriva('consent', { ads: false }) withdraws consent and clears the visitor cookie. Consent is only kept in memory: on every page, your banner has to give it back. To leave it time to do so, events wait for its signal for up to 1.5 seconds when the page loads (the consent_wait option), then go out without consent if it has not come. They go out at once if the visitor leaves the page. Examples for Axeptio, Didomi, Cookiebot, tarteaucitron, Complianz and CookieYes.

oriva('identify', data)

Remembers the visitor's email, phone or other data for every following event on the page. They are normalized and hashed with SHA-256 in the browser, before they leave. Call it before a lead or a purchase, for example when the form is submitted.

oriva('identify', { email: 'jane@example.com', phone: '06 12 34 56 78' });

oriva('track', name, data)

Sends an event.

oriva('track', 'purchase', {
  event_id: 'commande-1001',
  value: 49.9,
  currency: 'EUR',
  order_id: '1001',
  content_ids: ['sku-42'],
});
  • event_id: your stable reference. Without it, the code generates a random one, and the same sale also sent by your server will be counted twice at the platforms.
  • value: in units, not in cents (49.9 means 49.90).
  • currency: 3-letter ISO code. When absent, Oriva uses your domain's currency.
  • user_data: like identify, but for this event only.
  • Any other key goes into custom_data (see what is forwarded to the platforms).

On purchase, refreshing the thank-you page sends the same event_id again: the sale is not counted twice.

What the code captures on its own

Only with ad consent, when the page loads:

  • the click ids in the URL: fbclid, ttclid, gclid, gbraid, wbraid, msclkid, aff_click_id, oppref;
  • the utm_source, utm_medium, utm_campaign, utm_content, utm_term parameters;
  • subid, s1, s2, s3, s4, s5;
  • the cookies of the pixels already on the page: _fbc, _fbp (Meta), _ttp, ttclid (TikTok), __oppref, __obref (OpenAI).

You don't have to do anything for that.

The server API

POST https://t.<your-domain>/api/v1/collect
X-Oriva-Key: sk_…
Content-Type: application/json

One event per request, with the fields below. Full example and good practices. Your secret key stays on your server, in an environment variable.

The fields of an event

Valid for the server API. The tracking code fills in event_id, source, occurred_at, url, referrer, consent, visitor_id and the click ids itself.

  • event_id

    Required
    Yes
    Notes
    Text, 128 characters at most. Unique per domain: a second request with the same event_id is accepted but ignored.
  • name

    Required
    Yes
    Notes
    One of the events, or custom:<name>.
  • source

    Required
    No
    Notes
    browser or server, browser by default. Must match the key.
  • occurred_at

    Required
    No
    Notes
    ISO 8601 date with time zone. Now by default. At most 7 days in the past and 5 minutes in the future.
  • value

    Required
    No
    Notes
    Positive number, in units and not in cents: 49.9 means 49.90.
  • currency

    Required
    No
    Notes
    3-letter ISO code (EUR). When absent, Oriva uses your domain's currency.
  • consent

    Required
    No
    Notes
    { "ads": true } or { "ads": false }. When absent, Oriva treats the visitor as having refused.
  • visitor_id

    Required
    No
    Notes
    UUID: the visitor's or_vid cookie, to tie the sale to their visit.
  • user_data

    Required
    No
    Notes
    Object: email, phone, first_name, last_name, zip, external_id. See Personal data.
  • custom_data

    Required
    No
    Notes
    Free-form object, 8 KB at most. See custom_data.
  • click_ids

    Required
    No
    Notes
    Object: fbclid, ttclid, gclid, gbraid, wbraid, msclkid, aff_click_id, fbc, fbp, ttp, oppref, obref.
  • utm

    Required
    No
    Notes
    Object: source, medium, campaign, content, term.
  • sub_ids

    Required
    No
    Notes
    Object: subid, s1, s2, s3, s4, s5.
  • url, referrer

    Required
    No
    Notes
    Absolute URL. Filled in by the tracking code.
  • ip, user_agent

    Required
    No
    Notes
    Server only: the visitor's, never your server's. Rejected on a browser event.

An empty string counts as absent. Unknown fields are ignored.

Events

  • page_view

    Sent to the platforms
    No
    What it is
    A page view. Sent automatically by the tracking code.
  • view_content

    Sent to the platforms
    No
    What it is
    A product page or other content viewed.
  • add_to_cart

    Sent to the platforms
    If you turn it on for the destination (Meta, TikTok, ChatGPT Ads)
    What it is
    An add to cart.
  • initiate_checkout

    Sent to the platforms
    If you turn it on for the destination (Meta, TikTok, ChatGPT Ads)
    What it is
    The start of checkout.
  • lead

    Sent to the platforms
    Yes
    What it is
    A contact: form, quote request, list signup.
  • purchase

    Sent to the platforms
    Yes
    What it is
    A purchase.
  • complete_registration

    Sent to the platforms
    Yes
    What it is
    An account creation.
  • subscribe

    Sent to the platforms
    Yes
    What it is
    A paid subscription started.
  • start_trial

    Sent to the platforms
    Yes
    What it is
    A trial started.
  • custom:<name>

    Sent to the platforms
    Yes
    What it is
    Any other event that matters to you: an outbound click, a download.

The first four are for your Oriva dashboard. They are not sent to any platform. The others become conversions, under these names:

  • lead

    Meta and TikTok
    Lead
    ChatGPT Ads
    lead_created
  • purchase

    Meta and TikTok
    Purchase
    ChatGPT Ads
    order_created
  • complete_registration

    Meta and TikTok
    CompleteRegistration
    ChatGPT Ads
    registration_completed
  • subscribe

    Meta and TikTok
    Subscribe
    ChatGPT Ads
    subscription_created
  • start_trial

    Meta and TikTok
    StartTrial
    ChatGPT Ads
    trial_started
  • add_to_cart

    Meta and TikTok
    AddToCart
    ChatGPT Ads
    items_added
  • initiate_checkout

    Meta and TikTok
    InitiateCheckout
    ChatGPT Ads
    checkout_started
  • custom:<name>

    Meta and TikTok
    <name>
    ChatGPT Ads
    <name>, as a custom event
  • Google Ads: a destination follows a single event, the one you choose when you create it (any of those that go to the platforms). To follow a lead and a purchase, create two destinations.
  • Affiliate postback: every event that goes to the platforms, or a single one if you pick one, and only if they come from your server.
  • custom:<name>: <name> is 1 to 64 characters long, made of lowercase letters, digits, _ and -, and starts with a letter or a digit (custom:clic_partenaire). For ChatGPT Ads, first create a conversion event with the exact name (clic_partenaire) in your ads manager: without it, OpenAI accepts the request but counts nothing.

custom_data

Oriva stores everything you put there (up to 8 KB), but only forwards part of it:

  • Meta and TikTok only receive these keys: content_ids, content_id, content_name, content_type, content_category, contents, num_items, order_id, predicted_ltv, search_string, status, delivery_category, quantity, query. Any other key stays with Oriva.
  • ChatGPT Ads receives the same ones, plus plan_id on subscribe and start_trial.
  • Google Ads does not read custom_data.
  • Postback: payout feeds the {payout} variable of your URL. All the variables.

order_id is also used by the Health tab to spot the same order sent by both the browser and the server.

Personal data

Fields accepted in user_data: email, phone, first_name, last_name, zip, external_id.

Oriva never keeps these values in clear text: they are normalized, then hashed with SHA-256 before they are written. You can send them in clear text or already hashed (64 hexadecimal characters): an already hashed value is kept as is, provided you normalized it the same way:

  • everything: leading and trailing spaces removed, lowercase;
  • phone: digits only, with the country code, without + (33612345678). A number that starts with 0 and has no country code is read as French;
  • postal code: no spaces or hyphens, 5 characters at most;
  • external_id: case kept.

Without ad consent, user_data is not stored at all.

Responses and errors

Success: 202.

{ "ok": true, "event_id": "commande-1001", "deduped": false }

deduped: true: this event_id was already known, the event is ignored. buffered: true: Oriva set it aside during an incident and will write it as soon as possible. In both cases, don't send it again.

Errors: always { "ok": false, "error": "…" }.

  • 400

    error
    invalid_payload
    What it means
    A field is invalid. issues gives the path and the reason for each one.
  • 400

    error
    invalid_payload:ip_and_user_agent_are_server_only
    What it means
    ip or user_agent sent on a browser event.
  • 401

    error
    missing_api_key
    What it means
    No key, neither in the X-Oriva-Key header nor in ?k=.
  • 401

    error
    invalid_api_key:malformed
    What it means
    The key does not have the right format.
  • 401

    error
    invalid_api_key:unknown
    What it means
    Unknown key.
  • 401

    error
    invalid_api_key:revoked
    What it means
    Revoked key.
  • 401

    error
    key_scope:public_key_cannot_send_server_events
    What it means
    A pk_ key sending a server event.
  • 401

    error
    key_scope:secret_key_cannot_send_browser_events
    What it means
    An sk_ key sending a browser event.
  • 403

    error
    origin_not_allowed
    What it means
    Call from a browser, on a site other than your domain.
  • 429

    error
    rate_limited
    What it means
    Too many calls. retry_after and the Retry-After header tell you how many seconds to wait.

Only a 429 can be retried as is. A 400 or a 401 will fail the same way until the request or the key changes.

The read API

Pro and Agency plans. An rk_ token, created in the app (account menu, API), to pull your numbers into your own tools: a spreadsheet, a client report, an alert. It can't change anything. To send events, use the server API and an sk_ key, on every plan.

curl -H "Authorization: Bearer rk_…" \
  https://www.orivaforge.com/api/v1/read/properties

All routes are GET and answer in JSON. Amounts in cents, dates in ISO (UTC). :id is a domain's id, returned by the first route.

No code needed: the API page of the app gives you a ready-to-paste Google Sheets script that fills a tab every morning, keeps a history and can warn you on Slack when a destination starts failing.

Your domains

GET /api/v1/read/properties: The account's domains, with the id to pass to the other routes.

[
  {
    "id": "0192f3a4-7b1c-7d2e-9f10-2a3b4c5d6e7f",
    "domain": "boutique.fr",
    "name": "boutique.fr",
    "status": "active"
  }
]

Health

GET /api/v1/read/properties/:id/health: The same state as the Health tab: each destination, the checks to fix, collection.

{
  "diagnostics": [
    { "code": "DESTINATION_FAILING", "severity": "high", "message": "…" }
  ],
  "destinations": [
    {
      "name": "Meta",
      "kind": "meta_capi",
      "displayStatus": "failing",
      "sent": 41,
      "failed": 5,
      "lastFailureError": "HTTP 400: OAuthException code 190 …",
      "deliveredRate": 0.89
    }
  ],
  "pulse": { "lastEventReceivedAt": "2026-09-27T06:58:12.000Z", "browserEvents24h": 1320 }
}

Key figures

GET /api/v1/read/properties/:id/summary: Conversions, revenue, spend, ROAS and the gap with the platforms over the period.

  • from, to: ISO dates (2026-09-01), last 30 days by default, 90 days at most.
{
  "conversions": 128,
  "purchases": 97,
  "revenueByCurrency": [
    { "currency": "EUR", "revenueCents": 684250, "spendCents": 210000, "roas": 3.26 }
  ],
  "platformGap": {
    "total": -12,
    "orivaConversions": 88,
    "platformConversions": 100,
    "ratio": -0.12,
    "matchedRows": 14
  }
}

Delivery log

GET /api/v1/read/properties/:id/conversions: Recent conversions and their status at each destination.

  • limit: 50 by default, 200 at most. Newest first.
[
  {
    "id": "0192f3b8-…",
    "occurredAt": "2026-09-27T06:41:03.000Z",
    "eventName": "purchase",
    "valueCents": 5990,
    "currency": "EUR",
    "campaign": "rentree-2026",
    "orderId": "1042",
    "deliveries": [
      { "destinationName": "Meta", "destinationKind": "meta_capi", "status": "sent", "error": null }
    ]
  }
]

Click to conversion delay

GET /api/v1/read/properties/:id/attribution-delays: Per campaign, the median delay and the one by which 8 conversions in 10 had arrived.

  • from, to: same as for the key figures.
[
  { "campaign": "rentree-2026", "conversions": 42, "medianDelayMs": 5400000, "p80DelayMs": 172800000 }
]

Limits and errors

  • 60 calls per minute and per token.
  • 90 days at most per call, 30 by default.
  • 200 conversions at most per call.
  • 401

    error
    missing_token
    What it means
    No Authorization: Bearer <token> header, or it is malformed.
  • 401

    error
    invalid_token
    What it means
    Unknown or revoked token.
  • 403

    error
    plan_restricted
    What it means
    The account is no longer on a Pro or Agency plan.
  • 404

    error
    not_found
    What it means
    This domain doesn't exist, or doesn't belong to the token's account.
  • 429

    error
    rate_limited
    What it means
    More than 60 calls per minute. The Retry-After header says in how many seconds to retry.

Errors use the { "error": "…" } format. Only a 429 can be retried as is.

Further reading

Try Oriva for free.

14 days to connect your site and watch your sales reach your platforms.

Start free trial