Endpoint par endpoint, champ par champ · calée sur la doc « API Trustt SMS » 09/06/2026 et sur un crawl exhaustif du compte entier (19/06/2026 : 54 entreprises, 98 marques, 334 campagnes, 9594 ambassadeurs, 4141 posts réels) complétant le relevé échantillonné du 10/06.
Référence technique exhaustive : 5 endpoints (4 en lecture, 1 en écriture), tous les champs typés, toutes les valeurs d'énumération observées en prod, et les pièges connus. Le code couleur :
GET lectureécriture.
Ambassadeurs sélectionnés (testeurs) d'une campagne éligible, avec identité, téléphones et livrables réalisés. cid optionnel restreint à un ambassadeur. Tri : lastName puis firstName.
GET /api_trusttsms/ambassadors?key=xxx&caid=<campagneUUID>[&cid=<candidateUUID>]
Réponse — champs
Champ
Type
Description
candidateUUID
string (UUID)
Identifiant par participation (clé de dédup ; la même personne sur N campagnes a N candidateUUID)
email
string|null
Email
firstName / lastName
string
Identité (peuvent être vides)
phoneE164
string|null
En prod : le vrai E.164 (« +33… »). 977/984.
phone
string|null
En prod : format national (« 0… »). Piège : l'exemple de la doc inverse les deux.
receiptStatus
int
Colis : 0 non reçu, 1 reçu, 2 non documenté (cf. pièges)
receiptDate
string|null
« YYYY-MM-DD HH:mm:ss » sans fuseau ; null si non reçu
Posts publiés. status : valid (4009) / pending (132), aucun rejeté. Jamais d'URL ni d'id de post (0 sur 4141).
review
null | { dateCrea, isVideo }
Avis produit réalisé (4122 remplis sur le compte)
merchantReview[]
[] | [{ dateCrea }]
Avis marchand réalisé (491 entrées)
testForms[]
[] | [{ formId, name, dateCrea }]
Questionnaires remplis. Bien rempli en prod (4428 entrées) — pas vide contrairement à un ancien relevé.
Trouvaille majeure (crawl 4141 posts) : un post réalisé ne porte jamais d'URL ni d'identifiant (0 sur 4141). Trustt suit les posts par type, pas par lien, et les auto-détecte (des milliers en valid sans rien pousser). Aucune URL nulle part non plus dans les avis. C'est le prérequis bloquant de la remontée des publications (cf. onglet « Remontée publications »).
Règle dates : si receiptStatus=0 ou pas de date, receiptDate/testEndDate peuvent être null/vides. cid fourni mais inexistant → 200 + {"data":[]}.
5save_receipt écriture
Déclare la réception / le retrait du produit pour un ambassadeur (ajouté le 08/06/2026). Effet de bord côté Trustt : pose la réception ET lance la période de test. À n'appeler qu'avec confirmation explicite.
POST /api_trusttsms/save_receipt?key=xxx&cid=<candidateUUID>&rd=<Y-m-d H:i:s>
Vérifié : appel en POST, paramètres key + cid + rd (le double cid de l'exemple de la doc était une coquille). cid inconnu → HTTP 404 {"error":"Ambassador not found"} (statut terminal côté Trustt SMS : aucun retry).
6cancel_receipt écriture
Annule la réception / le retrait d'un ambassadeur (ajouté le 23/06/2026) : remet receiptStatus à 0 et date_test_start à null. Appelé quand un retrait déjà remonté est décoché localement.
POST /api_trusttsms/cancel_receipt?key=xxx&cid=<candidateUUID>
Route vérifiée empiriquement (23/06) : la vraie route est cancel_receipt (le changelog Trustt écrivait cancel_recipt, coquille : cette route renvoie un 200 HTML vide, donc inexistante). save_receiptsansrd n'annule pas non plus (200 HTML). cid inconnu → 404 « Ambassador not found » (traité comme « rien à annuler »).
Catalogue des valeurs réelles
Crawl exhaustif du compte entier le 19/06/2026 (occurrences entre parenthèses) ; les enums campagne viennent du relevé échantillonné du 10/06. Source machine : docs/trustt-data-cases.json + docs/TRUSTT-DATA-CASES.md du dépôt.
Type de campagne (typeId)
id
Libellé
1
Produit (126)
2
Influence (109)
3
Evènement (12)
4
Produit acheté (2)
5
Test d'usage (13)
6
Achat vérifié (2)
Avancement (progressId)
id
Libellé
4
Inscription en cours (55)
5
Sélection du panel (40)
6
Produits à envoyer (doc, non observé)
7
Test en cours (69)
8
Terminée (100)
Plateforme (socialType) & type de post (postTypeId)
postTypeId
Libellé
Attendu (campagnes)
Réalisé (posts)
1
Article
jamais
5
3
Post Instagram
54
1415
4
Story Instagram
jamais
366
5
Post Facebook
jamais
55
6
non observé (libellé inconnu)
—
0
7
Vidéo Youtube
jamais
14
8
Post Pinterest
jamais
2
9
Vidéo TikTok
49 (+1 en qty 2)
2284
socialTypeId réalisés observés : 1 (Article/web), 2 (Instagram), 3 (Facebook), 5 (Youtube), 6 (Pinterest), 7 (TikTok). Plateformes ciblées (campagnes) : Instagram (2), TikTok (7). Statut de post : valid (4009) / pending (132), aucun rejeté. Quantité attendue : 1 (quasi toujours), 2 (rare). L'attendu formel (Post Instagram, Vidéo TikTok) est plus étroit que le réalisé : Story, Facebook, Youtube, Article, Pinterest sont publiés sans être formellement attendus.
Briques de contenu réalisé (compte entier)
Brique
Forme réalisée
Réalisé
Post (posts[])
{ socialTypeId, postTypeId, postTypeLabel, status, dateCrea } — sans URL
4141
Avis produit (review)
{ dateCrea, isVideo }
4122
Avis marchand (merchantReview[])
{ dateCrea }
491
Formulaire (testForms[])
{ formId, name, dateCrea }
4428
Colis (receiptStatus)
Valeur
Sens
Occurrences (compte entier)
0
Non reçu
1674
1
Reçu
7916
2
Non documenté — à clarifier
4
Pièges connus
Piège
Détail
Notre parade
phoneE164 / phone inversés
L'exemple de la doc met l'E.164 dans phone ; la prod le met dans phoneE164.
On retient le champ qui commence par « + », l'autre en national de secours.
label vs libelle
Prod renvoie label dans type/progress ; la doc montre libelle.
Schéma qui accepte les deux, normalise vers un seul.
receiptStatus = 2
Valeur non documentée (2 cas).
Affichée « Statut 2 », jamais mappée à reçu/non reçu ; filtre « reçu » = ===1.
Posts sans URL
Un post réalisé n'a jamais d'URL ni d'id (0 sur 4141). Trustt suit par type, pas par lien, et auto-détecte les posts.
Verdict de publication au type + quantité ; remontée des liens impossible à réconcilier sans URL (cf. onglet dédié).
Types réalisés > attendus
Story / Facebook / Youtube / Article / Pinterest réalisés alors que l'attendu n'est que Instagram / TikTok.
On affiche postTypeLabel tel quel.
testForms réalisés non vides
Un ancien relevé les voyait vides ; le crawl complet en trouve 4428 ({ formId, name, dateCrea }).
On lit bien realizedUgc.testForms comme livrable.
publicName de marque vide
Certaines marques sans nom public.
Ne pas filtrer là-dessus pour récupérer les campagnes.
Dates sans fuseau
« YYYY-MM-DD HH:mm:ss », pas ISO, sans timezone.
Parsing au mapping (jour pour le pivot).
Résolu par le crawl 19/06 : postTypeId 8 = Post Pinterest (et 1 = Article), receiptStatus=2 confirmé présent (4 cas sur tout le compte). Résolu le 23/06 : save_receipt (POST, key+cid+rd) et cancel_receipt (POST, key+cid ; le cancel_recipt du changelog était une coquille) vérifiés empiriquement. Questions encore ouvertes côté Trustt : sens exact de receiptStatus=2 · libellé de postTypeId 6 (toujours non observé) · progressId 6 · exposition de l'URL d'un post réalisé (prérequis à la remontée des publications).