Crée une ressource MessageSearchResult.
const url = 'https://api.facteur.local/messages/search';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"attachmentName":"example","body":"example","cursor":"example","hasAttachment":true,"hasOtp":true,"inbox":"example","limit":50,"match":"all","otp":"example","sentFrom":"example","sentTo":"example","since":"2026-04-15T12:00:00Z","status":"parsed","subject":"verification","type":"email","wait":0,"workspace":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.facteur.local/messages/search \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "attachmentName": "example", "body": "example", "cursor": "example", "hasAttachment": true, "hasOtp": true, "inbox": "example", "limit": 50, "match": "all", "otp": "example", "sentFrom": "example", "sentTo": "example", "since": "2026-04-15T12:00:00Z", "status": "parsed", "subject": "verification", "type": "email", "wait": 0, "workspace": "example" }'La recherche de searchMessages avec ses critères dans un corps JSON au lieu de la chaîne de requête : mêmes critères, mêmes limites, même page, même curseur et même attente. Rend les messages qui correspondent, le plus récent d’abord, une page à la fois, corps compris. Au moins un critère est exigé ; un champ qui n’existe pas est refusé.
Authorizations
Section intitulée « Authorizations »Request Bodyrequired
Section intitulée « Request Bodyrequired »La nouvelle ressource MessageSearchResult
Une page de messages trouvés par une recherche, et le curseur de la suivante.
object
Une sous-chaîne du nom d’une pièce jointe, sans tenir compte de la casse, parmi toutes les vraies pièces jointes du message, gardées ou non (une image intégrée n’en est pas une). Un critère de texte : il se joint à sentTo, sentFrom, subject, body et otp dans all ou any.
Une sous-chaîne du corps, dans sa partie texte ou sa partie HTML, sans tenir compte de la casse.
Le nextCursor de la page précédente.
Si le message porte une vraie pièce jointe (une image intégrée, comme une signature, n’en est pas une) ; false cherche l’absence. Une borne : elle restreint dans les deux modes, et seule elle suffit à faire une recherche.
Si le message porte un code (un code vide n’en est pas un). Une borne : elle restreint dans les deux modes, et seule elle suffit à faire une recherche.
L’identifiant d’une inbox. En nommer une suffit à faire une recherche. Une inbox que l’appelant n’atteint pas répond 404, jamais une liste vide. Elle l’emporte sur workspace quand les deux sont donnés.
La taille de la page, 50 par défaut et 200 au plus ; une valeur plus grande est ramenée à 200, zéro est refusé.
Comment sentTo, sentFrom, subject, body, otp et attachmentName se combinent : tous, ou n’importe lequel. Les bornes (since, type, hasOtp, hasAttachment, status) restreignent dans les deux modes.
Une sous-chaîne du code à usage unique que l’ingesteur a extrait ; lue dans cette colonne, jamais dans le corps.
Une sous-chaîne de l’adresse de l’expéditeur, sans tenir compte de la casse.
Une sous-chaîne de l’adresse à laquelle le message a été envoyé, sans tenir compte de la casse. % et _ sont du texte.
Les messages reçus à cet instant ou après, en ISO 8601. Une borne : elle restreint dans les deux modes.
parsed (par défaut) cache un message que l’ingesteur n’a pas fini de lire ; any montre tous les états, refusés compris.
Une sous-chaîne du sujet, sans tenir compte de la casse.
Example
verificationLe canal. Une borne, absente par défaut.
Combien de temps attendre, en millisecondes, un message qui correspond : la recherche est rejouée toutes les 250 ms et répond dès qu’un message correspond. Cinq minutes (300000) au plus, une valeur plus grande est ramenée à ce plafond et n’est pas refusée ; zéro, absente ou négative donne une recherche unique. Une attente expirée répond 200 avec une page vide. Une organisation garde 20 attentes ouvertes à la fois, partagées entre toutes les instances : la suivante est refusée en 429 TOO_MANY_WAITS avec Retry-After: 1. Une instance qui s’arrête répond à une attente qu’elle ne peut pas finir par un 503 API_DRAINING avec Retry-After: 1, jamais par une page vide. Elle ne remplit aucune recherche à elle seule.
L’adresse (slug) d’un espace de travail où chercher. Elle restreint la recherche mais ne suffit pas à en faire une ; l’inbox l’emporte quand les deux sont données.
Responses
Section intitulée « Responses »Ressource MessageSearchResult créée
Une page de messages trouvés par une recherche, et le curseur de la suivante.
object
Un message qu’une inbox a reçu, ou la trace de celui qu’elle a refusé.
object
Les vraies pièces jointes du message, gardées ou non, par nom puis par identifiant ; une image intégrée n’en est pas une (voir inlines). Absent sur un message refusé. Téléchargez une pièce gardée avec downloadAttachment, par son identifiant : la réponse ne dit jamais où sont les octets.
object
sha256: puis le sha256 des octets décodés, en hexadécimal.
Le type que l’expéditeur a déclaré, que rien n’a vérifié sur les octets.
Tel que l’expéditeur l’a écrit : une donnée, jamais un chemin.
Pourquoi les octets n’ont pas été gardés ; seulement sur une pièce qui ne l’a pas été.
Des octets décodés.
Si les octets ont été gardés, donc s’il y a quelque chose à télécharger. Vaut vrai exactement quand reason est absent.
Tous les codes que l’ingesteur a trouvés, le meilleur candidat d’abord. Absent sur un message refusé.
Ce que la connexion savait, dans la lecture d’un message et dans une recherche de l’API publique : nul quand l’ingesteur ne savait rien, et chaque fait nul quand il ne le savait pas, jamais une chaîne vide. Un message refusé le garde.
object
Nommé, comme TLS 1.3, jamais un nombre.
Le temps que l’ingesteur a mis à l’accepter, en millisecondes.
Pourquoi le message a été refusé ; seulement sur un message quota_exceeded, qui ne porte rien de dérivé. L’un de PLAN_QUOTA_EXCEEDED, INBOX_QUOTA_EXCEEDED, WORKSPACE_QUOTA_EXCEEDED, OVERAGE_CAP_REACHED, DAILY_SPIKE_CAP, SUBSCRIPTION_SUSPENDED ; un code qu’une version ultérieure de l’ingesteur écrit est dit tel quel.
Quand la conservation du plan supprime le message, ou null s’il n’expire pas.
Les valeurs que les extracteurs de l’inbox ont trouvées, par clé. Absent sur un message refusé.
object
Le nom d’affichage de l’expéditeur, quand le message en donnait un. Absent sur un message refusé.
Les en-têtes du message, noms en minuscules ; dans la lecture d’un message et dans une recherche de l’API publique. Absents d’un message refusé.
object
Dans la lecture d’un message et dans une recherche de l’API publique ; absent de la liste d’une inbox et de la recherche de app. Absent d’un message refusé.
L’inbox qui l’a reçu.
Les images intégrées au corps, comme le logo d’une signature : les parties que le message a déclarées inline. Ce ne sont pas des pièces jointes (jamais comptées parmi elles, jamais trouvées par une recherche) et elles n’ont pas de lien. Absent sur un message refusé.
object
Ce que le cid: du corps HTML désigne.
Les liens du message, dans l’ordre d’apparition, la partie HTML d’abord. Absent sur un message refusé.
Le code à usage unique que l’ingesteur a extrait, null s’il n’y en a pas. Absent sur un message refusé.
La taille du message tel qu’il a été reçu, en octets ; 0 pour un message refusé, dont le contenu n’a pas été gardé.
L’état du message. Lisez-le avant tout ce qui dérive du corps.
Absent sur un message refusé ; null s’il n’y en a pas.
Dans la lecture d’un message et dans une recherche de l’API publique ; absent de la liste d’une inbox et de la recherche de app. Absent d’un message refusé.
Le canal qui l’a transporté.
Renvoyez-le comme cursor pour lire la page suivante ; null sur la dernière page.
Example
{ "messages": [ { "attachments": [ { "reason": "PERFORMANCE_MODE" } ], "status": "received", "type": "email" } ]}La requête ne peut pas être lue : un critère vide, inconnu ou invalide, un curseur qui n’en est pas un, une valeur que sa règle refuse, ou un corps qui n’est pas du JSON. Le code dit lequel, et field nomme le critère.
Un refus, en application/problem+json (RFC 9457) avec le code du registre. Un code ajoute les membres que sa règle demande (retryAfter, permission…), donc d’autres membres que ceux-ci peuvent arriver.
object
Le code stable du refus. Il ne change jamais une fois publié.
Du texte en anglais pour la personne qui lit la réponse. Il peut être reformulé : branchez-vous sur code.
Le statut HTTP.
Le nom du statut HTTP.
L’adresse du problème : /errors/<code>.
Sur un corps qui échoue à la validation, une entrée par champ.
object
Example
{ "code": "BAD_REQUEST", "status": 404, "title": "Not Found", "type": "/errors/INBOX_NOT_FOUND", "violations": [ { "code": "BAD_REQUEST" } ]}Aucune clé, ou une clé refusée. WWW-Authenticate dit où lire comment en présenter une.
Un refus, en application/problem+json (RFC 9457) avec le code du registre. Un code ajoute les membres que sa règle demande (retryAfter, permission…), donc d’autres membres que ceux-ci peuvent arriver.
object
Le code stable du refus. Il ne change jamais une fois publié.
Du texte en anglais pour la personne qui lit la réponse. Il peut être reformulé : branchez-vous sur code.
Le statut HTTP.
Le nom du statut HTTP.
L’adresse du problème : /errors/<code>.
Sur un corps qui échoue à la validation, une entrée par champ.
object
Example
{ "code": "BAD_REQUEST", "status": 404, "title": "Not Found", "type": "/errors/INBOX_NOT_FOUND", "violations": [ { "code": "BAD_REQUEST" } ]}La clé n’a pas la permission de l’opération, ou l’opération refuse toutes les clés.
Un refus, en application/problem+json (RFC 9457) avec le code du registre. Un code ajoute les membres que sa règle demande (retryAfter, permission…), donc d’autres membres que ceux-ci peuvent arriver.
object
Le code stable du refus. Il ne change jamais une fois publié.
Du texte en anglais pour la personne qui lit la réponse. Il peut être reformulé : branchez-vous sur code.
Le statut HTTP.
Le nom du statut HTTP.
L’adresse du problème : /errors/<code>.
Sur un corps qui échoue à la validation, une entrée par champ.
object
Example
{ "code": "BAD_REQUEST", "status": 404, "title": "Not Found", "type": "/errors/INBOX_NOT_FOUND", "violations": [ { "code": "BAD_REQUEST" } ]}Il n’y a rien avec cet identifiant à la portée de la clé. La réponse est la même pour une autre organisation ou un espace de travail que la clé ne nomme pas.
Un refus, en application/problem+json (RFC 9457) avec le code du registre. Un code ajoute les membres que sa règle demande (retryAfter, permission…), donc d’autres membres que ceux-ci peuvent arriver.
object
Le code stable du refus. Il ne change jamais une fois publié.
Du texte en anglais pour la personne qui lit la réponse. Il peut être reformulé : branchez-vous sur code.
Le statut HTTP.
Le nom du statut HTTP.
L’adresse du problème : /errors/<code>.
Sur un corps qui échoue à la validation, une entrée par champ.
object
Example
{ "code": "BAD_REQUEST", "status": 404, "title": "Not Found", "type": "/errors/INBOX_NOT_FOUND", "violations": [ { "code": "BAD_REQUEST" } ]}Plus d’appels que la clé n’en peut faire en une minute. Retry-After dit quand réessayer.
Un refus, en application/problem+json (RFC 9457) avec le code du registre. Un code ajoute les membres que sa règle demande (retryAfter, permission…), donc d’autres membres que ceux-ci peuvent arriver.
object
Le code stable du refus. Il ne change jamais une fois publié.
Du texte en anglais pour la personne qui lit la réponse. Il peut être reformulé : branchez-vous sur code.
Le statut HTTP.
Le nom du statut HTTP.
L’adresse du problème : /errors/<code>.
Sur un corps qui échoue à la validation, une entrée par champ.
object
Example
{ "code": "BAD_REQUEST", "status": 404, "title": "Not Found", "type": "/errors/INBOX_NOT_FOUND", "violations": [ { "code": "BAD_REQUEST" } ]}L’instance qui tient l’appel s’arrête et ne peut pas finir une attente : Retry-After: 1, renvoyez l’appel. Ce n’est jamais une page vide.
Un refus, en application/problem+json (RFC 9457) avec le code du registre. Un code ajoute les membres que sa règle demande (retryAfter, permission…), donc d’autres membres que ceux-ci peuvent arriver.
object
Le code stable du refus. Il ne change jamais une fois publié.
Du texte en anglais pour la personne qui lit la réponse. Il peut être reformulé : branchez-vous sur code.
Le statut HTTP.
Le nom du statut HTTP.
L’adresse du problème : /errors/<code>.
Sur un corps qui échoue à la validation, une entrée par champ.
object
Example
{ "code": "BAD_REQUEST", "status": 404, "title": "Not Found", "type": "/errors/INBOX_NOT_FOUND", "violations": [ { "code": "BAD_REQUEST" } ]}Any refusal: an application/problem+json body whose code says which.
Un refus, en application/problem+json (RFC 9457) avec le code du registre. Un code ajoute les membres que sa règle demande (retryAfter, permission…), donc d’autres membres que ceux-ci peuvent arriver.
object
Le code stable du refus. Il ne change jamais une fois publié.
Du texte en anglais pour la personne qui lit la réponse. Il peut être reformulé : branchez-vous sur code.
Le statut HTTP.
Le nom du statut HTTP.
L’adresse du problème : /errors/<code>.
Sur un corps qui échoue à la validation, une entrée par champ.
object
Example
{ "code": "BAD_REQUEST", "status": 404, "title": "Not Found", "type": "/errors/INBOX_NOT_FOUND", "violations": [ { "code": "BAD_REQUEST" } ]}