tributs

API v1

API Tributs

Lisez les données de vos entreprises depuis Power BI, Excel (Power Query) ou votre propre programme. L'API est en lecture seule et voit exactement ce que vous voyez dans Tributs, avec vos autorisations.

  • Lecture seule
  • REST + JSON
  • OpenAPI 3.1
  • Jeton Bearer
Sur cette page
  1. Présentation
  2. Démarrage rapide
  3. Authentification
  4. Pagination et synchronisation
  5. Ressources
  6. Conventions
  7. Limites
  8. Erreurs
  9. Excel et Power BI
  10. Assistants IA
  11. Sécurité
  12. Versions

Présentation

L'API a deux adresses. Celle des comptes, accounts.tributs.ad, indique à quelles entreprises vous avez accès. Chaque entreprise sert ses données à sa propre adresse, et ces données ne passent que par là.

Tout utilisateur peut créer un jeton, quel que soit son rôle. Dans un cabinet comptable, un seul jeton lit toutes les entreprises de vos clients.

URL de basePour
https://accounts.tributs.ad/api/v1Les entreprises auxquelles le jeton a accès
https://{slug}.tributs.ad/api/v1Les données d'une entreprise

Démarrage rapide

  1. Créez un jeton

    Dans Tributs, ouvrez votre profil → Connexions externes → Créer un jeton. Donnez-lui le nom du programme qui l'utilisera et choisissez quand il expire : 30 jours, 90 jours ou 1 an. Le jeton (trb_…) ne s'affiche qu'une fois : copiez-le à ce moment-là.

  2. Trouvez vos entreprises

    Chaque entreprise arrive avec son api_base_url, l'adresse où vous lirez ses données.

    cURL
    curl https://accounts.tributs.ad/api/v1/companies \
      -H "Authorization: Bearer $TRIBUTS_TOKEN"
    200 OK · application/json
    {
      "data": [
        {
          "id": "acme.tributs.ad",
          "name": "Acme Serveis SL",
          "display_name": "Acme",
          "role": "advisor",
          "status": "active",
          "api_base_url": "https://acme.tributs.ad/api/v1"
        }
      ],
      "next_cursor": null,
      "has_more": false
    }
  3. Lisez les données

    Les listes sont paginées. Cet exemple récupère toutes les factures de vente depuis le 1er janvier.

    curl "https://acme.tributs.ad/api/v1/sales_invoices?date_from=2026-01-01&limit=200" \
      -H "Authorization: Bearer $TRIBUTS_TOKEN"

Authentification

Envoyez le jeton dans l'en-tête Authorization de chaque requête, avec le schéma Bearer. Toutes les requêtes passent par HTTPS.

HTTP
Authorization: Bearer trb_…
  • Le jeton est opaque : trb_ suivi de 40 caractères. Tributs n'en conserve qu'une empreinte (SHA-256) : personne ne peut le revoir.
  • Il expire toujours : après 30 jours, 90 jours ou 1 an. Nous vous écrivons 7 jours avant et le jour de l'expiration.
  • Renouveler crée une nouvelle clé pour le même jeton. L'ancienne cesse de fonctionner en moins d'une minute ; le nom et l'historique sont conservés.
  • Vous pouvez le révoquer à tout moment. La révocation atteint toutes les entreprises en 60 secondes au plus.
  • Il agit en votre nom : dans chaque entreprise, il a exactement votre rôle et vos autorisations.
  • Jusqu'à 10 jetons actifs par personne. Utilisez un jeton par programme.

L'entreprise garde le contrôle

Le propriétaire de chaque entreprise voit dans les réglages qui la consulte par l'API, avec quel jeton et quand, et peut couper l'accès à tous ou à une personne.

Pagination et synchronisation

Les listes renvoient data, next_cursor et has_more. Tant que has_more vaut true, rappelez avec les mêmes paramètres et cursor=<next_cursor>. limit va de 1 à 200 (50 par défaut, et 50 au maximum avec expand=lines).

Les éléments sont triés par dernière modification, du plus ancien au plus récent. Pour garder une copie à jour, conservez le updated_at du dernier élément et passez-le en updated_since la fois suivante : vous recevez ce qui a changé depuis. Enregistrez les éléments par id en remplaçant ceux que vous avez déjà, car ceux de la dernière seconde peuvent revenir.

Un document annulé réapparaît avec status: "cancelled". Les brouillons n'apparaissent pas : seuls les documents émis sont renvoyés. Les mouvements bancaires font exception, car ils ne sont pas émis : ils apparaissent toujours, et un mouvement manuel supprimé disparaît sans préavis.

Les factures et les mouvements bancaires acceptent sort : total_desc (les factures les plus élevées d'abord), issue_date_desc (les factures les plus récentes d'abord) et date_desc (les mouvements les plus récents d'abord). Un cursor ne vaut que pour le tri avec lequel il a été demandé. Avec include=totals, la première page (l'appel sans cursor) contient totals : combien d'éléments correspondent aux filtres et quelle somme ils représentent, toutes pages confondues. Les éléments annulés sont comptés à part et n'entrent pas dans les sommes.

Ressources

Toutes les ressources répondent à GET. Le contrat complet, avec chaque champ et chaque paramètre, est le fichier OpenAPI 3.1 que chaque entreprise sert sans jeton à {api_base_url}/openapi.json. Importez-le dans Postman ou générez-en un client.

EndpointContenuFiltres
GET/companies Entreprises que le jeton peut lire, avec l'api_base_url de chacune. S'appelle sur accounts.tributs.ad. —
GET/contacts Clients et fournisseurs, avec NRT, pays et rôles. role
GET/sales_invoices Factures de vente émises, avoirs et clôtures de caisse. expand=lines ajoute les lignes et l'IGI par taux. date_fromdate_tostatustypecontact_idmin_totalsortinclude=totalsexpand=lines
GET/purchase_invoices Factures d'achat et avoirs, avec l'IGI déductible effectivement supporté. date_fromdate_tostatustypecontact_idmin_totalsortinclude=totalsexpand=lines
GET/journal_lines Lignes du journal : date, compte, débit, crédit, tiers et document d'origine. date_fromdate_toaccountcontact_iddocument_id
GET/accounts Plan comptable (PGC d'Andorre), avec numéro, nom et compte parent. —
GET/bank_transactions Mouvements bancaires et leur état de rapprochement. date_fromdate_tostatusbank_account_idmin_amountsortinclude=totals
GET/bank_accounts Comptes bancaires de l'entreprise avec deux soldes : celui des livres (ledger_balance) et celui du relevé de la banque (statement_balance). date
GET/receivables Ce que doit chaque client à ce jour : montant ouvert, échu, à 30 jours et acomptes non imputés. Par défaut, le solde le plus élevé d'abord ; sort=oldest_due, l'échéance la plus ancienne. min_amountsortinclude=totals
GET/payables Ce qui est dû à chaque fournisseur, avec les mêmes champs que receivables. min_amountsortinclude=totals
GET/obligations Calendrier fiscal : modèle, période, échéance, statut et résultat de la déclaration enregistrée. GET /obligations/{id} ajoute les chiffres case par case. yearstatusdeadline_fromdeadline_to
GET/payroll_summary Totaux de paie par mois : bulletins et personnes, brut, net, CASS du salarié et de l'entreprise, retenues (IRPF et IRNR) et coût total, salariés et associés séparés. Sans noms. month_frommonth_to
GET/payslips Bulletins de paie, un par personne et par mois : brut, net, CASS, retenue avec son taux, coût pour l'entreprise, état et date de paiement. include=totals ajoute les sommes. month_frommonth_toemployee_idstatuskindsortinclude=totals
GET/employees Personnes de l'effectif : nom, dates d'entrée et de sortie, type de contrat, catégorie et résidence fiscale. statuskind
GET/reports/profit_and_loss Compte de résultat par rubrique, avec le détail par compte. date_fromdate_toperiodicityperiods
GET/reports/balance_sheet Bilan par rubrique, avec le détail par compte. dateperiodicityperiods
GET/reports/trial_balance Balance générale : solde d'ouverture, débit, crédit et solde de clôture par compte. date_fromdate_to

Les listes paginées (toutes les ressources sauf companies, bank_accounts, payroll_summary et les états) acceptent aussi limit et cursor, ainsi que updated_since sauf receivables et payables, qui sont des soldes à ce jour.

Pour lire un seul document : GET /sales_invoices/{id}, /purchase_invoices/{id}, /contacts/{id} et /obligations/{id} (par id ou par code, par exemple M900-T2-2026). Les factures arrivent toujours avec leurs lignes, et l'obligation avec les chiffres de la déclaration enregistrée (filing) : résultat et détail par case des formulaires 900, 910, 800, 805, 810, 700, 710, 310 et 311. Les retenues sortent en totaux, sans la liste des bénéficiaires.

Hors de la v1 : PDF et pièces jointes, devis, bons de livraison, abonnements et projets. Pour les personnes de l'effectif, le NRT, le numéro d'affiliation à la CASS, l'IBAN et la date de naissance ne sont jamais renvoyés.

Exemple de réponse

GET /sales_invoices?limit=1
{
  "data": [
    {
      "id": "FV-26-00042",
      "number": "FV-26-00042",
      "type": "invoice",
      "status": "unpaid",
      "issue_date": "2026-10-02",
      "due_date": "2026-11-01",
      "contact_id": "Grup Ferrer SL",
      "contact_name": "Grup Ferrer SL",
      "contact_tax_id": "L712345A",
      "currency": "EUR",
      "net_amount": 1200.0,
      "tax_amount": 54.0,
      "total": 1254.0,
      "outstanding_amount": 1254.0,
      "document_currency": "EUR",
      "document_total": 1254.0,
      "exchange_rate": 1.0,
      "credited_invoice_id": null,
      "project_ids": [],
      "description": "Consultoria setembre",
      "disbursements_amount": 0.0,
      "created_at": "2026-10-02T08:14:03Z",
      "updated_at": "2026-10-02T08:14:03Z"
    }
  ],
  "next_cursor": "WyIyMDI2LTEwLTAyIDEwOjE0OjAzIiwiRlYtMjYtMDAwNDIiXQ",
  "has_more": true
}

Conventions

  • JSON, avec des noms de champ en anglais et en snake_case.
  • Les statuts sont des codes stables (paid, unpaid, cancelled…) et ne sont jamais traduits.
  • Les dates comptables sont au format YYYY-MM-DD (calendrier d'Andorre). Les instants, en RFC 3339 et UTC.
  • Les montants sont des nombres à 2 décimales en EUR, la devise de la comptabilité. Les documents en devise étrangère portent aussi document_currency, document_total et exchange_rate.
  • Les rubriques des états s'identifient par leur code (Decret 479/2025). Le libellé est le texte officiel en catalan.
  • Les chiffres d'un formulaire fiscal s'identifient par leur numéro de case (box) ; le libellé est en catalan, la langue du formulaire officiel.

Limites

60 requêtes par minute par jeton et par entreprise, en rafales de 20 au plus. Un état compte pour 5, tout comme bank_accounts, receivables, payables et payroll_summary. La limite étant par entreprise, un cabinet peut lire de nombreuses entreprises en parallèle ; chaque adresse IP a en plus un plafond global de 600 requêtes par minute.

En-têteSignification
RateLimit-LimitRequêtes par minute : 60.
RateLimit-RemainingRequêtes que vous pouvez encore faire tout de suite.
RateLimit-ResetSecondes avant que le compteur soit de nouveau plein.
RateLimit-PolicyLa politique appliquée : 60;w=60;burst=20.
Retry-AfterAvec 429 et 503 : secondes à attendre avant de réessayer.

Erreurs

Les erreurs suivent la RFC 9457 (application/problem+json). Le champ code est stable et type renvoie à la ligne correspondante de ce tableau.

application/problem+json
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json

{
  "type": "https://tributs.ad/developers#errors-expired-token",
  "title": "Access token expired",
  "status": 401,
  "code": "expired_token",
  "instance": "/api/v1/sales_invoices"
}
StatutcodeQue faire
401 missing_token Ajoutez l'en-tête Authorization: Bearer trb_….
401 invalid_token Le jeton n'existe pas ou a été mal copié. Vérifiez-le ou créez-en un nouveau.
401 expired_token Le jeton a expiré. Créez-en un nouveau depuis votre profil.
401 revoked_token Le jeton a été révoqué. Créez-en un nouveau depuis votre profil.
403 no_access Vous n'avez pas accès à cette entreprise.
403 permission_denied Votre rôle dans cette entreprise ne permet pas de lire cette ressource.
403 api_access_disabled Le propriétaire a coupé l'accès API de l'entreprise.
403 api_access_blocked Le propriétaire vous a coupé l'accès API à cette entreprise.
403 company_suspended L'abonnement de l'entreprise n'est pas actif.
400 invalid_parameter Un paramètre n'est pas valide. Le champ detail indique lequel.
404 not_found La ressource ou le document n'existe pas.
405 method_not_allowed L'API n'accepte que GET.
429 rate_limited Attendez le nombre de secondes indiqué dans Retry-After.
500 internal_error Erreur de notre côté. Réessayez ; si elle persiste, écrivez-nous.
503 maintenance L'entreprise est en maintenance. Réessayez après les secondes de Retry-After.
503 auth_unavailable Nous n'avons pas pu vérifier le jeton. Réessayez dans quelques secondes.

Excel et Power BI

Dans Excel ou Power BI, créez d'abord un paramètre texte TributsToken contenant le jeton (Gérer les paramètres). Ouvrez ensuite Obtenir les données → Requête vide → Éditeur avancé et collez cette requête, qui parcourt toutes les pages.

Power Query (M)
let
    Token = TributsToken,
    Base = "https://acme.tributs.ad/api/v1/sales_invoices",
    GetPage = (cursor as nullable text) =>
        Json.Document(Web.Contents(Base, [
            Query = if cursor = null
                then [limit = "200"]
                else [limit = "200", cursor = cursor],
            Headers = [Authorization = "Bearer " & Token]
        ])),
    Pages = List.Generate(
        () => GetPage(null),
        each _ <> null,
        each if _[has_more] then GetPage(_[next_cursor]) else null
    ),
    Rows = List.Combine(List.Transform(Pages, each _[data])),
    Invoices = Table.FromRecords(Rows)
in
    Invoices

Si des identifiants vous sont demandés, choisissez Anonyme : le jeton voyage déjà dans l'en-tête. L'URL de base fixe et les paramètres dans Query permettent d'actualiser le rapport depuis le service Power BI ; là, dans les identifiants de la source de données, cochez « Skip test connection » (ignorer le test de connexion), car ce test se fait sans jeton et reçoit une erreur 401. Le jeton est enregistré dans le fichier : utilisez-en un réservé à ce rapport et partagez le fichier uniquement avec les personnes autorisées à voir ces données.

Assistants IA

Un assistant IA (ChatGPT, Claude et d'autres logiciels compatibles MCP) peut lire les mêmes données que cette API, avec les mêmes requêtes et vos droits. Aucun jeton n'est nécessaire : vous vous connectez avec votre utilisateur Tributs.

  1. Dans l'assistant, ajoutez un connecteur personnalisé avec l'adresse https://mcp.tributs.ad/mcp, avec le /mcp final.
  2. Un écran de Tributs s'ouvre : connectez-vous avec votre utilisateur et cliquez sur Autoriser.
  3. Dans Réglages → Profil → Connexions externes, vous voyez l'application connectée et vous pouvez lui retirer l'autorisation.
  • Lecture seule. Chaque ressource de cette page est une requête de l'assistant, et les nouvelles lui arrivent d'elles-mêmes.
  • Limite propre : 120 requêtes par minute par connexion, avec des rafales jusqu'à 40, en plus de la limite de l'API par entreprise.
  • Claude Code, Cursor ou un logiciel maison qui parle MCP peuvent aussi entrer avec un jeton : envoyez-le en Authorization: Bearer trb_… à la même adresse.
  • Ce que l'assistant lit passe par le fournisseur que vous avez choisi, selon ses conditions.

Ce qu'on peut demander et ce que voit l'entreprise

Sécurité

Comment nous protégeons l'accès :

  • Lecture seule : aucun endpoint de l'API ne modifie de données.
  • Tributs ne conserve qu'une empreinte du jeton (SHA-256).
  • Expiration obligatoire, révocation et renouvellement depuis le profil.
  • Chaque entreprise voit qui la lit, et son propriétaire peut couper l'accès.
  • Limites par jeton et par entreprise, et HTTPS pour chaque requête.

Bonnes pratiques

  • Conservez le jeton dans un gestionnaire de secrets ou une variable d'environnement. Gardez-le hors du code, des dépôts et des applications qui s'exécutent dans le navigateur.
  • Créez un jeton par programme, avec l'expiration la plus courte qui vous convient.
  • Envoyez-le toujours dans l'en-tête Authorization : les URL restent dans les historiques et les journaux des serveurs.
  • Si vous pensez qu'il a fuité, révoquez-le depuis votre profil et créez-en un nouveau. Le préfixe trb_ aide les scanners de secrets à le repérer.

Pour signaler une vulnérabilité, écrivez à security@tributs.ad.

Versions

La version figure dans l'URL (/api/v1/). La v1 ne fait qu'ajouter des champs : un changement incompatible passe en v2.