Une tâche de compte représente dans Billabex une action à mener qui demande une intervention ou une approbation humaine. Elles sont créées exclusivement par l’agent Billabex, quand il a besoin d’une consigne, d’une coordonnée de contact ou d’une approbation explicite pour poursuivre le suivi d’un compte.
Ce guide couvre leur usage par l’API : lister, consulter, annuler, mettre de côté et répondre par une interaction.
Vue d’ensemble
Une tâche de compte suit un cycle de vie simple :
- Créée : l’agent ouvre une tâche quand une intervention est nécessaire
- Ouverte : la tâche attend une réponse
- Interaction : un utilisateur répond par un message
- Close ou annulée : la tâche est résolue par l’agent, ou annulée par l’utilisateur
Chaque tâche porte un type, qui détermine la forme de réponse attendue.
Note : seul l’agent Billabex peut créer une tâche de compte. L’API publique permet de les lire, d’y répondre, de les mettre de côté et de les annuler, pas d’en créer.
Types de tâches
| Type | Description | Réponse attendue |
|---|---|---|
ApproveEligibility |
Approuver ou refuser un contact pour le suivi | Structurée : boolean |
NeedContacts |
Fournir les coordonnées d’un contact pour un compte | Structurée : objet contact |
AskNextAction |
Question ouverte de l’agent | Message texte |
NeedUserInput |
L’agent a besoin d’une précision ou d’une information | Message texte |
Unknown |
Type de repli | Structurée : boolean |
Notice |
L’agent signale une action qu’il a déjà faite ; rien n’est attendu | Aucune |
extraData.idempotencyKey
Les types de tâches qui ne portent pas de charge structurée propre (Notice, AskNextAction,
NeedContacts, ApproveFirstOutreach, Unknown) exposent extraData.idempotencyKey. C’est une
clé stable que l’agent pose quand plusieurs tâches d’un même type peuvent légitimement coexister sur
un compte, et elle vaut null sinon. Elle ne change pas quand la tâche est rejouée : utilisez-la
pour reconnaître une tâche déjà vue. Un Notice signalant une réclamation client est par exemple
clé par contact-grievance:<identifiant de l'email entrant>.
Scopes nécessaires
| Scope | Niveau d’accès | Endpoints |
|---|---|---|
tasks:read |
Lecture seule | GET /account-tasks, GET /account-tasks/search, GET /account-tasks/:accountTaskId |
tasks:all |
Accès complet | Tout le précédent + POST /account-tasks/:accountTaskId/cancel, POST /account-tasks/:accountTaskId/set-pending, interactions |
Lister les tâches actives
Récupérer les tâches actives d’un compte précis.
GET [baseURL]/api/public/v1/account-tasks?accountId=ACCOUNT_ID
Authorization: Bearer YOUR_ACCESS_TOKEN
Paramètres de requête :
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
accountId |
UUID | oui | Restreindre les tâches à ce compte |
type |
chaîne | non | Restreindre à un type de tâche |
Exemple de réponse :
[
{
"task": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"organizationId": "org-uuid",
"accountId": "account-uuid",
"type": "NeedUserInput",
"title": "Clarification needed on invoice #1234",
"status": "UserActionRequired",
"isActive": true,
"isClosed": false,
"isCanceled": false,
"thread": [
{
"id": "interaction-uuid",
"message": {
"type": "Text",
"value": "The customer mentioned a dispute. How should I proceed?"
},
"attachments": [],
"sentAt": "2024-05-01T10:15:30.000Z",
"agent": {
"email": "agent@billabex.com",
"firstName": "Alex",
"lastName": "Martin"
}
}
],
"assignees": [],
"createdAt": "2024-05-01T10:15:30.000Z",
"closedAt": null,
"canceledAt": null,
"cancelReason": null,
"canceledBy": null,
"completedAt": null,
"isPending": false,
"pendingAt": null,
"pendingUntil": null,
"extraData": { "refEmailMessageIds": [] }
}
}
]
Rechercher des tâches de compte
GET /account-tasks répond pour un seul compte et renvoie ses tâches actives d’un coup. Pour
travailler à l’échelle de l’organisation, avec filtres, tri et pagination, utilisez l’endpoint de
recherche.
GET [baseURL]/api/public/v1/account-tasks/search?organizationId=ORG_ID&first=20
Authorization: Bearer YOUR_ACCESS_TOKEN
Paramètres de requête :
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
organizationId |
UUID | oui | Organisation dans laquelle chercher |
accountId |
UUID | non | Restreindre à un seul compte |
query |
chaîne | non | Recherche en texte libre sur le titre de la tâche et le nom du compte |
filters |
chaîne | non | Conditions de filtrage, voir Pagination et filtres |
sortBy |
chaîne | non | createdAt, updatedAt, title, accountFullName, status ou balance |
sortOrder |
chaîne | non | asc ou desc |
first |
entier | non | Entre 1 et 100 |
after |
chaîne | non | Curseur issu de pageInfo.endCursor |
Champs filtrables :
| Champ | Opérateurs |
|---|---|
title |
contains, startsWith, equals |
accountName |
contains, startsWith, equals |
status |
is, isNot, isAnyOf |
type |
is, isNot, isAnyOf |
tags |
containsAny, containsAll, containsNone, isEmpty, isNotEmpty |
balance |
equals, greaterThan, lessThan, between, isEmpty, isNotEmpty |
createdAt |
on, before, after, between |
updatedAt |
on, before, after, between, isEmpty, isNotEmpty |
type accepte ApproveEligibility, ApproveContactChange, ApprovePaymentArrangement,
ApproveFirstOutreach, NeedContacts, AskNextAction, NeedUserInput,
PaymentScheduleInvalidated, Notice et Unknown. status accepte les valeurs du tableau plus
bas dans cette page.
Les tâches ouvertes d’un type donné, les plus récentes d’abord :
GET [baseURL]/api/public/v1/account-tasks/search?organizationId=ORG_ID&filters=status%3Ais%3AUserActionRequired%3Btype%3Ais%3ANeedContacts&sortBy=createdAt&sortOrder=desc
Les tâches créées depuis le début du trimestre, sur des comptes devant plus de 1000 :
GET [baseURL]/api/public/v1/account-tasks/search?organizationId=ORG_ID&filters=createdAt%3Aafter%3A2026-06-30%3Bbalance%3AgreaterThan%3A1000
Exemple de réponse :
{
"nodes": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"organizationId": "org-uuid",
"accountId": "account-uuid",
"accountFullName": "Acme Corporation",
"accountTagIds": [],
"title": "Clarification needed on invoice #1234",
"type": "NeedUserInput",
"status": "UserActionRequired",
"assignees": [],
"assigneesFullName": [],
"isActive": true,
"isClosed": false,
"isCanceled": false,
"isPending": false,
"balance": 1250.5,
"currency": "EUR",
"createdAt": "2026-05-01T10:15:30.000Z",
"updatedAt": "2026-05-02T08:00:00.000Z",
"closedAt": null,
"canceledAt": null,
"cancelReason": null,
"canceledBy": null,
"pendingAt": null,
"pendingUntil": null,
"completedAt": null,
"lastAgentInteractionAt": "2026-05-01T10:15:30.000Z"
}
],
"pageInfo": {
"endCursor": "v2:8f14e45fceea:2"
}
}
Deux points à garder en tête :
- Les éléments ne portent pas le fil d’interactions
thread. AppelezGET /account-tasks/:accountTaskIdpour le fil d’une tâche. - Le
endCursorappartient aux filtres et au tri pour lesquels il a été émis. Changer l’un ou l’autre l’invalide, et l’appel renvoie400avec le codeLIST_CURSOR_INVALID.
Consulter une tâche
Récupérer une tâche par son identifiant.
GET [baseURL]/api/public/v1/account-tasks/:accountTaskId
Authorization: Bearer YOUR_ACCESS_TOKEN
Renvoie la même structure que plus haut, enveloppée dans { "task": { ... } }.
Annuler une tâche
Annuler une tâche active la marque comme annulée sans la résoudre.
POST [baseURL]/api/public/v1/account-tasks/:accountTaskId/cancel
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"reason": "Facture renvoyée à la main, le contact a confirmé la réception."
}
Le corps est facultatif, et reason aussi (2000 caractères au plus). En fournir une est
fortement recommandé : l’annulation est la seule issue qui ne répond à rien, et plusieurs types de
tâches retiennent les relances automatiques tant qu’elles sont actives. En annuler une rend donc la
cadence à l’agent. Le motif est affiché à côté de l’annulation, et l’agent le relit avant de
rouvrir le même sujet sur ce compte.
Renvoie la tâche mise à jour, avec isCanceled: true, canceledAt renseigné, cancelReason
portant le motif s’il a été donné, et canceledBy nommant qui a annulé et par quelle porte :
{
"canceledBy": {
"userId": "usr_01H8...",
"userFullName": "Camille Roy",
"channel": "PublicApi"
}
}
canceledBy vaut null quand c’est l’agent qui a annulé, et sur les annulations enregistrées avant
le 2026-09-03. channel vaut Webapp, PublicApi ou Mcp, et null sur une annulation
enregistrée avant que la porte soit suivie. userFullName vaut null quand l’utilisateur n’a pas
pu être nommé, typiquement après son départ de l’organisation.
Mettre une tâche de côté
Reporter une tâche plutôt que d’y répondre tout de suite, en nommant éventuellement la date à laquelle elle doit revenir.
POST [baseURL]/api/public/v1/account-tasks/:accountTaskId/set-pending
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"pendingUntil": "2026-09-20T08:00:00.000Z"
}
Le corps est facultatif, et pendingUntil aussi, qui doit être un instant ISO 8601 dans le futur.
Fournissez-le dès que vous savez quand la réponse sera disponible : à cette date, Billabex publie un
message d’agent sur la tâche expliquant qu’elle est de retour, et la tâche repasse d’elle-même en
UserActionRequired.
Sans lui, la tâche revient quand même, au bout de 30 jours. Une tâche ne reste jamais de côté indéfiniment, et cela compte parce que plusieurs types de tâches retiennent les relances automatiques de leur compte tant qu’elles sont actives : reporter une tâche repousse la décision, il ne rend pas la cadence. Annulez la tâche ou répondez-y pour cela.
Renvoie la tâche mise à jour, avec isPending: true, pendingAt renseigné, et pendingUntil
portant la date si elle a été donnée.
Ajouter une interaction
Répondre à une tâche en y ajoutant une interaction utilisateur. C’est ainsi que l’on fournit à l’agent Billabex l’information qu’il demande.
POST [baseURL]/api/public/v1/account-tasks/:accountTaskId/interactions
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
Interaction texte
Pour les tâches NeedUserInput et AskNextAction :
{
"interaction": {
"message": {
"type": "Text",
"value": "Proposez un échéancier sur 3 mois avec 10 % d'intérêts."
},
"attachments": []
}
}
Interaction structurée
Pour les tâches ApproveEligibility, NeedContacts et Unknown, utilisez un message structuré.
Réponse à ApproveEligibility
{
"interaction": {
"message": {
"type": "Structured",
"schema": "ApproveEligibility",
"schemaVersion": 1,
"value": true
}
}
}
value est un booléen : true pour approuver, false pour refuser.
Réponse à NeedContacts
{
"interaction": {
"message": {
"type": "Structured",
"schema": "NeedContacts",
"schemaVersion": 1,
"value": {
"fullName": "Jane Doe",
"email": "jane@company.com",
"language": "fr"
}
}
}
}
Champs obligatoires dans value :
fullName(chaîne)email(chaîne)language(chaîne, par exemple « en » ou « fr »)
Réponse à Unknown
{
"interaction": {
"message": {
"type": "Structured",
"schema": "Unknown",
"schemaVersion": 1,
"value": true
}
}
}
Référence des schémas de message
| Type de tâche | Nom du schéma | Version | Type de valeur |
|---|---|---|---|
ApproveEligibility |
ApproveEligibility |
1 | boolean |
NeedContacts |
NeedContacts |
1 | { fullName, email, language } |
Unknown |
Unknown |
1 | boolean |
AskNextAction |
sans objet | sans objet | Message texte uniquement |
NeedUserInput |
sans objet | sans objet | Message texte uniquement |
Règles de validation
L’API valide strictement les messages d’interaction :
- une tâche texte (
NeedUserInput,AskNextAction) doit recevoir un messagetype: "Text"; - une tâche structurée doit recevoir un message
type: "Structured"au schéma correspondant ; - le nom et la version du schéma doivent correspondre exactement ;
- la valeur doit respecter le type attendu par ce schéma.
Un message invalide renvoie 400 Bad Request avec le détail.
Statuts d’une tâche
| Statut | Description |
|---|---|
Open |
Tâche créée, en attente de traitement |
InProgress |
L’agent y travaille |
UserActionRequired |
En attente d’une réponse utilisateur |
Closed |
Tâche menée à bien |
Canceled |
Tâche annulée |
Pending |
Tâche mise de côté, de retour à pendingUntil ou au bout de 30 jours |
Erreurs courantes
400 Bad Request, message invalide
{
"statusCode": 400,
"message": "Text message is required for this task type"
}
Cause : un message structuré envoyé à une tâche qui n’accepte que du texte.
404 Not Found, tâche introuvable
{
"statusCode": 404,
"message": "Account task 123e4567-e89b-12d3-a456-426614174000 not found"
}
Cause : l’identifiant n’existe pas, ou la tâche appartient à une autre organisation.
403 Forbidden, scope insuffisant
{
"statusCode": 403,
"message": "Forbidden",
"error": "insufficient_scope"
}
Cause : votre jeton ne porte pas tasks:all pour une opération d’écriture.
Résolution des protections de relance
Une réponse NeedUserInput suit les mêmes règles dans la webapp, l’API et le MCP. Une instruction
n’est pas confirmée ni la tâche clôturée si ses effets n’ont pas pu être appliqués. Fermer, annuler
ou mettre de côté une tâche ne résout pas le paiement ou la correction qu’elle demande de vérifier.
Pour une correction annoncée, mettre à jour les factures concernées puis répondre à la tâche. Si la correction a été abandonnée, le préciser explicitement et autoriser la reprise sur la facture d’origine. Un simple « merci » ou une reprise générique ne constitue pas cette décision. Les paiements annoncés se résolvent par la décision explicite du compte, séparément de la tâche.
Paiements annoncés
Un paiement annoncé n’est pas un paiement comptabilisé. Le registre reste actif après clôture ou annulation de sa tâche. Utiliser le scope dunning:manage et les endpoints sous /api/public/v1/accounts/{accountId}/payment-declarations :
GET: lire les déclarations et décisions.POST: enregistrersourceRef,declaredAt, et éventuellementpaymentDate,amount,currency,declaredStage,invoiceNumbers,proofDocumentAttached. RéutilisersourceReflors d’une nouvelle tentative.POST /{declarationId}/resolve: fournirresolutionet unenoteexplicite.
proofDocumentAttached dit que le client a joint un document qu’il présente comme la preuve de ce règlement : un avis de virement, un reçu bancaire, une capture de la transaction. Le champ ne prouve rien de l’arrivée de l’argent et ne change ni le stade annoncé ni la retenue des relances ; il indique que le rapprochement part d’une référence et non d’une simple affirmation, et la tâche de revue le signale. Une déclaration enregistrée avant l’existence du champ le porte à false.
La question de revue s’ouvre dès l’enregistrement de la déclaration, pas à l’expiration de sa période de grâce.
Résolutions : PaymentReceived, CreditApplied, InvoicesSettled, PaymentNotReceived, Withdrawn, ResumeAuthorized. La réception confirmée (paymentConfirmedAt) ne libère pas les relances tant que les factures restent ouvertes. ResumeAuthorized autorise la reprise sans nier le paiement. Un avoir ou une facture soldée ne prouvent pas une réception bancaire. Toutes ces routes renvoient la liste courante des déclarations.
Pour aller plus loin
- Démarrage : le parcours d’intégration rapide
- Scopes OAuth : les permissions nécessaires
- Pagination et filtres : curseurs et paramètre
filters - Limites de débit : éviter de les atteindre
- Référence de l’API : documentation complète des endpoints
Support
Une question sur les tâches de compte et les interactions ? Écrivez-nous via le formulaire de contact.