Erreurs
Cette surface d'API est destinée aux partenaires d'intégration construisant sur le réseau Rokt. Les partenaires e-commerce de Rokt intégrant des placements sur leur propre processus de paiement devraient utiliser à la place les documents pour développeurs Rokt Ecommerce.
Chaque réponse d'erreur de l'API des Partenariats utilise la même enveloppe JSON : identique en forme aux réponses de succès, mais avec error rempli et data: null. Cette page est la référence pour ce que chaque statut signifie, les scénarios qui les produisent, et comment déboguer une réponse inattendue devant vous en ce moment.
Enveloppe de réponseLien direct vers Enveloppe de réponse
Chaque réponse (succès et erreur) a cette forme :
{
"status": 400,
"error": "BadRequest",
"message": "store_identifier https://acme is not a valid URL",
"request_id": "0e3a1b9c-1234-4abc-9def-aaaabbbbcccc",
"data": null
}
statusintegerReflète le code de statut HTTP (200 en cas de succès, 400/401/403/404/409/422/5xx en cas d'erreur).
errorstring | nullCode d'erreur stable lié au statut HTTP : par exemple BadRequest (400), Unauthorized (401), Forbidden (403), NotFound (404), Conflict (409), ValidationFailed (422), RateLimitExceeded (429), InternalServerError (500). Sûr à utiliser. null en cas de succès.
messagestringDescription lisible par l'homme de ce qui a mal tourné (ou "ok" en cas de succès). Sûr à afficher aux opérateurs internes ; ne pas afficher tel quel aux marchands finaux.
request_idstringID de corrélation généré par le serveur (UUID). Également retourné dans l'en-tête de réponse X-Request-Id. Transmettez ceci au support Rokt pour qu'ils puissent consulter les journaux côté serveur pour l'appel.
dataobject | array | nullCharge utile spécifique à l'endpoint en cas de succès. null en cas d'erreur.
Capturez toujours request_id de l'enveloppe de réponse. L'inclure dans les tickets de support est le levier le plus important pour une résolution rapide.
Codes de statut HTTPLien direct vers Codes de statut HTTP
| Statut | Signification | Action de l'appelant |
|---|---|---|
| 400 Mauvaise Requête | Validation échouée, charge utile malformée, champ requis du corps manquant | Corrigez la charge utile, réessayez avec un nouveau Idempotency-Key |
| 401 Non Autorisé | Jeton API manquant, expiré ou invalide | Faites tourner le jeton API via votre intégration d'émission de jeton |
| 403 Interdit | Le jeton API est valide, mais soit (a) vous n'avez pas la permission d'agir sur ce compte au nom de votre gestionnaire (la configuration de concession de compte à compte de votre plateforme est manquante ou n'a pas été synchronisée), soit (b) votre X-Platform-Parent-Account-Id ne correspond pas au véritable parent du compte géré | Remontez à l'opération : une concession gérée par le gestionnaire peut avoir été révoquée, ou la valeur de l'en-tête est incorrecte |
| 404 Non Trouvé | La ressource n'existe pas, ou n'est pas accessible à l'appelant | Vérifiez account_id et qu'il se situe dans votre périmètre géré par le gestionnaire |
| 409 Conflit | Conflit Idempotency-Key, ou store_identifier déjà enregistré par un autre partenaire | Voir scénarios courants ci-dessous |
| 422 Entité Non Traitée | En-tête requis manquant (le plus souvent X-Platform-Parent-Account-Id lors d'une écriture), ou charge utile sémantiquement invalide (par exemple, valeur d'énumération inconnue) | Ajoutez l'en-tête manquant et réessayez avec la même clé |
| 429 Trop de Requêtes | Limite de taux par partenaire atteinte | Respectez Retry-After, réessayez avec le même Idempotency-Key. Voir Limites de Taux pour les plafonds par endpoint |
| 500 Erreur Interne du Serveur | Erreur côté Rokt | Attendez et réessayez avec le même Idempotency-Key |
| 501 Non Implémenté | Vous avez envoyé Prefer: respond-async mais le mode asynchrone n'est pas encore activé pour votre plateforme | Supprimez l'en-tête |
| 502 / 503 / 504 | Transitoire côté Rokt (service en aval non sain) | Réessayez avec un backoff, même Idempotency-Key |
Pour les réponses 5xx, réessayez toujours avec le même Idempotency-Key que vous avez utilisé à l'origine, dans la fenêtre de déduplication de 24 heures. Une nouvelle clé lors du réessai peut provoquer l'exécution de la même opération logique deux fois si l'original a finalement réussi côté serveur.
Scénarios d'erreurs courantsLien direct vers Scénarios d'erreurs courants
422 : add-pages retourne 422 sur une surface dupliquée (pas 409)
Lors de l'appel à POST /accounts/{account_id}/pages (add-pages), si une page pour la même surface existe déjà sur le compte, le point de terminaison retourne actuellement 422 plutôt que 409. Traitez un 422 de add-pages comme une condition de surface dupliquée possible et vérifiez les pages existantes via GET /accounts ou examinez les valeurs pages[].page_identifier de votre réponse d'enregistrement initiale.
422 : l'en-tête X-Platform-Parent-Account-Id est requis
Vous avez omis l'en-tête X-Platform-Parent-Account-Id lors d'un appel d'écriture. Le serveur le requiert pour toutes les écritures.
{
"status": 422,
"error": "ValidationFailed",
"message": "header X-Platform-Parent-Account-Id is required",
"request_id": "0e3a1b9c-...",
"data": null
}
Correction. Ajoutez X-Platform-Parent-Account-Id: <your-rokt-parent-account-id> à la requête. Réessayez avec le même Idempotency-Key; dans la fenêtre de déduplication de 24 heures, le serveur regroupe les tentatives.
400 : store_identifier n'est pas une URL valide
store_identifier doit être une URL entièrement qualifiée entre 3 et 400 caractères, schéma inclus. L'envoi d'un nom d'hôte nu est rejeté.
{
"status": 400,
"error": "BadRequest",
"message": "store_identifier acme.myshopify.com is not a valid URL",
"request_id": "0e3a1b9c-...",
"data": null
}
Correction. Envoyez https://acme.myshopify.com (ou quelle que soit l'URL principale de la vitrine du marchand). Réessayez avec un Idempotency-Key neuf.
400 : Aucun mappage vertical trouvé pour le(s) vertical(s) partenaire suivant(s) (sur MCL PUT)
Votre tableau blockedVerticals contient une paire verticale ou sous-verticale qui n'a pas de ligne correspondante dans votre mappage vertical. Le serveur ne peut pas la traduire dans la taxonomie interne de Rokt, donc l'ensemble du PUT est rejeté de manière atomique : aucune écriture partielle.
Le message liste chaque paire non mappée qu'il a trouvée, vous n'avez donc pas besoin de diviser le tableau pour localiser l'élément fautif.
{
"status": 400,
"error": "BadRequest",
"message": "No vertical mapping found for the following partner vertical(s): (partner_vertical_id=1500, partner_sub_vertical_id=1610). Call GET /v1/partnership/vertical-mappings to see which verticals are currently mapped, and contact smb-partnerships@rokt.com to request additions. The MCL write was rejected atomically; no partial update was applied.",
"request_id": "0e3a1b9c-...",
"data": null
}
Correction. Appelez GET /v1/partnership/vertical-mappings?parent_account_id=<your-parent> et comparez les paires nommées dans le message avec ce qui revient (voir Vérifiez ce qui est mappé). Envoyez un email à smb-partnerships@rokt.com avec les valeurs partnerVerticalId / partnerSubVerticalId et vos noms de catégorie pour faire ajouter les lignes. Jusqu'à ce qu'elles soient ajoutées, omettez les paires non mappées de votre PUT.
400 : Cette verticale n'est pas encore mappée (sur register)
La paire vertical_id / sub_vertical_id que vous avez envoyée à POST /v1/accounts/register/partnership n'a pas de ligne dans votre mappage vertical. L'enregistrement échoue avant que le compte marchand ne soit créé, donc il n'y a pas de compte partiel à nettoyer.
{
"status": 400,
"error": "BadRequest",
"message": "This vertical isn't mapped yet (vertical_id=1500, sub_vertical_id=1610). Contact smb-partnerships@rokt.com to have it mapped.",
"request_id": "0e3a1b9c-...",
"data": null
}
Correction. Vérifiez ce qui est semé sur votre compte parent (voir Vérifiez ce qui est mappé), puis envoyez un email à smb-partnerships@rokt.com avec la paire et vos noms de catégorie.
Si chaque appel d'enregistrement échoue de cette manière, rien n'est semé plutôt qu'une ligne manquante. Le GET retourne un tableau vide dans ce cas.
409 : Le compte Rokt existe déjà (sur register)
Une autre plateforme partenaire possède déjà ce store_identifier. Le compte Rokt existe, mais il est attaché à une autre intégration ; l'enregistrement ne peut pas transférer automatiquement la propriété.
{
"status": 409,
"error": "Conflict",
"message": "Rokt Account already exists",
"request_id": "0e3a1b9c-...",
"data": null
}
Correction. Affichez ce message exact au marchand dans votre interface d'intégration :
Il y a un problème avec la création du compte qui nécessite un examen plus approfondi. Veuillez envoyer un email à [Support de la plateforme partenaire].
Ne pas réessayer avec un store_identifier modifié pour contourner cela ; le conflit est le système vous indiquant qu'une véritable question de propriété doit être résolue par des humains.
400 : Paramètre requis Idempotency-Key manquant et non vide
Chaque appel d'écriture (POST, PUT) requiert l'en-tête Idempotency-Key. Il doit s'agir d'un UUID non vide.
{
"status": 400,
"error": "BadRequest",
"message": "Idempotency-Key header required for partnership writes",
"request_id": "0e3a1b9c-...",
"data": null
}
Correction. Générez un UUID par opération logique côté client et passez-le comme Idempotency-Key: <uuid>. Voir Clés d'idempotence pour savoir comment définir la portée de la clé lors des réessais.
409 : Opération en cours / Incohérence de corps Idempotency-Key
Vous avez réutilisé un Idempotency-Key soit pendant que l'appel original est encore en cours de traitement, soit avec un corps différent de celui mis en cache. Le serveur n'exécutera pas la même clé deux fois simultanément et ne remplacera pas silencieusement une réponse mise en cache par une nouvelle charge utile.
Correction. Attendez brièvement et réessayez le même appel ou, mieux, interrogez directement l'opération :
curl https://accounts.rokt.com/v1/partnership/operations/$OPERATION_ID \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT"
Le operation_id est retourné dans l'en-tête de réponse X-Operation-Id à chaque écriture. Voir Opérations.
429 : Limite de débit dépassée (respecter Retry-After)
Vous avez dépassé la limite de débit par partenaire pour ce point de terminaison. Le serveur renvoie l'enveloppe standard plus un en-tête de réponse Retry-After contenant un nombre entier de secondes à attendre avant de réessayer.
{
"status": 429,
"error": "RateLimitExceeded",
"message": "rate limit exceeded for partnership writes; retry after 30s",
"request_id": "0e3a1b9c-...",
"data": null
}
En-têtes de réponse (sous-ensemble pertinent) :
HTTP/1.1 429 Too Many Requests
Retry-After: 30
X-Request-Id: 0e3a1b9c-1234-4abc-9def-aaaabbbbcccc
Correction. Attendez Retry-After secondes, puis réessayez avec le même Idempotency-Key que vous avez utilisé à l'origine. Réutiliser la clé dans la fenêtre de déduplication de 24 heures garantit que le serveur regroupe les tentatives en une seule opération logique ; une nouvelle clé ici risquerait d'exécuter l'écriture deux fois si l'original a finalement réussi côté serveur.
Extrait de backoff curl (écrit les en-têtes dans un fichier, analyse Retry-After, attend, réessaye avec la même clé) :
KEY=$(uuidgen)
while true; do
STATUS=$(curl -s -o body.json -D headers.txt -w '%{http_code}' \
-X PUT https://accounts.rokt.com/v1/partnership/accounts/$ACCOUNT_ID/status \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT" \
-H "Idempotency-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "active" }')
if [ "$STATUS" != "429" ]; then break; fi
WAIT=$(grep -i '^Retry-After:' headers.txt | awk '{print $2}' | tr -d '\r')
sleep "${WAIT:-30}"
done
Équivalent Python (utilisant requests) :
import time, uuid, requests
key = str(uuid.uuid4())
while True:
r = requests.put(
f"https://accounts.rokt.com/v1/partnership/accounts/{account_id}/status",
headers={
"Authorization": f"Bearer {token}",
"X-Platform-Parent-Account-Id": parent,
"Idempotency-Key": key, # same key across retries
"Content-Type": "application/json",
},
json={"status": "active"},
)
if r.status_code != 429:
break
time.sleep(int(r.headers.get("Retry-After", "30")))
Voir Limites de débit pour les plafonds par point de terminaison et Gestion des échecs pour le contrat de nouvelle tentative plus large.
400 : le contact n'est valide que pour la configuration de paiement hosted_invite
Vous avez envoyé experience: "embedded" avec un bloc contact. Les deux sont mutuellement exclusifs : contact est requis pour hosted_invite, interdit pour embedded.
Correction. Soit supprimez le champ contact (pour embedded), soit changez experience en hosted_invite (si vous souhaitez que Rokt envoie un email au marchand).
Erreurs de validation au niveau des champsLien direct vers Erreurs de validation au niveau des champs
Règles communes par champ qui font échouer les intégrations lors de l'intégration initiale. Le schéma complet est dans openapi.yaml ; voici la liste courte des contraintes à connaître par cœur.
POST /v1/accounts/register/partnershipLien direct vers post-v1accountsregisterpartnership
| Champ | Règle |
|---|---|
brand | Requis, 1–200 caractères |
country_code | Requis, exactement 2 lettres (ISO 3166-1 alpha-2). L'entrée en minuscules est normalisée en majuscules côté serveur |
store_identifier | Requis, URL valide (doit inclure un schéma comme https://), 3–400 caractères |
external_account_id | Requis, non vide. Clé d'idempotence pour l'enregistrement ; la réutiliser renvoie le même account_id |
vertical_id / sub_vertical_id | Requis. Vos valeurs de taxonomie partenaires, pas celles de Rokt. Les deux doivent avoir une ligne dans votre mappage vertical ; confirmez via Vérifiez ce qui est mappé |
platform_parent_account_id | Champ de corps requis. Reflétez-le dans l'en-tête X-Platform-Parent-Account-Id pour plus de clarté |
PUT .../marketplacecontrolslistsLien direct vers put-marketplacecontrolslists
| Champ | Règle |
|---|---|
name | Requis, chaîne non vide |
blockedVerticals | Tableau requis. Chaque entrée doit inclure partnerVerticalId + partnerSubVerticalId. policy par défaut à Block si omis |
blockedVerticals[].policy | L'un de Allow, Block |
blockedVerticals[].position1Policy | Optionnel. L'un de Allow, Block. Par défaut à l'entrée policy si omis |
domains[].policy | L'un de Allow, Block |
PUT .../statusLien direct vers put-status
| Champ | Règle |
|---|---|
status | Requis. L'un de active, paused. Remarque : mixed est un état agrégé en lecture seule ; vous ne pouvez pas l'envoyer |
POST .../payout-setupLien direct vers post-payout-setup
| Champ | Règle |
|---|---|
provider | Obligatoire. Actuellement, seul stripe_connect est pris en charge |
experience | Obligatoire. L'un de embedded, hosted_invite. Mutuellement exclusif avec contact; voir ci-dessous |
contact.email | Obligatoire pour hosted_invite. Interdit pour embedded. Envoyer contact avec experience: "embedded" renvoie 400 |
tout bank / card / routing / account_number / iban / ssn / tax / tax_id / external_account* / payout_destination / payment_method / cvc imbriqué | Interdit partout dans la demande. Renvoie 400. Stripe collecte ces données directement auprès du marchand |
Liste de vérification pour le débogageLien direct vers Liste de vérification pour le débogage
Lorsque vous êtes confronté à une erreur inattendue, parcourez cette liste de haut en bas avant de demander de l'aide.
- Capturez
request_idde l'enveloppe de réponse (ou de l'en-tête de réponseX-Request-Id; même valeur). - Confirmez que
Content-Type: application/jsonest défini sur chaque appel d'écriture. - Confirmez que
X-Platform-Parent-Account-Idest défini sur chaque écriture;422est le signal canonique qu'il manque. - Décodez votre jeton API et vérifiez qu'il n'a pas expiré (revendication
exp). Les jetons API ont une durée de vie courte : environ 5 minutes. - Confirmez que vous atteignez
accounts.rokt.com/v1/partnership/*ouaccounts.rokt.com/v1/accounts/register/partnership. Aucun autre hôte Rokt n'est appelable par le partenaire. - Si une écriture renvoie un 4xx mais que vous soupçonnez un bug serveur, réessayez avec
?dry_run=truepour isoler si le problème vient de la charge utile ou du serveur. Le mode Dry-run effectue la validation complète sans persister l'état. Voir Mode Dry-Run. - Sur tout
400de mappage vertical, appelezGET /v1/partnership/vertical-mappings?parent_account_id=<your-parent>(voir Vérifiez ce qui est mappé). Un tableau vide signifie que rien n'est initialisé ; un tableau non vide manquant votre paire signifie qu'une seule ligne est absente. - Pour les réponses 5xx, réessayez avec le même
Idempotency-Keydans la fenêtre de déduplication de 24 heures. Ne générez pas de nouvelle clé lors de la réessai. - Si tout échoue, envoyez un email à
smb-partnerships@rokt.comavec lerequest_id, l'horodatage approximatif de l'appel (UTC), et le point de terminaison que vous avez atteint.
Pourquoi request_id est important. Rokt l'intègre dans chaque entrée de journal côté serveur pour votre appel. Renvoyez-le dans un ticket de support et l'équipe pourra trouver l'échec exact sans parcourir tout le trafic.