Problème API purchaseRegister (Erreur 500)

Bonsoir, je rencontre un souci avec l’API de Abby qui me renvoi une 500 Internal server error.

Voici les détails de la requête POST :

payload = {
« valueDate »: « 2025-04-23T22:16:09.890Z »,
« paymentMethodUsed »: 1,
« otherPaymentMethodUsed »: « text »,
« amount »: 1,
« thirdPartyId »: « text »,
« label »: « text »,
« reference »: « text »,
« entries »: [
{
« vatId »: 1,
« accountingAccountNumber »: 1,
« isPersonal »: True,
« amount »: 1
}
]
}

headers = {
« Authorization »: f"Bearer {ABBY_API_TOKEN}",
« Content-Type »: « application/json »,
« Accept »: « / »,
}

response = requests.post(
f"{ABBY_BASE_URL}/v2/purchaseRegister",
headers=headers,
data=json.dumps(payload),
timeout=60
)

Bien évidement, le token API est bien valide.

Je souhaite créer un outil avec IA qui permet de scanner des documents PDF et des images afin de reconnaître automatiquement les différents champs du livre des dépenses (achats). La partie concernant l’IA a été faite il me manque plus que l’envoi sur Abby.

Merci d’avance pour votre aide :wink:

Bonjour,

L’erreur que vous rencontrez est liée au champ thirdPartyId, qui doit impérativement faire référence à un fournisseur valide associé à votre compte. Si ce lien n’est pas pertinent dans votre cas, il est préférable d’envoyer la valeur null.

Par ailleurs, concernant le champ paymentMethodUsed, il n’est pas nécessaire de renseigner otherPaymentMethodUsed si la valeur de paymentMethodUsed est différente de 8.

Je vous invite à effectuer un nouvel essai en tenant compte de ces éléments. N’hésitez pas à revenir vers moi si le problème persiste.

Rebonjour, merci pour votre réponse.
Nous ne pouvons pas définir un nom d’entreprise par du texte brut ?

Bonjour,

Non, ce n’est pas possible. Le fournisseur doit obligatoirement être renseigné en amont dans l’application, comme illustré sur la capture d’écran ci-jointe. Cela permet de lier correctement l’achat au fournisseur concerné.

N’hésitez pas si vous avez d’autres questions

Ok et y’a une route API pour lister les fournisseurs et en créer ?

Même avec "thirdPartyId": "null" j’ai l’erreur.

Bonjour,

Je vois ce payload de notre côté.

{
"amount": 1,

"entries": [
1 item
],
"label": "text",
"otherPaymentMethodUsed": "text",
"paymentMethodUsed": 1,
"reference": "text",
"thirdPartyId": "0",
"valueDate": "2025-04-23T22:16:09.890Z"
}

Cela indique "thirdPartyId": "0" Pouvez-vous me confirmer cela ?

Bonjour,

Les endpoints permettant l’ajout de fournisseurs ne sont pas encore disponibles dans la documentation publique de l’API. En attendant leur publication, je vous invite à consulter la page “Fournisseurs” directement dans l’application, qui vous donnera un aperçu du fonctionnement.

Concrètement, lors de la création d’un fournisseur (similaire à un contact, mais avec le type « fournisseur »), un numéro de compte comptable lui est automatiquement associé. Ce compte est référencé par la propriété accountingAccountId au sein de l’objet fournisseur. Cette information sera également requise lors de la création d’une écriture dans le livre des achats.

Je suis en train de préparer une documentation plus détaillée sur ce sujet, et je reviendrai vers vous dans la journée avec davantage d’éléments.

Oui j’ai essayé avec « 0 » de base j’avais testé votre requête de la documentation et ça ne fonctionne pas Erreur 500.

En relisant attentivement et après vérification des logs d’erreur, j’ai remarqué que la valeur transmise pour le champ thirdPartyId est une chaîne de caractères contenant le mot "null" (c’est-à-dire "thirdPartyId": "null"), au lieu de la valeur nulle attendue au format JSON, c’est-à-dire null sans les guillemets ("thirdPartyId": null).

Ce détail est important, car "null" (avec des guillemets) est interprété comme une chaîne de caractères, et non comme une valeur nulle. Cela peut entraîner un comportement inattendu ou une erreur côté serveur, notamment si ce champ est censé référencer un identifiant absent ou non défini.

Je vous recommande donc de modifier la requête pour envoyer la valeur correcte : thirdPartyId: null.

N’hésitez pas si vous avez besoin d’aide pour ajuster la structure de la requête.

PS : J’ai bien avancé sur la documentation du endpoint « fournisseur » et je reviendrai vers vous dès qu’elle sera finalisée.

Ok merci pour votre réactivité c’est que j’utilise Python donc j’ai essayé None etc

Effectivement, le langage Python ne dispose pas d’un mot-clé null tel qu’on le retrouve dans le format JSON. En revanche, son équivalent en Python est la valeur spéciale None. Lors de la génération de données JSON avec Python, la bibliothèque standard json se charge automatiquement de convertir None en null dans le format attendu par l’API.

import json

data = {
    "name": "Produit A",
    "description": None  # équivalent de `null` en JSON
}

print(json.dumps(data))

Ce code produira le JSON suivant :

{
  "name": "Produit A",
  "description": null
}

Ainsi, vous pouvez utiliser None dans votre code Python lorsque vous souhaitez représenter une valeur absente ou facultative dans vos appels à notre API.

N’hésitez pas à revenir vers moi si vous avez d’autres questions.

Oui c’est bien ce que j’ai fait justement et ça ne fonctionne pas

Ah maintenant je pense que vous avez mis a jour votre API car le message d’erreur est plus clair. « thirdPartyId must be a string »

Ou peut être que ça y était déjà mais il n’est pas possible de mettre une valeur null pour ce paramètre

Effectivement, en rédigeant la documentation, j’ai pu clarifier l’ensemble des éléments nécessaires — et je m’excuse si mes réponses précédentes ont pu prêter à confusion.

Voici un récapitulatif complet de la procédure à suivre pour créer un fournisseur via notre API, avec toutes les informations utiles.

Endpoint : Créer un fournisseur

POST /provider

Description
Cet endpoint permet de créer un nouveau fournisseur pour la société courante. Il enregistre ses informations principales ainsi que ses éventuels contacts, et génère automatiquement un compte comptable associé.

Corps de la requête (payload)

interface CreateProviderPayload {
  additionalAddress?: string;
  address?: string;
  city?: string;
  commercialName?: string;
  contacts?: Contact[];
  country?: string;
  keywords?: string;
  language?: string;
  nafCode?: string;
  name?: string;
  notes?: string;
  phone?: string;
  siren?: string;
  siret?: string;
  vatNumber?: string;
  website?: string;
  zipCode?: string;
}

interface Contact {
  firstname: string;
  lastname: string;
  email?: string;
  phone?: string;
}

Note importante : Bien que le champ contacts permette d’envoyer une liste, la gestion de plusieurs contacts par fournisseur n’est pas encore active dans l’application. Cette structure a été pensée pour anticiper de futures évolutions, et la fonctionnalité sera disponible dans une version à venir.

Exemple de requête

POST /provider
Content-Type: application/json

{
  "name": "Société ABC",
  "commercialName": "ABC Fournitures",
  "address": "12 rue des Fleurs",
  "zipCode": "75001",
  "city": "Paris",
  "country": "France",
  "contacts": [
    {
      "firstname": "Jean",
      "lastname": "Dupont",
      "email": "jean.dupont@abc.com",
      "phone": "0601020304"
    }
  ],
  "siret": "12345678900012",
  "vatNumber": "FR123456789"
}

Réponse de l’API

interface ProviderResponse {
  id: string;
  name: string;
  commercialName?: string;
  address?: string;
  zipCode?: string;
  city?: string;
  country?: string;
  contacts?: Contact[];
  siret?: string;
  vatNumber?: string;
  // autres champs retournés
}

Exemple de réponse

{
  "id": "provider-uuid-123",
  "name": "Société ABC",
  "commercialName": "ABC Fournitures",
  "address": "12 rue des Fleurs",
  "zipCode": "75001",
  "city": "Paris",
  "country": "France",
  "contacts": [
    {
      "firstname": "Jean",
      "lastname": "Dupont",
      "email": "jean.dupont@abc.com",
      "phone": "0601020304"
    }
  ],
  "siret": "12345678900012",
  "vatNumber": "FR123456789"
}

Fonctionnement interne

  • L’API complète automatiquement les données avec l’identifiant de la société courante et le type PROVIDER.
  • Un compte comptable est généré automatiquement pour ce fournisseur.
  • Le fournisseur et ses contacts (s’ils sont précisés) sont enregistrés en base de données.

N’hésitez pas à revenir vers moi si vous avez d’autres questions ou besoins d’éclaircissements !

Endpoint : Récupérer la liste paginée des fournisseurs

URL

GET /providers

Description

Cet endpoint permet de récupérer la liste des fournisseurs associés à la société courante. Il prend en charge la pagination, la recherche, le tri et les filtres, ce qui le rend particulièrement adapté à l’affichage dans une interface utilisateur ou à l’export de données.

Paramètres de requête

Tous les paramètres doivent être passés en tant que query parameters dans l’URL :

Nom Type Obligatoire Description
page number :white_check_mark: Oui Numéro de la page à récupérer (à partir de 1).
limit number :white_check_mark: Oui Nombre d’éléments à retourner par page.
search string :cross_mark: Non Terme de recherche global (appliqué sur le nom, SIRET, adresse, etc.).
type enum :cross_mark: Non Type de tiers à filtrer (ex. : provider).
sortBy string :cross_mark: Non Liste des champs à utiliser pour le tri (ex. : ["name"]).
sortDesc boolean :cross_mark: Non Indique si le tri est descendant (true) ou ascendant (false) pour chaque champ de sortBy.
countWithoutFilters boolean :cross_mark: Non Si true, retourne également le nombre total d’éléments sans filtre de recherche.

Exemple d’appel

GET /providers?page=1&limit=20&search=abc&sortBy=name&sortDesc=true

Structure de la réponse

L’API retourne un objet paginé contenant :

interface BasePaginate<T> {
  maxPages: number;              // Nombre total de pages disponibles
  currentPage: number;           // Page actuellement retournée
  totalItems: number;            // Nombre total d’éléments correspondant aux filtres
  data: T[];                     // Liste des fournisseurs pour la page demandée
  countWithoutFilters?: number;  // (Optionnel) Nombre total d’éléments sans filtre
}

Exemple de réponse

{
  "maxPages": 5,
  "currentPage": 1,
  "totalItems": 100,
  "data": [
    {
      "id": "provider-uuid-123",
      "name": "Société ABC",
      "commercialName": "ABC Fournitures",
      "address": "12 rue des Fleurs",
      "zipCode": "75001",
      "city": "Paris",
      "country": "France",
      "contacts": [
        {
          "firstname": "Jean",
          "lastname": "Dupont",
          "email": "jean.dupont@abc.com",
          "phone": "0601020304"
        }
      ],
      "siret": "12345678900012",
      "vatNumber": "FR123456789"
    }
    // ... autres fournisseurs
  ],
  "countWithoutFilters": 200
}

Fonctionnement interne

  • L’API applique les critères de pagination, recherche et tri uniquement aux fournisseurs de la société courante.
  • Les champs inclus dans la recherche sont : nom, nom commercial, SIRET, SIREN, adresse, et code postal.
  • Si countWithoutFilters=true, le nombre total de fournisseurs non filtrés est également retourné.
  • La réponse inclut toujours la page demandée, le nombre total d’éléments filtrés, ainsi que la liste des fournisseurs correspondants.

Ok super merci beaucoup je vais tester ça. C’est dommage que vous ne souhaitez pas intégrer des fonctionnalités IA dans votre outil, cela permettrait d’auto-compléter une dépense a partir d’un document PDF ou d’une facture avec vérification manuelle bien sûr.

Super, concernant thirdPartyId je peux pas mettre null est ce normal ?

Pour le moment, il est en effet nécessaire de créer un fournisseur en amont : aucun paramètre par défaut n’est encore prévu à ce stade. Cela dit, nous envisageons d’ajouter à l’avenir la possibilité de configurer un fournisseur par défaut, ce qui simplifierait certains cas d’usage.

Concernant vos idées autour des fonctionnalités basées sur l’IA : c’est une excellente suggestion ! Toute l’équipe produit est à l’écoute de ce type de propositions. N’hésitez pas à les partager via notre formulaire dédié :
:backhand_index_pointing_right: Formulaire de suggestion

Nous avons de nombreuses évolutions en préparation, et vos retours sont précieux pour nous aider à façonner les prochaines fonctionnalités !