Idempotency
Every endpoint accepts an optional Idempotency-Key header. Use it to safely retry requests when your network or our backend has a hiccup.
How it works
-
Your first request runs normally. We store the response body keyed on
(apiKeyId, idempotencyKey). -
Any request with the same key within 24h returns the same response with a header:
X-Idempotent-Replay: true -
Two days later the cached row is purged. Calling with the same key again will re-execute the request.
Guidelines
- The key is string ≤ 128 characters.
- Generate one per business action:
order_<order_id>,signup_<user_id>_<timestamp>, etc. - Don’t reuse keys across different operations. Each key represents one logical “attempt”.
- The Idempotency-Key is scoped per API key — two different keys may use the same string without conflict.
Example
Fire a Purchase event with retry safety:
curl -X POST https://adtarget.io/api/v1/events/conversion \
-H "Authorization: Bearer atk_live_..." \
-H "Idempotency-Key: order_98765" \
-H "Content-Type: application/json" \
-d '{ "telegramUserId": 1234567890, "channelId": "-1001234567890", "eventType": "Purchase", "value": 49.00, "currency": "USD" }'If your network drops the response and you retry with the same Idempotency-Key, AdTarget returns the original conversionId without firing a second Meta event.
We don’t validate that the body matches the original request. If you reuse a key with a different body, you’ll get back the original response — not the new one. Always generate a fresh key for a different intent.
What gets cached
- The full response body and HTTP status code.
- The
conversionIdfor forensic linking.
We do not cache anything about the request body itself. The key is the sole replay identifier.
Combined with Meta dedup
AdTarget has two layers of duplicate protection:
Idempotency-Keyreplays the same API response for the same logical request within 24h.- Conversion upsert logic reuses recent matching events for the same resolved site, Telegram user, channel, and event type. Pending/failed/skipped events are updated and retried; sent events are returned with
deduplicated: trueand are not sent again.
Meta CAPI also deduplicates within 48h based on event_id.
Optionale Besuchs-Deduplizierung für /track/init
POST /backend/track/init akzeptiert optional eine UUID visitRequestId im JSON-Body. Dies ist das bevorzugte öffentliche Feld; der bisherige Name gatewayRequestId bleibt als rückwärtskompatibler Alias gültig. Werden beide Felder gesendet, müssen sie dieselbe UUID enthalten; unterschiedliche Werte führen zu HTTP 400. Verwende dieselbe UUID bei Wiederholungen desselben Seitenaufrufs: AdTarget gibt denselben Besuch zurück und ergänzt nur zuvor fehlende Attributionsdaten. Vorhandene Werte und das Routing werden nie überschrieben. Wiederholungen müssen dieselben websiteId, tempId und sessionId verwenden; eine geänderte Browser-Identität wird abgelehnt.
Ohne visitRequestId bleibt das bisherige Verhalten unverändert: Jeder Aufruf erzeugt einen eigenen Besuch, auch innerhalb derselben Browser-Sitzung. Verwende für jeden echten neuen Seitenaufruf eine neue UUID.
Keyless direct-invite-Wiederholungen
POST /backend/track/direct-invite verwendet visitRequestId (UUID) im Body, nicht den Header Idempotency-Key. Der bisherige Alias gatewayRequestId bleibt gültig. Verwende für Wiederholungen derselben Weiterleitung dieselbe UUID.
Wiederholte Aufrufe erzeugen einen Besuch, einen PageView-Eintrag und eine Telegram-Einladung. Sie ergänzen nur fehlende Felder und überschreiben keine vorhandenen Werte. websiteId, tempId und sessionId müssen den ursprünglichen Besuch identifizieren. Für einen neuen Klick ist eine neue UUID erforderlich.