Conversion API
Die Conversion API ermöglicht es Ihnen, Nicht-Stripe-Konversionen an Selgeo zu melden – Anmeldungen, Formulareinreichungen, kostenlose Testversionen, Upgrades oder beliebige benutzerdefinierte Ereignisse. Sie rufen sie von Ihrem Server nach einer Konversion auf, und Selgeo ordnet sie dem empfehlenden Partner basierend auf einer click_id oder einem promo_code zu.
API-Version: v1
Endpunkt: POST /api/v1/conversions
Voraussetzungen
- Das Selgeo-Snippet ist auf Ihrer Website installiert (Snippet-Setup), um
click_id-Werte zu erfassen - Ein geheimer API-Schlüssel (
sk_test_*odersk_live_*) aus dem Selgeo-Dashboard (Einstellungen > API-Schlüssel)
Authentifizierung
Die Conversion API verwendet geheime API-Schlüssel, die als Bearer-Token im Authorization-Header übergeben werden:
Authorization: Bearer sk_test_YOUR_KEY
| Schlüsselpräfix | Modus | Beschreibung |
|---|---|---|
sk_test_* | Test | Testmodus – Konversionen werden verfolgt, aber keine echten Provisionen |
sk_live_* | Live | Live-Modus – Konversionen erzeugen echte Provisionen |
Geheime Schlüssel (sk_*) dürfen nur in server-seitigem Code verwendet werden. Fügen Sie sie niemals in JavaScript ein, das im Browser, in mobilen Apps oder in einem anderen client-seitigen Code ausgeführt wird. Verwenden Sie öffentliche Schlüssel (pk_*) für das Tracking-Snippet.
Anforderungsformat
POST /api/v1/conversions
Content-Type: application/json
Authorization: Bearer sk_test_YOUR_KEY
Anforderungskörper
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
click_id | string (UUID) | Bedingt | Die Klick-ID vom Tracking-Snippet. Erforderlich, wenn promo_code nicht angegeben ist. |
promo_code | string | Bedingt | Ein Promo-Code für die Attribution. Erforderlich, wenn click_id nicht angegeben ist. |
external_transaction_id | string | Ja | Ihr eindeutiger Bezeichner für diese Konversion (z. B. Bestell-ID, Anmelde-ID). Wird für die Deduplizierung verwendet. Max. 255 Zeichen. |
event_type | string | Ja | Der Typ des Konversionsereignisses (z. B. signup, purchase, upgrade, trial_start). Max. 100 Zeichen. |
amount_cents | integer | Nein | Der Konversionswert in Cent. Standard: 0. |
currency | string | Bedingt | ISO 4217 3-Buchstaben-Währungscode (z. B. EUR, USD). Erforderlich wenn amount_cents > 0. |
occurred_at | string (ISO 8601) | Nein | Zeitpunkt der Konversion. Standardmäßig die aktuelle Zeit. |
prospect_email | string (E-Mail) | Nein | Die E-Mail-Adresse des konvertierenden Benutzers. Wird für die Selbst-Empfehlungs-Betrugserkennung verwendet. |
metadata | object | Nein | Beliebige Schlüssel-Wert-Paare für Ihren eigenen Gebrauch. Max. 4 KB. |
Sie müssen entweder click_id oder promo_code (oder beides) angeben. Wenn keines angegeben ist, gibt die API einen 422-Fehler zurück.
Antwortformat
Eine erfolgreiche Antwort gibt 201 Created mit den Konversionsdetails und der Attributionsentscheidung zurück:
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"source": "conversion_api",
"event_type": "signup",
"external_transaction_id": "signup_12345",
"amount_cents": 0,
"currency": null,
"occurred_at": "2026-04-02T10:30:00.000Z",
"is_test": true,
"attributed": true,
"attribution": {
"attribution_event_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"attribution_source": "link",
"participant_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"explanation": "Attributed to partner via tracking link click"
},
"created_at": "2026-04-02T10:30:01.000Z"
}
Antwortfelder
| Feld | Typ | Beschreibung |
|---|---|---|
id | string (UUID) | Die Konversionsdatensatz-ID. null wenn die Attribution fehlgeschlagen ist. |
source | string | Immer "conversion_api" für diesen Endpunkt. |
event_type | string | Gibt Ihren event_type zurück. |
external_transaction_id | string | Gibt Ihre Transaktions-ID zurück. |
amount_cents | integer | Der Konversionswert. |
currency | string | null | Der Währungscode. |
occurred_at | string | Zeitpunkt der Konversion. |
is_test | boolean | true wenn ein Testschlüssel verwendet wird, false wenn ein Live-Schlüssel. |
attributed | boolean | true wenn die Konversion einem Partner zugeordnet wurde. |
attribution.attribution_event_id | string | null | Die Attributionsereignis-ID. null wenn nicht attributiert. |
attribution.attribution_source | string | null | "link" (klick-basiert) oder "code" (Promo-Code). null wenn nicht attributiert. |
attribution.participant_id | string | null | Die Teilnehmer-ID des Partners. null wenn nicht attributiert. |
attribution.explanation | string | Eine menschenlesbare Erklärung der Attributionsentscheidung. |
Interpretation der Attributionsentscheidung
attributed | attribution_source | Bedeutung |
|---|---|---|
true | "link" | Konversion wurde einem Partner über einen Tracking-Link-Klick zugeordnet. |
true | "code" | Konversion wurde einem Partner über einen Promo-Code zugeordnet. |
false | null | Keine Attribution. Das explanation-Feld beschreibt warum (z. B. abgelaufener Klick, ungültiger Promo-Code, Partner nicht aktiv). |
Attributionspriorität
Wenn sowohl click_id als auch promo_code in derselben Anfrage angegeben werden, hat der Promo-Code Priorität:
- Selgeo versucht zunächst die Attribution via
promo_code. - Wenn der Promo-Code gültig und mit einem aktiven Partner verknüpft ist, wird die Konversion via
"code"attributiert. - Wenn der Promo-Code ungültig oder inaktiv ist, fällt Selgeo auf die
click_id-Attribution zurück.
Diese Prioritätsreihenfolge stellt sicher, dass Partner, die Promo-Codes verteilen, Gutschriften erhalten, auch wenn der Kunde auch über den Tracking-Link eines anderen Partners angekommen ist.
Beispiele
Einfache Konversion mit click_id
- curl
- JavaScript (Node.js)
- Python
- PHP
curl -X POST https://api.selgeo.com/api/v1/conversions \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"click_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"external_transaction_id": "signup_12345",
"event_type": "signup",
"amount_cents": 0
}'
const response = await fetch('https://api.selgeo.com/api/v1/conversions', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_test_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
click_id: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
external_transaction_id: 'signup_12345',
event_type: 'signup',
amount_cents: 0,
}),
});
const conversion = await response.json();
console.log('Attributiert:', conversion.attributed);
console.log('Partner:', conversion.attribution.participant_id);
import requests
response = requests.post(
"https://api.selgeo.com/api/v1/conversions",
headers={
"Authorization": "Bearer sk_test_YOUR_KEY",
"Content-Type": "application/json",
},
json={
"click_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"external_transaction_id": "signup_12345",
"event_type": "signup",
"amount_cents": 0,
},
)
conversion = response.json()
print(f"Attributiert: {conversion['attributed']}")
print(f"Partner: {conversion['attribution']['participant_id']}")
$ch = curl_init('https://api.selgeo.com/api/v1/conversions');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer sk_test_YOUR_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'click_id' => 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
'external_transaction_id' => 'signup_12345',
'event_type' => 'signup',
'amount_cents' => 0,
]),
]);
$response = curl_exec($ch);
$conversion = json_decode($response, true);
echo "Attributiert: " . ($conversion['attributed'] ? 'ja' : 'nein') . "\n";
echo "Partner: " . $conversion['attribution']['participant_id'] . "\n";
curl_close($ch);
Bezahlte Konversion mit Betrag
- curl
- JavaScript (Node.js)
- Python
- PHP
curl -X POST https://api.selgeo.com/api/v1/conversions \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"click_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"external_transaction_id": "order_67890",
"event_type": "purchase",
"amount_cents": 9900,
"currency": "EUR"
}'
const response = await fetch('https://api.selgeo.com/api/v1/conversions', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_test_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
click_id: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
external_transaction_id: 'order_67890',
event_type: 'purchase',
amount_cents: 9900,
currency: 'EUR',
}),
});
const conversion = await response.json();
import requests
response = requests.post(
"https://api.selgeo.com/api/v1/conversions",
headers={
"Authorization": "Bearer sk_test_YOUR_KEY",
"Content-Type": "application/json",
},
json={
"click_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"external_transaction_id": "order_67890",
"event_type": "purchase",
"amount_cents": 9900,
"currency": "EUR",
},
)
conversion = response.json()
$ch = curl_init('https://api.selgeo.com/api/v1/conversions');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer sk_test_YOUR_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'click_id' => 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
'external_transaction_id' => 'order_67890',
'event_type' => 'purchase',
'amount_cents' => 9900,
'currency' => 'EUR',
]),
]);
$response = curl_exec($ch);
$conversion = json_decode($response, true);
curl_close($ch);
Promo-Code-Attribution
- curl
- JavaScript (Node.js)
- Python
- PHP
curl -X POST https://api.selgeo.com/api/v1/conversions \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"promo_code": "PARTNER20",
"external_transaction_id": "order_99999",
"event_type": "purchase",
"amount_cents": 4900,
"currency": "EUR"
}'
const response = await fetch('https://api.selgeo.com/api/v1/conversions', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_test_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
promo_code: 'PARTNER20',
external_transaction_id: 'order_99999',
event_type: 'purchase',
amount_cents: 4900,
currency: 'EUR',
}),
});
const conversion = await response.json();
// conversion.attribution.attribution_source === "code"
import requests
response = requests.post(
"https://api.selgeo.com/api/v1/conversions",
headers={
"Authorization": "Bearer sk_test_YOUR_KEY",
"Content-Type": "application/json",
},
json={
"promo_code": "PARTNER20",
"external_transaction_id": "order_99999",
"event_type": "purchase",
"amount_cents": 4900,
"currency": "EUR",
},
)
conversion = response.json()
# conversion["attribution"]["attribution_source"] == "code"
$ch = curl_init('https://api.selgeo.com/api/v1/conversions');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer sk_test_YOUR_KEY',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'promo_code' => 'PARTNER20',
'external_transaction_id' => 'order_99999',
'event_type' => 'purchase',
'amount_cents' => 4900,
'currency' => 'EUR',
]),
]);
$response = curl_exec($ch);
$conversion = json_decode($response, true);
// $conversion['attribution']['attribution_source'] === 'code'
curl_close($ch);
Sowohl click_id als auch promo_code
Wenn beide angegeben werden, hat der Promo-Code Priorität:
curl -X POST https://api.selgeo.com/api/v1/conversions \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"click_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"promo_code": "PARTNER20",
"external_transaction_id": "order_55555",
"event_type": "purchase",
"amount_cents": 4900,
"currency": "EUR"
}'
Wenn PARTNER20 gültig ist, wird attribution_source "code" sein. Wenn PARTNER20 ungültig oder inaktiv ist, fällt Selgeo auf click_id zurück und attribution_source wird "link" sein.
click_id vom Frontend ans Backend übergeben
Ein häufiges Muster ist es, die click_id aus dem Snippet im Frontend zu lesen und sie mit der Formulareinreichung oder dem API-Aufruf zu senden:
// Frontend: click_id in Ihre Formulareinreichung einschließen
const form = document.getElementById('signup-form');
form.addEventListener('submit', (event) => {
event.preventDefault();
const clickId = __selgeo.getClickId();
const formData = new FormData(form);
fetch('/api/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: formData.get('email'),
name: formData.get('name'),
clickId: clickId, // kann null sein
}),
});
});
Dann auf Ihrem Backend, nach der Verarbeitung der Anmeldung, rufen Sie die Conversion API auf:
// Backend: Konversion an Selgeo melden
app.post('/api/signup', async (req, res) => {
const { email, name, clickId } = req.body;
// 1. Anmeldung in Ihrem System verarbeiten
const user = await createUser({ email, name });
// 2. An Selgeo melden (nur wenn clickId vorhanden ist)
if (clickId) {
await fetch('https://api.selgeo.com/api/v1/conversions', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_test_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
click_id: clickId,
external_transaction_id: `signup_${user.id}`,
event_type: 'signup',
amount_cents: 0,
}),
});
}
res.json({ success: true });
});
Wenn Sie traditionelle Formulareinreichungen (kein AJAX) verwenden, fügen Sie ein verstecktes Input-Feld hinzu, das das Snippet befüllt:
<form action="/api/signup" method="POST">
<input type="email" name="email" required />
<input type="hidden" name="clickId" id="selgeo-click-id" />
<button type="submit">Registrieren</button>
</form>
<script>
// Das versteckte Feld beim Laden des Formulars setzen
document.addEventListener('DOMContentLoaded', () => {
const clickId = typeof __selgeo !== 'undefined'
? __selgeo.getClickId()
: null;
if (clickId) {
document.getElementById('selgeo-click-id').value = clickId;
}
});
</script>
Fehlerbehandlung
HTTP-Statuscodes
| Status | Bedeutung | Aktion |
|---|---|---|
201 | Konversion erfolgreich erstellt | Lesen Sie das attributed-Feld, um zu prüfen, ob sie attributiert wurde |
400 | Validierungsfehler (fehlende/ungültige Felder) | Korrigieren Sie den Anforderungskörper gemäß den Fehlerdetails |
401 | Ungültiger oder fehlender API-Schlüssel | Prüfen Sie Ihren Authorization-Header und Schlüssel |
409 | Doppelte external_transaction_id | Diese Konversion wurde bereits gemeldet. Dies ist idempotent – keine Aktion erforderlich |
422 | Kein Attributionssignal oder Test/Live-Modus-Mismatch | Geben Sie entweder click_id/promo_code an, oder stellen Sie sicher, dass der Schlüsselmodus übereinstimmt (Test-click_id mit Testschlüssel) |
429 | Rate-Limit überschritten | Zurückhalten und wiederholen. Prüfen Sie den Retry-After-Header |
Fehler-Antwortformat
{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request",
"code": "VALIDATION_ERROR"
}
Rate-Limits
Die Conversion API ist auf 120 Anfragen pro Minute pro geheimem Schlüsselpräfix begrenzt. Wenn Sie dieses Limit überschreiten, gibt die API 429 Too Many Requests mit einem Retry-After-Header zurück, der angibt, wie viele Sekunden zu warten sind.
Für Hochvolumen-Integrationen stapeln Sie Ihre Konversionen oder verteilen Sie sie über die Zeit. Wenn Sie konsequent höhere Limits benötigen, kontaktieren Sie den Support.
Deduplizierung
Das external_transaction_id-Feld wird zur Deduplizierung verwendet. Wenn Sie dieselbe external_transaction_id zweimal mit demselben geheimen Schlüssel senden, gibt die zweite Anfrage 409 Conflict zurück. Dies macht die API sicher für Wiederholungsversuche bei Netzwerkfehlern – Sie erstellen keine doppelten Konversionen.
Modus-Mismatch
Test-Modus-Schlüssel (sk_test_*) können Konversionen nur click_id-Werten zuordnen, die durch öffentliche Test-Modus-Schlüssel (pk_test_*) generiert wurden. Ebenso funktionieren Live-Modus-Schlüssel nur mit Live-Modus-Klick-IDs. Bei einem Mismatch gibt die API 422 mit dem Code MODE_MISMATCH zurück.
Testen
- Richten Sie ein Testprogramm mit einem Partner und Tracking-Link im Selgeo-Dashboard ein.
- Besuchen Sie Ihre Website über den Tracking-Link, um einen Klick zu registrieren.
- Lesen Sie die click_id aus der Browser-Konsole:
__selgeo.getClickId()
- Senden Sie eine Testkonversion von Ihrem Terminal:
curl -X POST https://api.selgeo.com/api/v1/conversions \-H "Authorization: Bearer sk_test_YOUR_KEY" \-H "Content-Type: application/json" \-d '{"click_id": "CLICK_ID_HIER_EINFÜGEN","external_transaction_id": "test_001","event_type": "signup","amount_cents": 0}'
- Prüfen Sie die Antwort –
attributedsolltetrueundattribution_sourcesollte"link"sein. - Überprüfen Sie im Dashboard – die Konversion sollte in Analytics erscheinen, dem Testpartner zugeordnet.
Nächste Schritte
- Webhooks – Benachrichtigungen erhalten, wenn Konversionen attributiert und Provisionen erstellt werden
- Stripe Metadata – wenn Sie auch Stripe für einige Konversionen verwenden
- Testmodus – detaillierter Leitfaden zum Testen Ihrer Integration
- Fehlerbehebung – häufige Probleme und Lösungen