Features9 min

Tâches de compte et interactions

Répondre aux tâches ouvertes par l'agent Billabex : rechercher, lister, consulter, annuler, mettre de côté, et ajouter une interaction.

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 :

  1. Créée : l’agent ouvre une tâche quand une intervention est nécessaire
  2. Ouverte : la tâche attend une réponse
  3. Interaction : un utilisateur répond par un message
  4. 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. Appelez GET /account-tasks/:accountTaskId pour le fil d’une tâche.
  • Le endCursor appartient aux filtres et au tri pour lesquels il a été émis. Changer l’un ou l’autre l’invalide, et l’appel renvoie 400 avec le code LIST_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 message type: "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 : enregistrer sourceRef, declaredAt, et éventuellement paymentDate, amount, currency, declaredStage, invoiceNumbers, proofDocumentAttached. Réutiliser sourceRef lors d’une nouvelle tentative.
  • POST /{declarationId}/resolve : fournir resolution et une note explicite.

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

Support

Une question sur les tâches de compte et les interactions ? Écrivez-nous via le formulaire de contact.