Ce document explique, par des schémas, d'abord ce qu'est Trustt SMS (Partie A : ses surfaces, ses composants, son cycle de vie, son modèle de données), puis comment il s'articule avec la plateforme Trustt mère (Partie B : l'intégration, les points bloquants, les endpoints). Objectif : partager une compréhension commune et lever les ambiguïtés. Le code couleur ci-dessous s'applique à tous les diagrammes.
L'implémentation de la section 9 (« ne relancer que les bons ») est en prod côté Trustt SMS : les relances SMS sont désormais conditionnées sur le statut de publication, calculé à partir de votre realizedUgc + expectedUgc.
Ce que ça renforce côté demandes Trustt : (1) exposer en lecture le statut publié + l'URL du post (cf. section 3 et 9) fiabilise directement ce conditionnement ; (2) un endpoint d'écriture save_post (onglet « Remontée publications ») permettrait de boucler le cycle. Le moteur qui consomme ces données est désormais actif, donc leur qualité a un impact direct sur le ciblage des envois.
Le design de la remontée « colis récupéré » vers Trustt est validé côté Trustt SMS (plan d'implémentation prêt).
Comportement décidé côté Trustt SMS :
save_receipt.Point bloquant prioritaire - il manque un endpoint d'annulation : save_receipt ne fait que poser la réception (et lance la période de test). Si un opérateur décoche par erreur dans Trustt SMS, il n'y a aujourd'hui aucun moyen de l'annuler côté Trustt (receiptStatus reste à 1). Il faudrait un moyen de le remettre à 0 (save_receipt avec rd vide, ou un delete_receipt / cancel_receipt). En attendant, le décochage reste local et crée une divergence à corriger manuellement côté Trustt.
À confirmer côté Trustt : rappeler save_receipt sur une réception existante écrase-t-il date_test_start / date_test_end ? Un seul cid suffit-il (l'exemple d'URL en montre deux) ?
Après votre mise à jour de l'API et un relevé de la prod (53 entreprises, 98 marques, 264 campagnes, 984 ambassadeurs).
Résolu / adressé par votre maj :
realizedUgc (endpoint ambassadors) expose les posts réalisés (type, date, statut), l'avis produit et l'avis marchand. Déjà exploité (filtre « a publié / pas encore », détail par post).save_receipt ajouté (08/06) - le canal d'écriture qui manquait. Design validé côté Trustt SMS, implémentation planifiée (cf. mise à jour 19/06).expectedUgc (posts attendus + quantité, avis, formulaires) ajouté. Exploité pour « réalisé / attendu ».languageCode, socialType, mention, hashtag, nbTestDays, dates ugc/pickup.Confirmé / précisé par le relevé prod :
phoneE164 (977/984) ; phone = national. L'exemple de la doc reste inversé.0 (non reçu), 1 (reçu) et 2 (non documenté, 2 cas).type/progress renvoient le libellé sous la clé label (et non libelle de l'exemple).valid, pending.Questions restantes : sens de receiptStatus = 2 ; libellés postTypeId 6 et 8 ; progressId 6 ; paramètres exacts de save_receipt (l'exemple montre deux cid).
Détail complet dans la version Markdown (section « Mise à jour 10/06/2026 »).
Trustt SMS expose trois pages publiques (accès par lien token, sans login) et une console admin (Google OAuth). Chaque surface s'adresse à un acteur différent.
flowchart TB
AMB["Ambassadeur"]
STAFF["Staff hote (lieu / evenement)"]
OP["Operateur Trustt SMS"]
subgraph PUB["Surfaces publiques (lien token, sans login)"]
direction LR
B["/b Brief ambassadeur
mission, produit, consignes"]
C["/c Confirmation / check-in
l'ambassadeur confirme ou decline"]
H["/h Portail hote
le staff marque present / recupere"]
end
subgraph ADMIN["Console admin (Google OAuth @trustt.io)"]
direction LR
AD1["Campagnes + sequences SMS"]
AD2["Audience / import contacts"]
AD3["Conversations (SMS entrants)"]
AD4["Briefs + soumissions"]
end
AMB --> B
AMB --> C
STAFF --> H
OP --> ADMIN
classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29;
class B,C,H good;
Les surfaces publiques (vert) sont celles que voient les gens hors de l'entreprise. Un portail hôte unifié /h/c regroupe plusieurs campagnes d'un même lieu sur une seule page.
Deux processus (API web + workers de file), une base Mongo, une file Redis, un fournisseur SMS interchangeable. Le fournisseur renvoie les statuts de livraison et les SMS entrants par webhook.
flowchart LR WEB["Next.js (web)
console admin + pages publiques"] API["API Express
routes + webhooks"] WRK["Workers BullMQ
materializer, envoi, sweeper,
rappels brief, entrant"] MDB[("MongoDB")] RDS[("Redis (files)")] PROV["Fournisseur SMS
Twilio / Vonage / OVH"] WEB --> API API --> MDB API --> RDS RDS --> WRK WRK --> MDB WRK --> PROV PROV -. "statut livraison + SMS entrant (webhook)" .-> API
Les envois ne partent jamais sur le chemin d'une requête : ils passent par des files Redis avec retries, throttle 1 SMS/s, et un sweeper qui récupère les messages bloqués. C'est ce qui permet d'absorber les pics sans bloquer l'opérateur.
Le parcours complet, de la création par l'opérateur jusqu'aux réactions de l'ambassadeur et au suivi. C'est ici que l'intégration Trustt vient se brancher (import en entrée, remontées en sortie).
flowchart TB CREATE["1. Creation de la campagne
(marque, date, mode check-in)"] --> IMPORT["2. Import de l'audience
(contacts = futurs ambassadeurs)"] IMPORT --> BRIEF["3. Brief publie (optionnel)
une livraison par contact"] BRIEF --> SEQ["4. Sequence SMS
(J-3, jour J, sur retrait, relances)"] SEQ --> LAUNCH["5. Lancement"] LAUNCH --> MAT["6. Materializer
programme les SMS"] MAT --> SEND["7. Envoi SMS
(worker + fournisseur)"] SEND --> AMB{"8. Reaction ambassadeur"} AMB -->|"ouvre /b"| VIEW["consulte le brief"] AMB -->|"clique /c"| CONF["confirme / decline"] AMB -->|"repond par SMS"| INB["conversation entrante"] CONF --> HOST["9. Jour J : le staff marque
present / recupere (/h)"] HOST --> RETICK["10. Retick : SMS 'sur retrait',
annule les relances devenues inutiles"] VIEW --> SUB["11. Soumission du contenu publie
(lien du post + capture)"] INB --> CONV["L'operateur repond (conversations)"] RETICK --> THANKS["SMS de remerciement"] classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29; class CONF,HOST,SUB good;
Soumission de contenu (étape 11) : Trustt SMS a déjà une entité « soumission » (lien du post + plateforme Instagram/TikTok/YouTube + validation opérateur). C'est exactement le lien de contenu publié de la Partie B (W4), aujourd'hui re-saisi à la main dans Trustt.
La chaîne centrale : Client puis Campagne puis la jonction CampaignContact qui relie une Campagne et un Contact, avec autour le brief, les soumissions, les SMS sortants et entrants, et le stock.
erDiagram
CLIENT ||--o{ CAMPAIGN : possede
CAMPAIGN ||--o{ CAMPAIGNCONTACT : contient
CONTACT ||--o{ CAMPAIGNCONTACT : participe
CAMPAIGN ||--o| BRIEF : a
BRIEF ||--o{ BRIEFDELIVERY : livre
CONTACT ||--o{ BRIEFDELIVERY : recoit
BRIEFDELIVERY ||--o| SUBMISSION : preuve
CAMPAIGNCONTACT ||--o{ MESSAGE : sortant
CONTACT ||--o{ INBOUNDMESSAGE : entrant
CAMPAIGN ||--o{ INVENTORY : stock
CONTACT {
string phoneE164 UK
string firstName
bool unsubscribed
}
CAMPAIGNCONTACT {
date pivotDate
string attendanceResponse
string markedByHostType
}
CAMPAIGN {
string status
string checkInMode
object flowConfig
}
SUBMISSION {
string postUrl
string platform
string status
}
Points d'ancrage de l'intégration : CONTACT.phoneE164 est unique (un contact = un numéro) ; CAMPAIGNCONTACT.pivotDate est la date par contact (cible de receiptDate) ; markedByHostType porte le retrait / la présence ; SUBMISSION.postUrl porte le lien publié.
Deux points de contact : l'import des ambassadeurs en entrée (existe), et les remontées en sortie
(réception colis livrée via save_receipt ; publication et optout encore à créer).
Tout le reste de Trustt SMS reste inchangé.
flowchart LR
subgraph TR["Trustt (mere)"]
direction TB
AMB2["Ambassadeurs selectionnes"]
REC["receiptStatus / receiptDate
+ realizedUgc / expectedUgc (statut publie, LECTURE)"]
end
subgraph TS["Trustt SMS"]
direction TB
CT2["Contacts + CampaignContact"]
OUTD["Reception colis (remontee LIVREE)"]
OUT["Optout, lien de contenu publie
(remontee A CREER)"]
end
AMB2 -- "IMPORT (GET ambassadors + realizedUgc)" --> CT2
OUTD -- "save_receipt (LIVRE, en prod)" --> TR
OUT -. "save_post / optout (a creer)" .-> TR
classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29;
classDef missing fill:#fdeceb,stroke:#dc2626,color:#1a1f29;
class CT2,OUTD good;
class OUT missing;
linkStyle 0 stroke:#16a34a,stroke-width:2px;
linkStyle 1 stroke:#16a34a,stroke-width:2px;
linkStyle 2 stroke:#dc2626,stroke-width:2px;
La suite du document (Partie B) détaille ces points : l'import via les endpoints de lecture (dont realizedUgc),
la remontée réception déjà livrée (save_receipt), et la remontée publication proposée (save_post, onglet dédié).
Trustt est le système mère (campagnes, ambassadeurs). Trustt SMS envoie les SMS de suivi. Le canal de lecture existe (API REST GET). Le canal de remontée n'existe pas encore.
flowchart LR
subgraph TRUSTT["Trustt (plateforme mere)"]
direction TB
T1["Companies / Brands"]
T2["Campaigns"]
T3["Ambassadeurs selectionnes"]
end
subgraph TSMS["Trustt SMS (outil interne)"]
direction TB
S1["Clients / Campagnes"]
S2["Contacts"]
S3["Sequences SMS + Portail hote"]
end
TRUSTT -- "API REST lecture (GET) : EXISTE" --> TSMS
TSMS -- "save_receipt (retrait colis) : LIVRE" --> TRUSTT
TSMS -. "optout, lien publie, annulation reception : MANQUE" .-> TRUSTT
linkStyle 0 stroke:#16a34a,stroke-width:2px;
linkStyle 1 stroke:#16a34a,stroke-width:2px;
linkStyle 2 stroke:#dc2626,stroke-width:2px;
Constat clé : un premier canal d'écriture est livré et en prod (save_receipt pour le colis récupéré), mais sans annulation. Le reste de ce que Trustt SMS doit renvoyer (désabonnement, lien de contenu publié, annulation de réception) n'a toujours aucun canal. L'API reste en lecture seule, à ces exceptions près.
Trustt a deux niveaux au-dessus de la campagne (Company puis Brand), Trustt SMS un seul (Client). Et surtout : une campagne Trustt peut alimenter plusieurs campagnes Trustt SMS.
flowchart TB
subgraph L["Modele Trustt (mere)"]
direction TB
CO["Company
companyUUID"] --> BR["Brand
brandUUID"]
BR --> CA["Campaign
campaignUUID"]
CA --> AM["Ambassador
candidateUUID"]
end
subgraph R["Modele Trustt SMS"]
direction TB
CL["Client"] --> CP["Campagne"]
CP --> JX["CampaignContact
(jonction)"]
JX --> CT["Contact
telephone UNIQUE"]
end
CO -. "aplati dans" .-> CL
BR -. "champ sur la campagne" .-> CP
CA -- "1 vers N" --> CP
AM -. "candidateUUID = cle de deduplication" .-> CT
classDef hot fill:#fdf3e3,stroke:#b45309,color:#1a1f29;
class CA,CP hot;
Piège de champ : dans le payload ambassadeur, le champ nommé phoneE164 contient du national (0612345678), c'est phone qui est au format E.164 (+33612345678). Trustt SMS impose un téléphone unique : deux ambassadeurs partageant un numéro entrent en collision (cf. doc, points B5 et D2).
Pour atteindre les ambassadeurs d'une campagne, il faut descendre la hiérarchie en quatre appels. Aucun filtre incrémental : à chaque cycle, la liste complète est re-téléchargée.
sequenceDiagram autonumber participant S as Trustt SMS participant A as API Trustt (GET) S->>A: GET /companies (key) A-->>S: data [companyUUID, nom] S->>A: GET /brands (key, coid) A-->>S: data [brandUUID, publicName] S->>A: GET /campaigns (key, bid) A-->>S: data [campaignUUID, name, type, progress] S->>A: GET /ambassadors (key, caid) A-->>S: data [candidateUUID, phone, receiptDate, testEndDate,
realizedUgc (posts/avis), expectedUgc (attendu)] Note over S,A: Pas de delta, pas de pagination, pas de webhook
realizedUgc/expectedUgc presents, mais sans l'URL du post
À clarifier (D6, D7, D9) : un filtre « modifié depuis », une liste plate des campagnes éligibles, ou un webhook éviteraient de re-balayer toute la hiérarchie à chaque synchronisation.
Statut « publié » désormais exposé (maj API) : la réponse GET /ambassadors porte maintenant realizedUgc (posts réalisés : type, date, statut ; avis ; avis marchand ; formulaires) et expectedUgc (attendu de campagne). Trustt SMS s'en sert déjà pour cibler les relances (cf. section 9, conditionnement en prod). Manque encore l'URL du post dans realizedUgc.posts : sans elle, le verdict se fait au type + à la quantité, et la réconciliation de la remontée reste impossible (cf. onglet « Remontée publications »).
Une fois les ambassadeurs récupérés, le mapping alimente la base Trustt SMS.
La date de réception colis (receiptDate) sert de pivot par contact : la séquence de SMS se planifie alors automatiquement.
flowchart LR P["Pull ambassadeurs
d'une campagne"] --> M{"Mapping"} M --> M1["phone vers phoneE164
(et non le champ phoneE164)"] M --> M2["candidateUUID vers externalTrusttId
cle de deduplication"] M --> M3["receiptDate vers pivot par contact"] M1 --> DB[("Base Trustt SMS")] M2 --> DB M3 --> DB DB --> SEQ["Moteur de sequence
relances auto sur receiptDate / testEndDate"] classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29; class SEQ good;
Gain (demande F1) : la plomberie « pivot par contact » existe déjà côté Trustt SMS. Si receiptDate est fiable et horodatée, les relances « J+2 après réception », « J+5 rédige ton avis » se déclenchent sans saisie manuelle.
Plusieurs signaux produits par Trustt SMS doivent remonter. Le style réel de votre API est
un endpoint par signal (confirmé par save_receipt), pas un puits générique.
Un seul est livré aujourd'hui ; les autres restent à créer.
flowchart LR
subgraph PROD["Trustt SMS produit"]
direction TB
E2["reception colis"]
E3["lien de contenu publie"]
E1["optout (STOP)"]
E4["sms_status / numero invalide"]
E5["attendance, brief_viewed, sentiment"]
end
TR["Trustt (mere)"]
E2 -- "save_receipt (LIVRE, en prod)" --> TR
E3 -. "save_post (propose, cf. onglet)" .-> TR
E1 -. "aucun canal (A CREER)" .-> TR
E4 -. "aucun canal (A CREER)" .-> TR
E5 -. "aucun canal (A CREER)" .-> TR
classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29;
classDef warn fill:#fdf3e3,stroke:#b45309,color:#1a1f29;
classDef missing fill:#fdeceb,stroke:#dc2626,color:#1a1f29;
class E2 good;
class E3 warn;
class E1,E4,E5 missing;
linkStyle 0 stroke:#16a34a,stroke-width:2px;
linkStyle 1 stroke:#b45309,stroke-width:2px;
linkStyle 2 stroke:#dc2626,stroke-width:2px;
linkStyle 3 stroke:#dc2626,stroke-width:2px;
linkStyle 4 stroke:#dc2626,stroke-width:2px;
État : save_receipt (réception colis) est livré et en prod. save_post (lien publié) est proposé dans l'onglet « Remontée publications » (prérequis : l'URL comme clé d'un post côté Trustt). L'optout, le statut SMS et les autres signaux n'ont encore aucun canal. Chaque remontée porte candidateUUID (+ campaignUUID si pertinent) et est idempotente.
Un SMS entrant ne contient que le numéro, pas la campagne visée. Comme le numéro est partagé entre plusieurs campagnes, le rattachement automatique est une heuristique, pas une certitude.
flowchart TB
R["SMS entrant : seulement le numero"] --> Q{"Quelle campagne ?"}
Q --> H["Heuristique : campagne du dernier SMS
sortant de moins de 7 jours, hors archivee"]
H --> OK["FIABLE si une seule campagne active"]
H --> F1["FAUX si 2 campagnes actives en parallele"]
H --> F2["AUCUN si reponse de plus de 7 jours"]
H --> F3["AUCUN si derniere campagne archivee"]
classDef bad fill:#fdeceb,stroke:#dc2626,color:#1a1f29;
classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29;
class F1,F2,F3 bad;
class OK good;
Conséquences : l'historique sortant est rattachable de façon fiable par campagne ; l'historique entrant ne l'est qu'au mieux. Donc un historique par personne est fiable, un historique par campagne côté entrant est indicatif (cf. W3). Le désabonnement n'est pas concerné : il est de toute façon au niveau personne.
Cas du lien de contenu publié (W4) : aujourd'hui l'opérateur copie le lien reçu et le colle à la main dans Trustt. En lui faisant confirmer la campagne au moment de pousser le lien, le rattachement redevient fiable, en un clic.
Un STOP reçu sur une campagne doit couper l'envoi pour ce numéro partout, des deux côtés. C'est une exigence RGPD, pas une option.
flowchart TB STOP["Ambassadeur repond STOP
(sur une campagne)"] --> G["Trustt SMS : optout GLOBAL
niveau personne / numero"] G --> C1["Campagne A : coupe"] G --> C2["Campagne B : coupe"] G --> C3["Campagne C : coupe"] G --> W["save_optout (a creer)"] W --> TR["Trustt coupe ce numero
sur toutes ses campagnes"] TR -. "symetrie : si optout cote Trustt" .-> IMP["expose a l'import
pour ne pas recontacter"] classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29; classDef missing fill:#fdeceb,stroke:#dc2626,color:#1a1f29; class C1,C2,C3 good; class W,TR missing;
Bloquant W2 + symétrie : si un ambassadeur se désinscrit côté Trustt, ce statut doit être exposé à l'import (point B2) pour qu'on ne le recontacte pas. Sans les deux sens, les systèmes divergent sur le même numéro.
Une campagne Trustt de type Evènement (masterclass, atelier) suit la même logique de « check-in » que le retrait colis, avec deux sous-signaux : l'intention (confirme ou décline, avant) et la présence réelle (jour J).
flowchart TB TY["Campagne Trustt de type Evenement
(typeId 3, ex : masterclass)"] --> NEED["Trustt SMS a besoin :
date + lieu de l'event (F3, F4)"] NEED --> PIV["date de l'event = pivot des relances"] PIV --> P1["J-3 : 'confirme ta venue'"] P1 --> PORT["Portail public (lien /c)
l'ambassadeur repond"] PORT --> CONF["intention : confirmed / declined"] CONF --> JJ["Jour J : presence reelle marquee
present / absent"] JJ --> EV["Remontee attendance + presence
save_attendance (a creer)"] classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29; classDef missing fill:#fdeceb,stroke:#dc2626,color:#1a1f29; class PORT,CONF,JJ good; class EV missing;
Même famille que le retrait : retrait colis (présent / récupéré) et présence à un événement (confirmé / présent) partagent le mécanisme de check-in. Côté Trustt SMS, c'est le champ checkInMode (pickup ou attendance) qui décide lequel s'applique, dérivé du type de campagne Trustt.
Bloquant identique à B1 / W1 : la confirmation de présence et la présence réelle ne peuvent pas remonter sans surface d'écriture. Côté lecture, il nous faut la date et le lieu de l'événement (F3, F4) pour piloter les relances de confirmation.
Trustt SMS relance les ambassadeurs sur leurs livrables (réception colis, avis, contenu publié).
Sans savoir qui a déjà franchi l'étape, on relance tout le monde, y compris ceux qui ont déjà publié.
Le payload ambassadeur n'expose aujourd'hui que receiptStatus.
flowchart TB R["Relance d'une etape
(publie ? avis ? brief vu ?)"] --> Q{"Statut connu
cote Trustt ?"} Q -- "PUBLICATION : realizedUgc expose
conditionnement EN PROD" --> G["Cibler : relancer SEULEMENT
ceux qui n'ont pas franchi l'etape"] Q -- "autres jalons (avis detaille, brief vu)
non exposes : DEMANDE" --> B["Relancer TOUT LE MONDE
y compris ceux qui ont deja franchi"] G --> OK["Moins de SMS, pas de sur-sollicitation"] B --> KO["Cout Twilio inutile + agacement
+ image de marque"] classDef good fill:#e9f8ef,stroke:#16a34a,color:#1a1f29; classDef bad fill:#fdeceb,stroke:#dc2626,color:#1a1f29; class G,OK good; class B,KO bad;
Jalons à exposer (F7-F9) : contenu publié (oui / non + lien + plateforme + date) ; avis rédigé (oui / non) ; brief vu / mission acceptée. Chacun est un point de relance distinct : on ne relance que ceux qui n'ont pas franchi l'étape.
Symétrie lecture / écriture : ces statuts sont la face lecture des évènements qu'on remonte
(content_submission, brief_viewed, attendance, section 5). Ce que Trustt sait déjà
doit être lisible pour ne pas relancer pour rien ; ce qu'on pousse doit être relisible. Sinon les deux systèmes relancent en double.
Implémenté (19/06/2026) : ce ciblage est en prod pour la publication. Trustt SMS calcule un statut
à 4 états (pas publié / incomplet / non conforme / publié conforme) à partir de votre realizedUgc +
expectedUgc, et l'utilise comme condition d'envoi (cumulable, ex. « a reçu ET pas publié »). Exposer
l'URL du post en lecture fiabiliserait encore le verdict (aujourd'hui basé sur le type + la quantité).
Note (maj 19/06/2026) : la proposition initiale d'un puits générique /api_trusttsms/events ci-dessous est dépassée. Trustt a finalement retenu le style un endpoint par signal avec save_receipt (réception, livré). On s'aligne donc sur ce style : voir save_post dans l'onglet « Remontée publications » ; un save_optout / save_attendance suivraient le même modèle. Le contrat /events reste ci-dessous pour mémoire (la liste des signaux et des charges utiles reste valable).
Contrat proposé, dans le style de votre documentation, pour que l'implémentation soit directe. Un endpoint d'écriture (le manque principal) et un endpoint de lecture optionnel qui simplifie la synchronisation.
Puits d'évènements unique : Trustt SMS y pousse tous les signaux qu'il produit (désabonnement, retrait, présence, lien publié, statut SMS, sentiment). Idempotent et extensible.
POST https://app.trustt.io/api_trusttsms/events Authorization: Bearer VOTRE_CLE_API (recommande, cf. D10 ; ?key= accepte) Content-Type: application/json { "eventId": "ttsms-3f9a1c7e", "type": "pickup", "candidateUUID": "e5f6a7b8-c9d0-1234-ef01-345678901234", "campaignUUID": "d4e5f6a7-b8c9-0123-def0-234567890123", "occurredAt": "2026-06-04T14:30:00+02:00", "payload": { "status": "picked_up" } }
Champs communs
| Champ | Format | Obligatoire | Description |
|---|---|---|---|
eventId | string | oui | Id stable Trustt SMS. Idempotence : rejouer le même eventId = aucun effet de bord |
type | enum | oui | optout, pickup, attendance, content_submission, sms_status, sentiment, brief_viewed |
candidateUUID | UUID | oui | Ambassadeur concerné |
campaignUUID | UUID | oui sauf optout | Campagne concernée (optout = niveau personne) |
occurredAt | ISO-8601 + offset | oui | Date de l'évènement métier |
payload | objet | selon type | Données spécifiques au type |
Payloads par type
| type | payload | Effet attendu côté Trustt |
|---|---|---|
optout | { phone, reason } | Couper le SMS pour ce numéro sur toutes les campagnes |
pickup | { status: "picked_up" } | Enregistrer le retrait (maj receiptStatus / receiptDate) |
attendance | { intent, presence } | Présence à l'évènement (confirmé/décliné + présent/absent) |
content_submission | { url, attribution } | Rattacher le lien de contenu publié au livrable |
sms_status | { status } | Qualité de la donnée (numéro mort) |
sentiment | { rating, comment } | Feedback marque sur l'ambassadeur |
brief_viewed | { } | Ambassadeur a ouvert le brief |
Réponse 200 : { "data": [ { "eventId": "...", "status": "accepted | duplicate" } ] } · Erreurs : 401 (clé), 422 (champ / enum), 404 (UUID inconnu), 500.
Liste plate des campagnes éligibles pour la clé, company et brand inline : remplace la cascade companies puis brands puis campaigns (D7). Le paramètre updatedSince permet la synchronisation incrémentale (D6).
GET https://app.trustt.io/api_trusttsms/eligible_campaigns?key=xxx GET ...?key=xxx&updatedSince=2026-06-01T00:00:00+02:00 { "data": [ { "campaignUUID": "d4e5f6a7-...", "companyUUID": "a1b2c3d4-...", "companyNom": "L'Oreal France", "brandUUID": "c3d4e5f6-...", "brandPublicName": "Garnier", "type": { "typeId": 3, "libelle": "Evenement" }, "progress": { "progressId": 6, "libelle": "..." }, "updatedAt": "2026-06-01T10:00:00+02:00" } ] }
Confort : remplace 1 + N + (N x M) appels par un seul, et rend la synchro incrémentale possible. Les endpoints existants restent inchangés.
Sans l'endpoint d'écriture, rien ne remonte. C'est le bloquant W1 : retrait, présence, désabonnement et lien publié en dépendent tous. Un seul endpoint les débloque ensemble.