API de conversion
L'API de conversion vous permet de signaler des conversions non-Stripe à Selgeo — inscriptions, soumissions de formulaires, essais gratuits, mises à niveau, ou tout événement personnalisé. Vous l'appelez depuis votre serveur après qu'une conversion se produit, et Selgeo l'attribue au partenaire référent en se basant sur un click_id ou un promo_code.
Version API : v1
Point de terminaison : POST /api/v1/conversions
Prérequis
- Le snippet Selgeo est installé sur votre site web (Configuration du snippet) pour capturer les valeurs de
click_id - Une clé API secrète (
sk_test_*ousk_live_*) depuis le tableau de bord Selgeo (Paramètres > Clés API)
Authentification
L'API de conversion utilise des clés API secrètes passées comme jeton Bearer dans l'en-tête Authorization :
Authorization: Bearer sk_test_YOUR_KEY
| Préfixe de clé | Mode | Description |
|---|---|---|
sk_test_* | Test | Mode test — les conversions sont suivies mais sans vraies commissions |
sk_live_* | Live | Mode live — les conversions génèrent de vraies commissions |
Les clés secrètes (sk_*) ne doivent être utilisées que dans le code côté serveur. Ne les incluez jamais dans du JavaScript qui s'exécute dans le navigateur, dans des applications mobiles, ou dans tout code côté client. Utilisez les clés publiques (pk_*) pour le snippet de suivi.
Format de la requête
POST /api/v1/conversions
Content-Type: application/json
Authorization: Bearer sk_test_YOUR_KEY
Corps de la requête
| Champ | Type | Requis | Description |
|---|---|---|---|
click_id | string (UUID) | Conditionnel | L'ID de clic du snippet de suivi. Requis si promo_code n'est pas fourni. |
promo_code | string | Conditionnel | Un code promo pour l'attribution. Requis si click_id n'est pas fourni. |
external_transaction_id | string | Oui | Votre identifiant unique pour cette conversion (ex. ID de commande, ID d'inscription). Utilisé pour la déduplication. Max 255 caractères. |
event_type | string | Oui | Le type d'événement de conversion (ex. signup, purchase, upgrade, trial_start). Max 100 caractères. |
amount_cents | integer | Non | La valeur de la conversion en centimes. Par défaut : 0. |
currency | string | Conditionnel | Code de devise ISO 4217 à 3 lettres (ex. EUR, USD). Requis quand amount_cents > 0. |
occurred_at | string (ISO 8601) | Non | Quand la conversion s'est produite. Par défaut à l'heure actuelle. |
prospect_email | string (email) | Non | L'adresse email de l'utilisateur effectuant la conversion. Utilisé pour la détection de fraude d'auto-référencement. |
metadata | object | Non | Paires clé-valeur arbitraires pour votre propre usage. Max 4 Ko. |
Vous devez fournir soit click_id soit promo_code (ou les deux). Si aucun n'est fourni, l'API retourne une erreur 422.
Format de la réponse
Une réponse réussie retourne 201 Created avec les détails de la conversion et la décision d'attribution :
{
"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"
}
Champs de réponse
| Champ | Type | Description |
|---|---|---|
id | string (UUID) | L'ID de l'enregistrement de conversion. null si l'attribution a échoué. |
source | string | Toujours "conversion_api" pour ce point de terminaison. |
event_type | string | Retourne votre event_type. |
external_transaction_id | string | Retourne votre ID de transaction. |
amount_cents | integer | La valeur de la conversion. |
currency | string | null | Le code de devise. |
occurred_at | string | Quand la conversion s'est produite. |
is_test | boolean | true si une clé test est utilisée, false si une clé live. |
attributed | boolean | true si la conversion a été attribuée à un partenaire. |
attribution.attribution_event_id | string | null | L'ID de l'événement d'attribution. null si non attribué. |
attribution.attribution_source | string | null | "link" (basé sur le clic) ou "code" (code promo). null si non attribué. |
attribution.participant_id | string | null | L'ID de participant du partenaire. null si non attribué. |
attribution.explanation | string | Une explication lisible par l'humain de la décision d'attribution. |
Interprétation de la décision d'attribution
attributed | attribution_source | Signification |
|---|---|---|
true | "link" | Conversion attribuée à un partenaire via un clic sur un lien de suivi. |
true | "code" | Conversion attribuée à un partenaire via un code promo. |
false | null | Pas d'attribution. Le champ explanation décrit pourquoi (ex. clic expiré, code promo invalide, partenaire inactif). |
Priorité d'attribution
Quand click_id et promo_code sont tous les deux fournis dans la même requête, le code promo a la priorité :
- Selgeo tente d'abord l'attribution via
promo_code. - Si le code promo est valide et lié à un partenaire actif, la conversion est attribuée via
"code". - Si le code promo est invalide ou inactif, Selgeo revient à l'attribution via
click_id.
Cet ordre de priorité garantit que les partenaires qui distribuent des codes promo reçoivent du crédit même quand le client est également arrivé via le lien de suivi d'un autre partenaire.
Exemples
Conversion de base avec 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('Attribué :', conversion.attributed);
console.log('Partenaire :', 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"Attribué : {conversion['attributed']}")
print(f"Partenaire : {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 "Attribué : " . ($conversion['attributed'] ? 'oui' : 'non') . "\n";
echo "Partenaire : " . $conversion['attribution']['participant_id'] . "\n";
curl_close($ch);
Conversion payante avec montant
- 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);
Attribution par code promo
- 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);
Passer click_id du frontend au backend
Un modèle courant est de lire le click_id depuis le snippet sur le frontend et de l'envoyer avec la soumission du formulaire ou l'appel API :
// Frontend : inclure click_id dans votre soumission de formulaire
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, // peut être null
}),
});
});
Puis sur votre backend, après avoir traité l'inscription, appelez l'API de conversion :
// Backend : signaler la conversion à Selgeo
app.post('/api/signup', async (req, res) => {
const { email, name, clickId } = req.body;
// 1. Traiter l'inscription dans votre système
const user = await createUser({ email, name });
// 2. Signaler à Selgeo (seulement si clickId est présent)
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 });
});
Gestion des erreurs
Codes de statut HTTP
| Statut | Signification | Action |
|---|---|---|
201 | Conversion créée avec succès | Lisez le champ attributed pour vérifier si elle a été attribuée |
400 | Erreur de validation (champs manquants/invalides) | Corrigez le corps de la requête selon les détails de l'erreur |
401 | Clé API invalide ou manquante | Vérifiez votre en-tête Authorization et votre clé |
409 | external_transaction_id en double | Cette conversion a déjà été signalée. C'est idempotent — aucune action requise |
422 | Pas de signal d'attribution ou incompatibilité test/live | Fournissez click_id/promo_code, ou assurez-vous que le mode de la clé correspond (click_id test avec clé test) |
429 | Limite de débit dépassée | Attendez et réessayez. Vérifiez l'en-tête Retry-After |
Format de réponse d'erreur
{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request",
"code": "VALIDATION_ERROR"
}
Limites de débit
L'API de conversion est limitée à 120 requêtes par minute par préfixe de clé secrète. Si vous dépassez cette limite, l'API retourne 429 Too Many Requests avec un en-tête Retry-After indiquant combien de secondes attendre.
Déduplication
Le champ external_transaction_id est utilisé pour la déduplication. Si vous envoyez le même external_transaction_id deux fois avec la même clé secrète, la deuxième requête retourne 409 Conflict. Cela rend l'API sûre pour les nouvelles tentatives en cas d'échecs réseau — vous ne créerez pas de conversions en double.
Incompatibilité de mode
Les clés en mode test (sk_test_*) ne peuvent attribuer des conversions qu'aux IDs de clic générés par des clés publiques en mode test (pk_test_*). De même, les clés en mode live ne fonctionnent qu'avec des IDs de clic en mode live. En cas d'incompatibilité, l'API retourne 422 avec le code MODE_MISMATCH.
Tests
- Configurez un programme de test avec un partenaire et un lien de suivi dans le tableau de bord Selgeo.
- Visitez votre site via le lien de suivi pour enregistrer un clic.
- Lisez le click_id depuis la console du navigateur :
__selgeo.getClickId()
- Envoyez une conversion de test depuis votre 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": "COLLEZ_CLICK_ID_ICI","external_transaction_id": "test_001","event_type": "signup","amount_cents": 0}'
- Vérifiez la réponse —
attributeddoit êtretrueetattribution_sourcedoit être"link". - Vérifiez dans le tableau de bord — la conversion doit apparaître dans Analytics, attribuée au partenaire de test.
Prochaines étapes
- Webhooks — recevoir des notifications quand les conversions sont attribuées et les commissions créées
- Stripe Metadata — si vous utilisez aussi Stripe pour certaines conversions
- Mode test — guide détaillé pour tester votre intégration
- Dépannage — problèmes courants et solutions