Insourcia Financials API

Données financières

GitHub OpenAPI

Operations 1

GET /companies/{siren}/financials Historique financier #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/insourcia-io:insourcia-io-financials-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

insourcia-io-financials-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Insourcia Financials API
  description: 'API publique Insourcia pour la recherche et l''analyse de sociétés françaises. ## Authentification


    Chaque requête porte un en-tête `Authorization: Bearer `. Deux types de jetons sont acceptés :

    - **Clé API** (format `isk_xxx`) : à créer dans l''application, rubrique Paramètres > API / MCP (`https://app.insourcia.io/settings/api`) ;

    - **JWT OAuth 2.1** : obtenu par le parcours OAuth du serveur MCP. ## Facturation en crédits


    L''API se paie sur le solde de crédits de votre organisation. **1 crédit = 1 fiche société.** Chaque opération indique son coût en tête de description (« Coût : ») et dans l''extension `x-credits`, lisible par un programme : `base` (crédits par appel), `perResult` (par résultat de recherche servi), `sections` (crédits par société servie, pour chaque section non vide), `subscriptionOnly` (opération réservée aux abonnements), `freeRelookup` (relecture gratuite, pendant `freeRelookupDays` jours, soit 30). **Règles de facturation.**

    - Seul ce qui est servi est facturé : une section vide ne coûte rien, une société introuvable ne coûte rien. - Une erreur est gratuite : seule une réponse 2xx est débitée. Un 4xx ou un 5xx (paramètre invalide, refus, `server_busy`) ne débite rien. - Relire la même section d''une même société dans les 30 jours qui suivent son premier débit est gratuit, entre la fiche, ses sections et leurs lots (par exemple `GET /companies/{siren}/financials` puis `GET /companies/batch/financials`). Une recherche est facturée à chaque appel. - Avant l''appel, le coût maximal est réservé sur le solde ; après, seul le coût réel est débité et le reste est rendu. Un appel dont le coût maximal dépasse le solde est refusé (402) sans rien débiter. - Les sections réservées aux abonnements (score crédit, estimation financière, email de dirigeant, données Insourcia d''une recherche) sont omises d''une réponse sans abonnement et listées dans `_billing.sections_skipped`, sans coût. Une opération entièrement réservée répond 403 `subscription_required`. **Coût et solde dans chaque réponse facturable.**

    - `X-Credits-Charged` : crédits débités par cet appel (0 pour une relecture ou un rejeu). - `X-Credits-Remaining` : solde de l''organisation après l''appel. - `X-Credits-Grant-Remaining` et `X-Credits-Grant-Expires-At` : reste et date d''expiration des crédits offerts du mois. - `X-Billing-Grid-Version` : version de la grille qui a calculé le coût. - Le bloc `_billing` du corps (`charged`, `breakdown`, `free_relookups`, `sections_skipped`, `grid_version`) détaille le calcul. Il est ajouté sur demande, avec `?billing=1` ou l''en-tête `X-Billing-Detail: 1`. - `GET /me` donne le solde à tout moment (bloc `credits`), gratuitement. **Rejeu sans double débit.** Un en-tête `Idempotency-Key` (200 caractères au plus) lie l''appel à ses arguments pendant 24 h : le même appel renvoyé sous la même clé est servi à nouveau sans être débité. La même clé sur un autre appel répond 409 `idempotency_key_reused`, et sur un appel encore en cours 409 `idempotency_key_in_progress`. **Erreurs de facturation.**

    - 402 `insufficient_credits` : solde insuffisant pour le coût maximal de l''appel (`credits_remaining`, `credits_required`). - 402 `spend_cap_reached` : plafond de dépense quotidien ou mensuel de l''organisation atteint (`cap` : `daily` ou `monthly`). - 403 `subscription_required` : opération réservée aux abonnements. - 409 `idempotency_key_reused` / `idempotency_key_in_progress` : voir ci-dessus. - 503 `service_unavailable` : facturation momentanément indisponible, rien n''est débité. **Offre.** 100 crédits offerts chaque mois à toute organisation, dès l''inscription. Recharge à 0,01 € le crédit, sans expiration. Abonnements :


    | Abonnement | Crédits inclus |

    |---|---|

    | 49 € par mois | 10 000 crédits par mois |

    | 99 € par mois | 20 000 crédits par mois |

    | 199 € par mois | 40 000 crédits par mois |

    | 499 € par mois | 100 000 crédits par mois |

    | 999 € par mois | 200 000 crédits par mois |


    Grille `2026-11-12.v9` (en-tête `X-Billing-Grid-Version`).'
  version: 1.0.0
  x-billing-grid-version: 2026-11-12.v9
  contact:
    name: Insourcia Support
    email: support@insourcia.io
servers:
- url: https://api.insourcia.io/v1
  description: Production
security:
- bearerAuth: []
tags:
- name: Financials
  description: Données financières
paths:
  /companies/{siren}/financials:
    get:
      x-credits:
        credits: 1
        unit: par société
        note: 'Par société servie et par section non vide : comptes 1 (2 en `detail=full`), estimation financière 5 (abonnements). Relire une même société et section dans les 30 jours est gratuit.'
        subscribers: false
        sections:
          financials: 1
          financials_full: 2
          estimation: 5
        subscriptionSections:
        - estimation
        subscriptionOnly: false
        freeRelookup: true
        freeRelookupDays: 30
      tags:
      - Financials
      summary: Historique financier
      description: '**Coût :** Par société servie et par section non vide : comptes 1 (2 en `detail=full`), estimation financière 5 (abonnements). Relire une même société et section dans les 30 jours est gratuit.


        Retourne l''historique financier sur plusieurs exercices.


        Trois modes d''usage :

        - `compact` (~40 champs / exercice) : compte de résultat complet (CA jusqu''au résultat net), bilan abrégé PCG (actif immobilisé net, stocks, créances clients, disponibilités, total général actif, total actif ; capital social, reserves, report à nouveau, capitaux propres, provisions, dettes financieres/fournisseurs/fiscales-sociales, total dettes, total passif), ratios clés.

        - `fields=` : injecte des champs supplémentaires cibles dans chaque exercice (ex: `fields=roe,bfr_jours_ca,autonomie_financiere`). Recommande pour 1-5 ratios additionnels au-dessus de compact.

        - `detail=full` : ~140 champs financiers exhaustifs par exercice (audit). 2 crédits par société au lieu de 1.


        Pour les sociétés cotées, un bloc `ifrs` complémentaire expose les agrégats consolidés.


        Priorité de type de bilan : K (consolidé) > C (complet) > S (simplifié).'
      operationId: getFinancials
      parameters:
      - $ref: '#/components/parameters/siren'
      - name: years
        in: query
        description: 'Nombre d''exercices. Par défaut : 3, maximum : 10.'
        schema:
          type: integer
          default: 3
          minimum: 1
          maximum: 10
      - name: type_bilan
        in: query
        description: 'Type de bilan. K (consolidé), C (complet/social), S (simplifié). Sans filtre: meilleure priorité.'
        schema:
          type: string
          enum:
          - K
          - C
          - S
      - name: detail
        in: query
        description: 'Niveau de détail : `compact` (~40 champs) ou `full` (~140 champs). Par défaut : `compact`.'
        schema:
          type: string
          enum:
          - compact
          - full
      - name: fields
        in: query
        description: 'Liste CSV de champs financiers additionnels à injecter dans chaque exercice.

          Exemple : `fields=roe,bfr_jours_ca,taux_marge_brute`. 5 champs au plus.

          Champs disponibles : voir le schéma `FinancialExercice` (~140 noms).

          '
        schema:
          type: string
          example: roe,bfr_jours_ca,autonomie_financiere
      - name: inclure_estimation
        in: query
        description: 'Compte de résultat confidentiel seulement. `true` ajoute `estimation_financiere` (fourchette de CA, confiance, tranche de marge d''EBE, probabilité de déficit : une ESTIMATION, jamais un chiffre déposé). Par défaut (`false`), seul `estimation_disponible` signale qu''une estimation existe.

          Réservé aux abonnements : sans abonnement, la section est omise et signalée dans

          `_billing.sections_skipped`, sans coût.

          '
        schema:
          type: boolean
          default: false
      responses:
        '402':
          $ref: '#/components/responses/CreditsRequired'
        '200':
          description: Données financières
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Financials'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    siren:
      name: siren
      in: path
      required: true
      description: 'SIREN à 9 chiffres, avec une clé de contrôle (Luhn) valide. Un numéro qui

        échoue la clé reçoit 400 `invalid_siren` ; un SIREN valide sans société

        reçoit 404 `not_found`. Seule exception à la clé : La Poste (356000000).

        '
      schema:
        type: string
        pattern: ^\d{9}$
        example: '380129866'
  schemas:
    EstimationFinanciere:
      type:
      - object
      - 'null'
      description: 'ESTIMATION du chiffre d''affaires et de la rentabilité, à partir du bilan, pour les sociétés dont le compte de résultat est confidentiel. Null dès qu''un CA est publié pour l''exercice estimé ou un exercice postérieur. Ce n''est jamais un chiffre déposé : ne pas l''additionner à des CA publies.'
      properties:
        nature:
          type: string
          enum:
          - estimation
        exercice:
          type:
          - integer
          - 'null'
          description: Exercice estimé (année de clôture)
        chiffre_affaires:
          type: object
          description: Fourchette de CA en euros, arrondie au millier, qui contient le vrai CA 8 fois sur 10
          properties:
            min:
              type: number
            max:
              type: number
        confiance:
          type: string
          enum:
          - haute
          - moyenne
          - faible
          description: 'Selon la richesse du bilan : erreur typique ~13 % (haute), 17-22 % (moyenne), 26-34 % (faible)'
        rentabilite:
          type: object
          properties:
            tranche_marge_ebe:
              type:
              - string
              - 'null'
              enum:
              - deficit
              - 0-5
              - 5-15
              - '>15'
              - null
              description: Tranche de marge d'EBE (EBE / CA, en %). Null si le modèle ne la fournit pas.
            probabilite_deficit:
              type:
              - number
              - 'null'
              description: Probabilité calibrée que l'EBE soit négatif (0 à 1). Null si le modèle ne la fournit pas.
        ebe:
          type: object
          description: 'Fourchette d''EBE en euros, arrondie au millier. Absente quand le modèle ne la publie pas pour cet exercice. Même nature que le CA estimé : jamais un chiffre déposé.'
          properties:
            min:
              type: number
            max:
              type: number
        as_of:
          type:
          - string
          - 'null'
          format: date
        model:
          type: string
    FinancialExercice:
      type: object
      description: 'Champs disponibles selon le mode (compact, full, fields=). Tous optionnels :

        seuls les champs non-null sont présents dans la réponse.


        Catégorisation (extrait, ~140 champs au total en mode full) :

        - Meta : annee, date_cloture, date_depot, type_bilan, duree_exercice_mois, confidentialite

        - Dépôt : document (le PDF déposé au greffe pour cet exercice, quand il est archivé - cf. `GET /documents/{type}/{id}`). Couverture partielle : l''absence de la clé est le cas courant.

        - P&L : chiffre_affaires, subventions_exploitation, autres_produits_exploitation, marge_brute, valeur_ajoutee, ebitda, resultat_exploitation, resultat_financier, resultat_courant, resultat_exceptionnel, resultat_net, impot_benefices, achats_marchandises, salaires_traitements, charges_sociales, charges_financieres, dotations_amortissements, etc.

        - Bilan actif : total_actif, actif_immobilise_net, immo_incorporelles_brut, immo_incorporelles_net, titres_participation_brut, titres_participation_net, immo_financieres_brut, immo_financieres_net, stocks_total, creances_clients, terrains_brut, constructions_brut, etc.

        - Bilan passif : capitaux_propres, capital_social, reserves, reserve_legale, primes_emission_fusion_apport, subventions_investissement, provisions_reglementees, dettes_financieres, emprunts_bancaires, dettes_fournisseurs, total_dettes, total_passif, etc.

        - Trésorerie : tresorerie (disponibilités + VMP, canonical), cash (disponibilités strictes)

        - Ratios : marge_nette (%), marge_ebitda (%), taux_marge_brute (%), roe (%), autonomie_financiere (%), liquidite_generale, capacite_remboursement, ratio_endettement, etc.

        - BFR : bfr_exploitation, bfr_hors_exploitation, bfr_total, bfr_jours_ca, dette_nette, fonds_roulement_net_global

        - Croissance : cagr_ca_1an..5ans (%), cagr_ebitda_1an..5ans (%), cagr_ebitda_signed_1an..5ans (%), cagr_rn_1an..5ans (%), cagr_rn_signed_1an..5ans (%)

        - Dividendes & effectif : dividendes_verses, dividende_estime, effectif_moyen

        - Alias historiques (mode compact) : ca (= chiffre_affaires), bfr (= bfr_exploitation), croissance_ca (= cagr_ca_1an), croissance_ebitda, croissance_rn

        '
      additionalProperties: true
      properties:
        annee:
          type: integer
        date_cloture:
          type: string
        date_depot:
          type: string
        type_bilan:
          type: string
          enum:
          - K
          - C
          - S
          - B
          - A
          description: K = consolidé, C = complet (social), S = simplifié, B = banque, A = assurance.
        duree_exercice_mois:
          type: integer
        confidentialite:
          type: boolean
          description: true si la société a déposé une déclaration de confidentialité au greffe (loi Macron art. L232-25).
        document:
          $ref: '#/components/schemas/DocumentRef'
        ca:
          type: number
          description: Alias historique de chiffre_affaires (mode compact uniquement).
        bfr:
          type: number
          description: Alias historique de bfr_exploitation (mode compact uniquement).
        chiffre_affaires:
          type: number
        marge_brute:
          type: number
        valeur_ajoutee:
          type: number
        ebitda:
          type: number
        resultat_exploitation:
          type: number
        resultat_net:
          type: number
        total_actif:
          type: number
        capitaux_propres:
          type: number
        dettes_financieres:
          type: number
        dettes_fournisseurs:
          type: number
        tresorerie:
          type: number
          description: Disponibilités + valeurs mobilières de placement (canonical large).
        cash:
          type: number
          description: Disponibilités strictes (excl. VMP).
        dette_nette:
          type: number
        marge_nette:
          type: number
          description: En %.
        marge_ebitda:
          type: number
          description: En %.
        ratio_endettement:
          type: number
          description: 'Ratio d''endettement net, en valeur décimale (0,5 = 50 %) : (dettes financières - trésorerie) / capitaux propres.'
        roe:
          type: number
          description: Return on Equity, en %.
        bfr_exploitation:
          type: number
        bfr_total:
          type: number
        bfr_jours_ca:
          type: number
        capacite_autofinancement:
          type: number
        delai_paiement_clients_jours:
          type: integer
        delai_paiement_fournisseurs_jours:
          type: integer
        effectif_moyen:
          type: integer
        dividendes_verses:
          type: number
    FinancialsIFRS:
      type: object
      description: 'Agrégats IFRS (comptes consolidés) pour les sociétés cotées.

        Présent uniquement pour une société qui publie des comptes IFRS.

        '
      properties:
        annee:
          type: integer
        chiffre_affaires:
          type: number
        resultat_net:
          type: number
        ebitda:
          type: number
        resultat_operationnel:
          type: number
        total_actif:
          type: number
        capitaux_propres:
          type: number
        tresorerie:
          type: number
        bpa:
          type: number
          description: Bénéfice par action.
        dividendes:
          type: number
    FinancialsLayoutSection:
      type: object
      properties:
        title:
          type: string
          example: Compte de resultat
        lines:
          type: array
          items:
            $ref: '#/components/schemas/FinancialsLayoutLine'
    FinancialsLayoutLine:
      type: object
      required:
      - key
      - label
      - level
      - kind
      properties:
        key:
          type: string
          description: Nom du champ à lire dans `exercices[year]`
          example: marge_brute
        label:
          type: string
          description: Label humain FR à afficher
          example: Marge brute
        level:
          type: integer
          description: 'Profondeur d''indentation : 1 = ligne principale, 2 = détail (`dont ...`)'
          example: 1
        kind:
          type: string
          enum:
          - value
          - subtotal
          - detail
          - total
          - meta
          description: 'Type de ligne pour le rendu : value (brut), subtotal (gras), detail (`dont`), total (gras+soulignement), meta (date/annee)'
        formula:
          type: string
          description: 'Pour kind=subtotal/total : expression humaine de la formule (informative : la valeur servie est déjà calculée)'
          example: chiffre_affaires + production_stockee - achats_marchandises - variation_stock_marchandises
        formula_note:
          type: string
          description: Note de définition optionnelle accompagnant la formule (ex. neutralisation des reprises pour la CAF). Informative.
          example: 'CAF PCG : reprises sur provisions et transferts de charges neutralises (non generateurs de tresorerie).'
    FinancialsLayout:
      type: object
      description: 'Schéma de rendu déterministe pour les états financiers. Permet aux consumers

        (LLM, scripts) de reconstruire un compte de résultat / bilan / ratios sans

        deviner l''ordre PCG.

        '
      properties:
        schema_version:
          type: string
          example: '1.0'
        currency:
          type: string
          example: EUR
        doc_url:
          type: string
        sections:
          type: object
          description: Map de sections (meta, compte_resultat, bilan_actif, bilan_passif, ratios, croissance, dividendes, effectif). Chaque section contient un title et un array lines[] ordonné PCG.
          additionalProperties:
            $ref: '#/components/schemas/FinancialsLayoutSection'
        missing_pcg_lines:
          type: array
          description: Lignes PCG standard qu'Insourcia ne fournit pas. Permet de signaler ces absences à l'utilisateur.
          items:
            type: object
            properties:
              label:
                type: string
              reason:
                type: string
                enum:
                - not_available
                - partially_available
                example: not_available
        not_applicable_pcg:
          type: boolean
          description: true si tous les exercices sont sectoriels (banque B ou assurance A). Le layout PCG standard n'est alors pas applicable.
        note:
          type: string
    DocumentRef:
      type: object
      description: 'Référence vers un document archivé du registre INPI. Ne porte aucune

        information de stockage : le PDF se lit par `GET /documents/{type}/{id}`.

        '
      properties:
        id:
          type: string
          description: Identifiant INPI du document (24 caractères hexadécimaux).
          example: 6aa3da5b274fd2a06800904b
        type:
          type: string
          enum:
          - actes
          - bilans
        nom_document:
          type:
          - string
          - 'null'
        date_depot:
          type:
          - string
          - 'null'
          format: date
        taille_octets:
          type:
          - integer
          - 'null'
        url:
          type: string
          description: 'Lien direct vers le PDF sur l''application web, authentifié par la

            session du navigateur : il s''ouvre d''un clic pour un utilisateur

            connecte. Un client authentifié par clé API passe par

            `GET /documents/{type}/{id}`.

            '
          example: https://app.insourcia.io/api/documents/bilans/6aa3da5b274fd2a06800904b
    Financials:
      type: object
      properties:
        siren:
          type: string
        denomination:
          type: string
        dernier_exercice:
          type: integer
        financials_status:
          type: string
          enum:
          - available
          - not_required_societe_civile
          - missing
          description: 'Disponibilité des comptes :

            - `available` : des exercices sont retournés.

            - `not_required_societe_civile` : société civile (SCI, etc.), non tenue de déposer ses comptes au greffe - absence structurelle, pas une lacune.

            - `missing` : forme commerciale tenue de déposer, mais aucun compte trouvé (lacune réelle).

            Quand le compte de résultat est confidentiel, `estimation_disponible` le signale ; avec `inclure_estimation=true`, `estimation_financiere` porte une ESTIMATION de CA et de rentabilité (jamais un chiffre déposé).

            '
        exercices:
          type: array
          items:
            $ref: '#/components/schemas/FinancialExercice'
        ifrs:
          $ref: '#/components/schemas/FinancialsIFRS'
        estimation_disponible:
          type: object
          description: Présent quand une estimation existe et que `inclure_estimation` n'est pas passé. Ne contient aucun chiffre estimé.
          properties:
            exercice:
              type:
              - integer
              - 'null'
            message:
              type: string
        estimation_financiere:
          $ref: '#/components/schemas/EstimationFinanciere'
        estimation_financiere_exercices:
          type: array
          description: Les autres exercices estimés (antérieurs, ou intercalés entre deux CA publiés), triés par année, avec `inclure_estimation=true`. Même forme que `estimation_financiere`. Un exercice est écarté seulement si un CA est publié pour CET exercice. Absent s'il n'y en a pas.
          items:
            $ref: '#/components/schemas/EstimationFinanciere'
        _layout:
          $ref: '#/components/schemas/FinancialsLayout'
        fields_skipped:
          type: array
          description: Champs ignorés parce que au-delà du plafond de champs.
          items:
            type: string
        upgrade_hint:
          type: string
          description: 'Présent quand des champs `fields` ont été ignorés au-delà du plafond : les liste, en français.'
    Error:
      type: object
      properties:
        error:
          type: string
          description: Code d'erreur stable. C'est lui qu'un client doit lire pour réagir, jamais le texte de `message`.
        message:
          type: string
          description: Explication pour un développeur ou un agent, en anglais.
        message_fr:
          type: string
          description: Version française de `message`, pour l'afficher telle quelle à un utilisateur francophone. Absente quand `message` n'a pas de version française.
        parameter:
          type: string
          description: 'Sur un `invalid_parameter` qui refuse des valeurs inconnues : le paramètre en cause (ex. `fields`).'
        unknown:
          type: array
          items:
            type: string
          description: Les valeurs refusées par ce paramètre, telles qu'envoyées. Présent avec `parameter`.
  responses:
    RateLimited:
      description: Limite de débit atteinte (fenêtre glissante d'une minute). Rien n'est débité.
      headers:
        Retry-After:
          schema:
            type: integer
          description: Secondes avant de pouvoir réessayer
      content:
        application/json:
          schema:
            allOf:
            - $ref: '#/components/schemas/Error'
            - type: object
              properties:
                window:
                  type: string
                  enum:
                  - minute
                retry_after_seconds:
                  type: integer
                limit_source:
                  type: string
                  enum:
                  - user
                  - organization
                  description: '`organization` quand la limite est celle de l''organisation (clé d''organisation), `user` sinon.'
          example:
            error: rate_limited
            window: minute
            retry_after_seconds: 12
            limit_source: organization
            message: Trop de requetes (plafond 25/minute). Reessayez dans 12 s.
    BadRequest:
      description: Paramètres invalides
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: invalid_parameter
            message: The 'q' parameter is required.
            message_fr: Le paramètre 'q' est requis.
    Unauthorized:
      description: Clé API invalide ou manquante
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: unauthorized
            message: Invalid or missing API key.
            message_fr: Clé API invalide ou manquante.
    NotFound:
      description: Société introuvable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: not_found
            message: No company found for SIREN 000000000.
            message_fr: Aucune entreprise trouvée pour le SIREN 000000000.
    CreditsRequired:
      description: 'Facturation en crédits uniquement. Solde de crédits insuffisant pour le coût maximal de l''appel

        (`insufficient_credits`), ou plafond de dépense de l''organisation atteint (`spend_cap_reached`).

        Rien n''est débité.

        '
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
                enum:
                - insufficient_credits
                - spend_cap_reached
              message:
                type: string
              credits_remaining:
                type: number
                description: Solde de l'organisation (`insufficient_credits`).
              credits_required:
                type: number
                description: Coût maximal réservé pour cet appel (`insufficient_credits`).
              cap:
                type: string
                enum:
                - daily
                - monthly
                description: Plafond atteint (`spend_cap_reached`).
          example:
            error: insufficient_credits
            message: Solde de crédits insuffisant pour cet appel.
            credits_remaining: 0.4
            credits_required: 1
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Clé API (isk_xxx) ou JWT OAuth 2.1