Référence API Trustt SMS

Endpoint par endpoint, champ par champ · calée sur la doc « API Trustt SMS » 09/06/2026 et sur un relevé de la prod du 10/06/2026 (53 entreprises, 264 campagnes, 984 ambassadeurs).

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.

Sommaire

Conventions générales

ÉlémentValeur
Base URL (prod)https://pro.trustt.io/
Préfixeapi_trusttsms/{action}
MéthodeGET uniquement (y compris l'écriture, cf. endpoint 5)
AuthentificationParamètre query key sur chaque appel (clé dédiée Trustt SMS, serveur uniquement)
TransportHTTPS obligatoire
Réponseapplication/json

Enveloppe de succès

{ "data": [ ... ] }

Une liste vide est un succès (HTTP 200), pas une 404. L'endpoint 5 renvoie un objet (data non tableau).

Paramètres UUID (filtres)

ParamFormatPour
coidUUID 36 car.companyUUID (Brands)
bidUUID 36 car.brandUUID (Campaigns)
caidUUID 36 car.campagneUUID (Ambassadors)
cidUUID 36 car.candidateUUID (filtre Ambassadors ; obligatoire pour save_receipt)

Codes HTTP & erreurs

Corps d'erreur : { "error": "Message court" }.

CodeSignificationQuand
200OKSuccès (y compris data vide)
401Unauthorizedkey absente / invalide → {"error":"Unauthorized"}
404Not FoundCompany / Brand / Campaign introuvable ou non éligible
422Unprocessable EntityParamètre UUID obligatoire manquant (coid/bid/caid)
500Internal Server ErrorErreur applicative non gérée (corps variable, non structuré)

1Companies GET

Entreprises avec au moins un contrat Community Builder (id_saas_product=1) démarré, non expiré, statut actif (2) ou en pause (1). Tri : nom croissant.

GET /api_trusttsms/companies?key=xxx

Réponse — champs

ChampTypeDescription
companyUUIDstring (UUID)Identifiant entreprise (sert de coid)
nomstringRaison sociale

2Brands GET

Marques de production (is_preprod=0) d'une entreprise, ayant au moins une campagne publiée. Tri : publicName croissant.

GET /api_trusttsms/brands?key=xxx&coid=<companyUUID>

Réponse — champs

ChampTypeDescription
brandUUIDstring (UUID)Identifiant marque (sert de bid)
publicNamestringNom public. Peut être vide en prod (à ne pas filtrer pour la récupération des campagnes).

3Campaigns GET

Campagnes publiées et éligibles d'une marque : id_progress entre 4 et 8, hors archivée (9) et annulée (99). Tri : name croissant.

GET /api_trusttsms/campaigns?key=xxx&bid=<brandUUID>

Réponse — champs

ChampTypeDescription
campaignUUIDstring (UUID)Identifiant campagne (sert de caid)
namestringNom de la campagne (peut contenir des emojis)
type{ typeId:int, label:string }Type de campagne. Piège : prod renvoie label, l'exemple de la doc libelle.
progress{ progressId:int, label:string }Avancement. Même piège label/libelle.
languageCodestringLangue (ex. fr)
nbTestDaysintDurée du test en jours (0 à 84 observés)
socialType{ socialTypeId:int, label:string }Plateforme cible (Instagram, TikTok)
mentionstringMention à utiliser (ex. @garanciabeauty)
hashtagstringHashtag (peut être vide)
ugcStartDate / ugcEndDatestring|nullFenêtre de publication
pickupStartDate / pickupEndDatestring|nullFenêtre de retrait
expectedUgcobjetLivrables attendus (voir ci-dessous)

expectedUgc (attendu de la campagne)

ChampTypeDescription
expectedPost[][{ socialTypeId, socialTypeLabel, postTypeId, postTypeLabel, quantity }]Posts attendus (ex. 2 × « Vidéo TikTok »)
reviewnull | { expected, hasVideo, hasTestingPhotos }Avis produit attendu (130 campagnes)
merchantReviewnull | { expected, merchantName, merchantUrl }Avis marchand attendu (41)
testForms[][{ formId, name, nbDaysStart }]Questionnaires attendus (99)

4Ambassadors GET

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

ChampTypeDescription
candidateUUIDstring (UUID)Identifiant par participation (clé de dédup ; la même personne sur N campagnes a N candidateUUID)
emailstring|nullEmail
firstName / lastNamestringIdentité (peuvent être vides)
phoneE164string|nullEn prod : le vrai E.164 (« +33… »). 977/984.
phonestring|nullEn prod : format national (« 0… »). Piège : l'exemple de la doc inverse les deux.
receiptStatusintColis : 0 non reçu, 1 reçu, 2 non documenté (cf. pièges)
receiptDatestring|null« YYYY-MM-DD HH:mm:ss » sans fuseau ; null si non reçu
testEndDatestring|nullFin de mission, même format
realizedUgcobjetLivrables réalisés (voir ci-dessous)

realizedUgc (réalisé par l'ambassadeur)

ChampTypeDescription
posts[][{ socialTypeId, postTypeId, postTypeLabel, status, dateCrea }]Posts publiés. status : valid / pending. dateCrea datée.
reviewnull | { dateCrea, isVideo }Avis produit réalisé
merchantReview[][] | [{ dateCrea }]Avis marchand réalisé
testForms[][]Questionnaires remplis

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 : à n'appeler qu'avec confirmation explicite.

GET /api_trusttsms/save_receipt?key=xxx&cid=<candidateUUID>&rd=<Y-m-d H:i:s>
ParamFormatObligatoireDescription
cidUUIDouicandidateUUID de l'ambassadeur
rd« Y-m-d H:i:s »ouiDate de réception

Réponse (objet, pas tableau)

{ "data": { "uuid_candidate": "…", "date_test_start": "2026-06-05 12:10:00", "date_test_end": "2026-06-12 23:59:59" } }
À clarifier : l'exemple d'URL de la doc montre deux cid (le premier ressemble à un caid). Confirmer les paramètres exacts et l'idempotence avant de brancher l'écriture.

Catalogue des valeurs réelles

Relevé prod du 10/06/2026 (occurrences entre parenthèses). Source machine : docs/trustt-data-cases.json du dépôt.

Type de campagne (typeId)

idLibellé
1Produit (126)
2Influence (109)
3Evènement (12)
4Produit acheté (2)
5Test d'usage (13)
6Achat vérifié (2)

Avancement (progressId)

idLibellé
4Inscription en cours (55)
5Sélection du panel (40)
6Produits à envoyer (doc, non observé)
7Test en cours (69)
8Terminée (100)

Plateforme (socialType) & type de post (postTypeId)

postTypeIdLibelléAttenduRéalisé
3Post Instagramoui (52)oui (160)
4Story Instagramoui (45)
5Post Facebookoui (3)
7Vidéo Youtubeoui (2)
9Vidéo TikTokoui (44)oui (218)

Plateformes ciblées observées : Instagram (socialTypeId 2), TikTok (7). Statut de post : valid (416) / pending (12). Quantité attendue : 1 (quasi toujours), 2 (rare).

Colis (receiptStatus)

ValeurSensOccurrences
0Non reçu123
1Reçu859
2Non documenté — à clarifier2

Pièges connus

PiègeDétailNotre parade
phoneE164 / phone inversésL'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 libelleProd renvoie label dans type/progress ; la doc montre libelle.Schéma qui accepte les deux, normalise vers un seul.
receiptStatus = 2Valeur non documentée (2 cas).Affichée « Statut 2 », jamais mappée à reçu/non reçu ; filtre « reçu » = ===1.
Types réalisés > attendusStory / Facebook / Youtube réalisés alors que l'attendu n'est que Instagram/TikTok.On affiche postTypeLabel tel quel.
publicName de marque videCertaines 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).
Questions ouvertes côté Trustt : sens de receiptStatus=2 · libellés postTypeId 6 et 8 · progressId 6 · paramètres exacts de save_receipt.