ingestion

Send data in

The tracker snippet covers pageviews and events automatically. These endpoints let your backend push payments, tie a session to a known user, and shorten links.

POST/api/v1/payment
Record a payment from any provider (Paddle, Polar, WooCommerce, custom). Attribute it to a visit with ref or email.
ParamTypeDescription
amountreqnumberAmount (negative or refund:true for a refund).
currencyreqstringISO currency, e.g. USD.
transaction_idreqstringYour id, used for dedup.
refstringwindow.datalenk.ref captured on your site.
emailstringCustomer email, hashed server-side for attribution.
refundbooleanMark this as a refund.
curl -X POST https://datalenk.com/api/v1/payment \
  -H "Authorization: Bearer dlk_…" -H "Content-Type: application/json" \
  -d '{ "amount": 29.99, "currency": "USD", "transaction_id": "txn_98hj", "ref": "…" }'
POST/api/v1/identify
Link a session to a known email so future payments attribute correctly.
POST/api/v1/links
Upsert tracked-link metadata (this is how Lenkli pushes its links in). Clicks and revenue join by slug. It does not create links: Lenkli does that.
POST/api/event
The endpoint the dl.js snippet posts to. You normally never call this by hand; the tracker does.

The server beacon (AI crawlers)

AI crawlers do not run JavaScript, so no client-side script can ever see them, ours included. To get AI visibility (who crawls you, who cites you, and what that turns into), send one call per request from your middleware or edge function. We identify the crawler, and we verify it against published IP ranges and reverse DNS, so a spoofed user-agent cannot pollute your numbers.

POST/api/server
Server-side beacon: report a request (user-agent, path, IP) so AI crawlers show up in your dashboard.
middleware.ts (Next.js)
export function middleware(req: Request) {
  // fire and forget, never block the response
  fetch("https://datalenk.com/api/server", {
    method: "POST",
    headers: { "Authorization": "Bearer dlk_…", "Content-Type": "application/json" },
    body: JSON.stringify({
      site_id: 42,
      ua: req.headers.get("user-agent") ?? "",
      ip: req.headers.get("cf-connecting-ip") ?? req.headers.get("x-forwarded-for") ?? "",
      path: new URL(req.url).pathname,
    }),
  }).catch(() => {});
  return;
}
Which key to use. The ingestion endpoints below (/payment, /identify, /links) take an ordinary API key with the write scope (Dashboard, API: dlk_live_…), like every other write endpoint. Older workspace tokens still work, but a scoped key is worth switching to: it can be revoked on its own without breaking your other integrations, and a key that only imports payments has no reason to be able to read visitor journeys.

The tracker

Every site needs the snippet once, on all pages. Creating a site returns it: including your site's data-key and data-consent="simple".

index.html
<script defer data-site="42" data-key="dk_..." data-consent="simple" src="https://in.datalenk.com/dl.js"></script>

By default the tracker is cookieless: it writes nothing to visitors' devices (no cookies, no localStorage). It still reads standard browser information (language, screen size, referrer) and sends it with each event, so the law on trackers applies: depending on what you measure, your visitors' consent can be required (see Visitor consent below). Optional attributes:

  • data-consent="simple": before your visitor's consent, only Simple measurement runs (pages, referring domain, device, country, region and city; no campaign parameters, no click ids, no marked links, no payment linking, no A/B test, no replay). Everything else starts once your visitor accepts. A snippet without the attribute behaves exactly the same way.
  • data-consent="wait": nothing at all is sent or stored before your visitor accepts.
  • data-banner: Datalenk shows its own consent banner to your visitors (see below), with data-banner-color="#rrggbb" and data-banner-policy="https://…" (your privacy policy).
  • data-persist: enables the Persistent layer (returning visitors, cohorts, multi-day attribution) by storing a first-party pseudonymous id (localStorage + datalenk_ref cookie), only after your visitor's consent. The id lives 90 days from the day it is first stored, and is never extended on later visits. Enable it from Settings → Tracking depth first.
  • data-replay: records pointer, scroll and click positions (no text, no input), only after your visitor's consent.
  • data-no-cookie, with data-persist, keeps the id in localStorage only (no cookie).
  • data-key: your site's public ingestion key (anti-spoofing). Shown in Settings → Install.

Tying a visit to its source and to a sale (campaign parameters, click ids, the Lenkli marker, links to Stripe and Calenkli, the return from Stripe, identify()), recognising a visitor from one day to the next (Persistent layer), showing A/B test versions and recording a session (replay) all require your visitors' prior consent, in every mode. The tracker waits for it: until then the visit gets Simple measurement (or nothing with data-consent="wait"), window.datalenk.ref stays empty, nothing is stored, identify() calls wait in the page and experiment() returns null (your normal version, not counted). A refusal, or a withdrawal, cuts all of it. Call this from your consent banner:

your consent banner
// "Accept all"
datalenk.consent(true);
// "Refuse all", or consent withdrawn later: deletes the id stored by Datalenk and unmarks links
datalenk.consent(false);
// Purpose by purpose (a missing key means refused)
datalenk.consent({ attribution: true, experiments: false, replay: false });

// If your banner may answer before dl.js has loaded, queue the call instead:
(window.datalenkQueue = window.datalenkQueue || []).push(["consent", true]);

datalenk.consentStatus();  // "pending" | "granted" | "partial" | "denied" | "off"
datalenk.consentChoices(); // { attribution, experiments, replay }, or null before an answer

Three purposes: attribution (sources and sales, and the Persistent layer if you turned it on), experiments (A/B tests), replay (if you turned it on). Call it on every page where the visitor has answered (your banner remembers the choice). In a banner, "Refuse" must be as easy as "Accept", and visitors must be able to change their mind at any time. Step by step, with a complete example: your own consent banner (en français).

Add data-banner to the snippet. Datalenk shows its banner in your visitor's language (French or English): "Accept" and "Refuse" side by side, the same size, and "Choose" for purpose by purpose (nothing ticked in advance). The choice is kept 6 months in a datalenk_consent cookie (it only holds the answer) and replayed on every page. Any element with data-datalenk-consent, such as a "Cookie settings" link in your footer, reopens it; so does datalenk.showConsent().

index.html
<script defer data-site="42" data-key="dk_..." data-consent="simple" data-banner data-banner-policy="https://example.com/privacy" src="https://in.datalenk.com/dl.js"></script>

<a href="#" data-datalenk-consent>Cookie settings</a>

Opt-out link for your privacy policy. Any element with data-datalenk-optout becomes a "Stop measuring me on this site" link: it sets a first-party opt-out cookie (13 months), deletes the Datalenk id and stops the tracker. data-datalenk-optin lets the visitor come back.

privacy policy
<a href="#" data-datalenk-optout data-optout-done="You are no longer measured on this site.">Stop measuring me on this site</a>

Your obligations, in plain words

  1. For the measurement of your site, you are the data controller; Datalenk is your processor, under our data processing agreement.
  2. Simple measurement writes nothing on your visitors' devices: still describe it in your privacy policy and add our “Stop measuring me” link.
  3. Everything else needs your visitors' consent before it turns on: revenue by channel and by campaign, UTM parameters and click ids (Lenkli, Google, Meta), the link with Calenkli and Stripe, identify(), the Persistent layer, A/B tests, replay. In your banner, “Refuse” must be as easy as “Accept”, and your visitors must be able to change their mind at any time.
  4. Keep a dated record of your settings and of your banner: it is up to you to be able to show that you follow these rules.
  5. Datalenk is neither “validated” nor “certified” by the CNIL: do not write that it is.

Version française : Accord de traitement des données, § 11.