{
  "openapi": "3.1.0",
  "info": {
    "title": "Tauraco Public API",
    "summary": "API publique de Tauraco (ERP, facturation, comptabilité, financement).",
    "description": "API publique de Tauraco pour les partenaires et intégrateurs : lecture des données de l'entreprise (clients, factures, comptabilité, trésorerie, stocks, financement), écritures idempotentes, exports et webhooks. Authentification OAuth 2.0 (client credentials ou authorization code + PKCE), jeton d'accès porté en `Authorization: Bearer`. Montants en unités majeures, en chaînes décimales ; horodatages ISO 8601 UTC (`Z`). Pagination par curseur opaque (`cursor`, `limit` ≤ 200, réponse `{data, next_cursor, has_more}`). Erreurs RFC 9457 `application/problem+json`.",
    "contact": {
      "name": "Tauraco — intégrations",
      "url": "https://docs.tauraco.ai/developers"
    },
    "version": "1.0.0-beta",
    "x-api-version-date": "2026-11-01"
  },
  "servers": [
    {
      "url": "https://api.tauraco.io/public/v1",
      "description": "Production"
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "tags": [
          "company"
        ],
        "summary": "Application et autorisation courantes",
        "description": "Décrit l'application appelante, l'entreprise qui lui a accordé l'accès et les scopes effectifs du jeton.\n\nScopes requis : `company:read`.",
        "operationId": "getMe",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeOut"
                },
                "example": {
                  "client_id": "tc_live_abcdefghijklmnopqrstuvwx",
                  "client_name": "Connecteur Exemple",
                  "client_kind": "partner",
                  "company_id": "8d3b6c1e-2f4a-4b7c-9e1d-5a6b7c8d9e0f",
                  "grant_id": "0b9f8e7d-6c5b-4a39-8271-605f4e3d2c1b",
                  "grant_flow": "client_credentials",
                  "delegated": false,
                  "scopes": [
                    "company:read",
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "company:read"
            ]
          },
          {
            "bearer": [
              "company:read"
            ]
          }
        ],
        "x-required-scopes": [
          "company:read"
        ]
      }
    },
    "/companies/me": {
      "get": {
        "tags": [
          "company"
        ],
        "summary": "Profil de l'entreprise",
        "description": "Identité légale et coordonnées professionnelles de l'entreprise qui a accordé l'accès.\n\nScopes requis : `company:read`.",
        "operationId": "getCompany",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyOut"
                },
                "example": {
                  "id": "8d3b6c1e-2f4a-4b7c-9e1d-5a6b7c8d9e0f",
                  "name": "Société Exemple SARL",
                  "legal_form": "SARL",
                  "registration_number": "RB/BKO/2026/B/0001",
                  "tax_number": "084000000X",
                  "full_address": "Rue 100, Bamako, Mali",
                  "country": "ML",
                  "phone": "+223 20 00 00 00",
                  "email": "contact@exemple.test",
                  "website": "https://exemple.test",
                  "base_currency": "XOF",
                  "accounting_regime": "OHADA"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "company:read"
            ]
          },
          {
            "bearer": [
              "company:read"
            ]
          }
        ],
        "x-required-scopes": [
          "company:read"
        ]
      }
    },
    "/customers": {
      "get": {
        "tags": [
          "customers"
        ],
        "summary": "Lister les clients",
        "description": "Clients de l'entreprise, par date de création croissante.\n\nScopes requis : `customers:read`.",
        "operationId": "listCustomers",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Recherche (nom ou raison sociale) (Search (name or legal name))."
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifié à partir du (inclus) (Updated from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifié avant le (exclu) (Updated before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerList"
                },
                "example": {
                  "data": [
                    {
                      "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                      "name": "Client Exemple",
                      "legal_name": "Client Exemple SA",
                      "city": "Dakar",
                      "country": "SN",
                      "tax_id": "SN-0000000",
                      "siren": null,
                      "siret": null,
                      "tva_intra": null,
                      "currency": "XOF",
                      "einvoicing_routing_code": null,
                      "created_at": "2026-01-05T08:00:01.007919Z",
                      "updated_at": "2026-01-05T08:00:01.007919Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "customers:read"
            ]
          },
          {
            "bearer": [
              "customers:read"
            ]
          }
        ],
        "x-required-scopes": [
          "customers:read"
        ]
      },
      "post": {
        "tags": [
          "customers"
        ],
        "summary": "Créer un client",
        "description": "Crée un client de l'entreprise (service de facturation). Idempotent par Idempotency-Key ; les coordonnées personnelles sont écrites mais jamais relues par l'API.\n\nScopes requis : `customers:write`.",
        "operationId": "createCustomer",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerOut"
                },
                "example": {
                  "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                  "name": "Client Exemple",
                  "legal_name": "Client Exemple SA",
                  "city": "Dakar",
                  "country": "SN",
                  "tax_id": "SN-0000000",
                  "siren": null,
                  "siret": null,
                  "tva_intra": null,
                  "currency": "XOF",
                  "einvoicing_routing_code": null,
                  "created_at": "2026-01-05T08:00:01.007919Z",
                  "updated_at": "2026-01-05T08:00:01.007919Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "description": "Corps de ``POST /customers`` : un nouveau client de l'entreprise.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerCreate"
              },
              "example": {
                "name": "Client Exemple",
                "legal_name": "Client Exemple SA",
                "city": "Dakar",
                "country": "SN",
                "tax_id": "SN-0000000",
                "currency": "XOF",
                "email": "comptabilite@client-exemple.test"
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "customers:write"
            ]
          },
          {
            "bearer": [
              "customers:write"
            ]
          }
        ],
        "x-required-scopes": [
          "customers:write"
        ]
      }
    },
    "/customers/{customer_id}": {
      "get": {
        "tags": [
          "customers"
        ],
        "summary": "Lire un client",
        "description": "Un client de l'entreprise ; 404 s'il est absent ou invisible.\n\nScopes requis : `customers:read`.",
        "operationId": "getCustomer",
        "parameters": [
          {
            "name": "customer_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerOut"
                },
                "example": {
                  "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                  "name": "Client Exemple",
                  "legal_name": "Client Exemple SA",
                  "city": "Dakar",
                  "country": "SN",
                  "tax_id": "SN-0000000",
                  "siren": null,
                  "siret": null,
                  "tva_intra": null,
                  "currency": "XOF",
                  "einvoicing_routing_code": null,
                  "created_at": "2026-01-05T08:00:01.007919Z",
                  "updated_at": "2026-01-05T08:00:01.007919Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "customers:read"
            ]
          },
          {
            "bearer": [
              "customers:read"
            ]
          }
        ],
        "x-required-scopes": [
          "customers:read"
        ]
      }
    },
    "/suppliers": {
      "get": {
        "tags": [
          "suppliers"
        ],
        "summary": "Lister les fournisseurs",
        "description": "Fournisseurs de l'entreprise, par date de création.\n\nScopes requis : `suppliers:read`.",
        "operationId": "listSuppliers",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "PENDING_VALIDATION",
                "VALIDATED",
                "SUSPENDED",
                "PAYMENT_UPDATE_PENDING"
              ]
            },
            "description": "Statut (Status).",
            "example": "DRAFT"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Recherche (nom) (Search (name))."
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifié à partir du (inclus) (Updated from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifié avant le (exclu) (Updated before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SupplierList"
                },
                "example": {
                  "data": [
                    {
                      "id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                      "name": "Fournisseur Exemple",
                      "city": "Abidjan",
                      "country": "CI",
                      "tax_id": "CI-0000000",
                      "currency": "XOF",
                      "payment_terms_days": 30,
                      "status": "VALIDATED",
                      "validated_at": "2026-01-06T09:30:00Z",
                      "created_at": "2026-01-05T08:00:02.015838Z",
                      "updated_at": "2026-01-06T09:30:00Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "suppliers:read"
            ]
          },
          {
            "bearer": [
              "suppliers:read"
            ]
          }
        ],
        "x-required-scopes": [
          "suppliers:read"
        ]
      }
    },
    "/suppliers/{supplier_id}": {
      "get": {
        "tags": [
          "suppliers"
        ],
        "summary": "Lire un fournisseur",
        "description": "Un fournisseur ; 404 s'il est absent ou invisible.\n\nScopes requis : `suppliers:read`.",
        "operationId": "getSupplier",
        "parameters": [
          {
            "name": "supplier_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SupplierOut"
                },
                "example": {
                  "id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                  "name": "Fournisseur Exemple",
                  "city": "Abidjan",
                  "country": "CI",
                  "tax_id": "CI-0000000",
                  "currency": "XOF",
                  "payment_terms_days": 30,
                  "status": "VALIDATED",
                  "validated_at": "2026-01-06T09:30:00Z",
                  "created_at": "2026-01-05T08:00:02.015838Z",
                  "updated_at": "2026-01-06T09:30:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "suppliers:read"
            ]
          },
          {
            "bearer": [
              "suppliers:read"
            ]
          }
        ],
        "x-required-scopes": [
          "suppliers:read"
        ]
      }
    },
    "/invoices": {
      "get": {
        "tags": [
          "invoices"
        ],
        "summary": "Lister les factures clients",
        "description": "En-têtes de factures clients, par date de création croissante.\n\nScopes requis : `invoices:read`.",
        "operationId": "listInvoices",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "SENT",
                "PARTIALLY_PAID",
                "PAID",
                "OVERDUE",
                "CANCELLED",
                "FINANCING_REQUESTED"
              ]
            },
            "description": "Statut (Status).",
            "example": "DRAFT"
          },
          {
            "name": "customer_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Client (Customer).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "issue_date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Émise à partir du (inclus) (Issued from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "issue_date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Émise jusqu'au (inclus) (Issued until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "due_date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Échéance à partir du (inclus) (Due from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "due_date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Échéance jusqu'au (inclus) (Due until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créée à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créée avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifiée à partir du (inclus) (Updated from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifiée avant le (exclu) (Updated before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceList"
                },
                "example": {
                  "data": [
                    {
                      "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "number": "FA-2026-0001",
                      "customer_id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                      "customer_name": "Client Exemple",
                      "issue_date": "2026-01-05",
                      "due_date": "2026-02-04",
                      "currency": "XOF",
                      "subtotal": "100000",
                      "tax_total": "18000",
                      "total": "118000",
                      "amount_paid": "0",
                      "status": "SENT",
                      "facturx_profile": null,
                      "tva_details": null,
                      "created_at": "2026-01-05T08:00:03.023757Z",
                      "updated_at": "2026-01-05T08:00:03.023757Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          },
          {
            "bearer": [
              "invoices:read"
            ]
          }
        ],
        "x-required-scopes": [
          "invoices:read"
        ]
      },
      "post": {
        "tags": [
          "invoices"
        ],
        "summary": "Créer une facture client",
        "description": "Crée une facture client en brouillon par le service de facturation (numérotation, totaux, TVA, quota du plan, trace d'audit ERP_INVOICE_CREATED). Idempotent par Idempotency-Key. Prix en unités majeures de la devise, en chaînes décimales.\n\nScopes requis : `invoices:write`.",
        "operationId": "createInvoice",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDetailOut"
                },
                "example": {
                  "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                  "number": "FA-2026-0001",
                  "customer_id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                  "customer_name": "Client Exemple",
                  "issue_date": "2026-01-05",
                  "due_date": "2026-02-04",
                  "currency": "XOF",
                  "subtotal": "100000",
                  "tax_total": "18000",
                  "total": "118000",
                  "amount_paid": "0",
                  "status": "SENT",
                  "facturx_profile": null,
                  "tva_details": null,
                  "created_at": "2026-01-05T08:00:03.023757Z",
                  "updated_at": "2026-01-05T08:00:03.023757Z",
                  "lines": [
                    {
                      "id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
                      "sort_order": 0,
                      "product_id": null,
                      "description": "Prestation de conseil",
                      "quantity": 2,
                      "unit_price": "50000",
                      "tax_rate_bps": 1800,
                      "tva_rate_type": null,
                      "line_total": "100000",
                      "tax_amount": "18000",
                      "currency": "XOF"
                    }
                  ],
                  "lines_truncated": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "description": "Corps de ``POST /invoices`` : une facture client, créée en brouillon par le service de facturation.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceCreate"
              },
              "example": {
                "customer_id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                "issue_date": "2026-01-05",
                "due_date": "2026-02-04",
                "currency": "XOF",
                "lines": [
                  {
                    "description": "Prestation de conseil",
                    "quantity": 2,
                    "unit_price": "50000",
                    "tax_rate_bps": 1800
                  }
                ]
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "invoices:write"
            ]
          },
          {
            "bearer": [
              "invoices:write"
            ]
          }
        ],
        "x-required-scopes": [
          "invoices:write"
        ]
      }
    },
    "/invoices/{invoice_id}": {
      "get": {
        "tags": [
          "invoices"
        ],
        "summary": "Lire une facture client",
        "description": "Une facture et ses lignes ; 404 si absente ou invisible.\n\nScopes requis : `invoices:read`.",
        "operationId": "getInvoice",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDetailOut"
                },
                "example": {
                  "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                  "number": "FA-2026-0001",
                  "customer_id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                  "customer_name": "Client Exemple",
                  "issue_date": "2026-01-05",
                  "due_date": "2026-02-04",
                  "currency": "XOF",
                  "subtotal": "100000",
                  "tax_total": "18000",
                  "total": "118000",
                  "amount_paid": "0",
                  "status": "SENT",
                  "facturx_profile": null,
                  "tva_details": null,
                  "created_at": "2026-01-05T08:00:03.023757Z",
                  "updated_at": "2026-01-05T08:00:03.023757Z",
                  "lines": [
                    {
                      "id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
                      "sort_order": 0,
                      "product_id": null,
                      "description": "Prestation de conseil",
                      "quantity": 2,
                      "unit_price": "50000",
                      "tax_rate_bps": 1800,
                      "tva_rate_type": null,
                      "line_total": "100000",
                      "tax_amount": "18000",
                      "currency": "XOF"
                    }
                  ],
                  "lines_truncated": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          },
          {
            "bearer": [
              "invoices:read"
            ]
          }
        ],
        "x-required-scopes": [
          "invoices:read"
        ]
      }
    },
    "/bills": {
      "get": {
        "tags": [
          "bills"
        ],
        "summary": "Lister les factures fournisseurs",
        "description": "Factures fournisseurs, par date de création.\n\nScopes requis : `bills:read`.",
        "operationId": "listBills",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "RECEIVED",
                "APPROVED",
                "PARTIALLY_PAID",
                "PAID",
                "OVERDUE",
                "CANCELLED"
              ]
            },
            "description": "Statut (Status).",
            "example": "DRAFT"
          },
          {
            "name": "supplier_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Fournisseur (Supplier).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "issue_date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Émise à partir du (inclus) (Issued from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "issue_date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Émise jusqu'au (inclus) (Issued until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "due_date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Échéance à partir du (inclus) (Due from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "due_date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Échéance jusqu'au (inclus) (Due until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créée à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créée avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifiée à partir du (inclus) (Updated from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifiée avant le (exclu) (Updated before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillList"
                },
                "example": {
                  "data": [
                    {
                      "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                      "bill_number": "FF-2026-0042",
                      "supplier_id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                      "issue_date": "2026-01-08",
                      "due_date": "2026-02-07",
                      "currency": "XOF",
                      "subtotal": "250000",
                      "tax_total": "45000",
                      "total": "295000",
                      "amount_paid": "0",
                      "status": "APPROVED",
                      "approved_at": "2026-01-09T10:00:00Z",
                      "created_at": "2026-01-08T11:12:13.000001Z",
                      "updated_at": "2026-01-09T10:00:00Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bills:read"
            ]
          },
          {
            "bearer": [
              "bills:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bills:read"
        ]
      }
    },
    "/bills/{bill_id}": {
      "get": {
        "tags": [
          "bills"
        ],
        "summary": "Lire une facture fournisseur",
        "description": "Une facture fournisseur ; 404 sinon.\n\nScopes requis : `bills:read`.",
        "operationId": "getBill",
        "parameters": [
          {
            "name": "bill_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillOut"
                },
                "example": {
                  "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                  "bill_number": "FF-2026-0042",
                  "supplier_id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                  "issue_date": "2026-01-08",
                  "due_date": "2026-02-07",
                  "currency": "XOF",
                  "subtotal": "250000",
                  "tax_total": "45000",
                  "total": "295000",
                  "amount_paid": "0",
                  "status": "APPROVED",
                  "approved_at": "2026-01-09T10:00:00Z",
                  "created_at": "2026-01-08T11:12:13.000001Z",
                  "updated_at": "2026-01-09T10:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bills:read"
            ]
          },
          {
            "bearer": [
              "bills:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bills:read"
        ]
      }
    },
    "/payments": {
      "get": {
        "tags": [
          "payments"
        ],
        "summary": "Lister les encaissements",
        "description": "Encaissements clients, par date de paiement.\n\nScopes requis : `payments:read`.",
        "operationId": "listPayments",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Facture (Invoice).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "method",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "CASH",
                "BANK_TRANSFER",
                "MOBILE_MONEY",
                "CHECK",
                "CARD"
              ]
            },
            "description": "Moyen de paiement (Payment method).",
            "example": "CASH"
          },
          {
            "name": "paid_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Payé à partir du (inclus) (Paid from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "paid_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Payé avant le (exclu) (Paid before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentList"
                },
                "example": {
                  "data": [
                    {
                      "id": "4d5e6f7a-8b9c-4d0e-a1f2-b3c4d5e6f7a8",
                      "invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "amount": "118000",
                      "currency": "XOF",
                      "method": "BANK_TRANSFER",
                      "paid_at": "2026-01-20T14:00:00Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "payments:read"
            ]
          },
          {
            "bearer": [
              "payments:read"
            ]
          }
        ],
        "x-required-scopes": [
          "payments:read"
        ]
      },
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Enregistrer un encaissement",
        "description": "Enregistre un encaissement sur une facture client (service de facturation : statut de la facture, écriture de banque, trace d'audit ERP_PAYMENT_RECORDED). Idempotent par Idempotency-Key. Facture gelée par un financement, annulée ou réglée : 409 conflict.\n\nScopes requis : `payments:write`.",
        "operationId": "createPayment",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentOut"
                },
                "example": {
                  "id": "4d5e6f7a-8b9c-4d0e-a1f2-b3c4d5e6f7a8",
                  "invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                  "amount": "118000",
                  "currency": "XOF",
                  "method": "BANK_TRANSFER",
                  "paid_at": "2026-01-20T14:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "description": "Corps de ``POST /payments`` : un encaissement sur une facture client.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentCreate"
              },
              "example": {
                "invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                "amount": "118000",
                "method": "BANK_TRANSFER",
                "paid_on": "2026-01-20",
                "reference": "VIR-2026-0042"
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "payments:write"
            ]
          },
          {
            "bearer": [
              "payments:write"
            ]
          }
        ],
        "x-required-scopes": [
          "payments:write"
        ]
      }
    },
    "/payments/{payment_id}": {
      "get": {
        "tags": [
          "payments"
        ],
        "summary": "Lire un encaissement",
        "description": "Un encaissement ; 404 s'il est absent ou invisible.\n\nScopes requis : `payments:read`.",
        "operationId": "getPayment",
        "parameters": [
          {
            "name": "payment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentOut"
                },
                "example": {
                  "id": "4d5e6f7a-8b9c-4d0e-a1f2-b3c4d5e6f7a8",
                  "invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                  "amount": "118000",
                  "currency": "XOF",
                  "method": "BANK_TRANSFER",
                  "paid_at": "2026-01-20T14:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "payments:read"
            ]
          },
          {
            "bearer": [
              "payments:read"
            ]
          }
        ],
        "x-required-scopes": [
          "payments:read"
        ]
      }
    },
    "/purchase-orders": {
      "get": {
        "tags": [
          "purchases"
        ],
        "summary": "Lister les bons de commande",
        "description": "Bons de commande fournisseurs, par date de création.\n\nScopes requis : `purchases:read`.",
        "operationId": "listPurchaseOrders",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "SENT",
                "CONFIRMED",
                "RECEIVED",
                "CANCELLED"
              ]
            },
            "description": "Statut (Status).",
            "example": "DRAFT"
          },
          {
            "name": "supplier_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Fournisseur (Supplier).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "issue_date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Émis à partir du (inclus) (Issued from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "issue_date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Émis jusqu'au (inclus) (Issued until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderList"
                },
                "example": {
                  "data": [
                    {
                      "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                      "po_number": "BC-2026-0007",
                      "supplier_id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                      "issue_date": "2026-01-03",
                      "currency": "XOF",
                      "total": "295000",
                      "status": "CONFIRMED",
                      "linked_bill_id": null,
                      "created_at": "2026-01-03T09:00:00.000002Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "purchases:read"
            ]
          },
          {
            "bearer": [
              "purchases:read"
            ]
          }
        ],
        "x-required-scopes": [
          "purchases:read"
        ]
      }
    },
    "/purchase-orders/{purchase_order_id}": {
      "get": {
        "tags": [
          "purchases"
        ],
        "summary": "Lire un bon de commande",
        "description": "Un bon de commande ; 404 s'il est absent ou invisible.\n\nScopes requis : `purchases:read`.",
        "operationId": "getPurchaseOrder",
        "parameters": [
          {
            "name": "purchase_order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderOut"
                },
                "example": {
                  "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                  "po_number": "BC-2026-0007",
                  "supplier_id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                  "issue_date": "2026-01-03",
                  "currency": "XOF",
                  "total": "295000",
                  "status": "CONFIRMED",
                  "linked_bill_id": null,
                  "created_at": "2026-01-03T09:00:00.000002Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "purchases:read"
            ]
          },
          {
            "bearer": [
              "purchases:read"
            ]
          }
        ],
        "x-required-scopes": [
          "purchases:read"
        ]
      }
    },
    "/products": {
      "get": {
        "tags": [
          "products"
        ],
        "summary": "Lister les produits",
        "description": "Produits et prestations facturables, par date de création.\n\nScopes requis : `products:read`.",
        "operationId": "listProducts",
        "parameters": [
          {
            "name": "active",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Actif (Active).",
            "example": true
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Recherche (nom) (Search (name))."
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductList"
                },
                "example": {
                  "data": [
                    {
                      "id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
                      "name": "Prestation de conseil",
                      "description": "Journée de conseil",
                      "unit_price": "50000",
                      "currency": "XOF",
                      "tax_rate_bps": 1800,
                      "unit": "jour",
                      "active": true,
                      "created_at": "2026-01-02T08:00:00.000003Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "products:read"
            ]
          },
          {
            "bearer": [
              "products:read"
            ]
          }
        ],
        "x-required-scopes": [
          "products:read"
        ]
      }
    },
    "/treasury/movements": {
      "get": {
        "tags": [
          "treasury"
        ],
        "summary": "Lister les mouvements de trésorerie",
        "description": "Mouvements des comptes bancaires et de caisse, par date de création.\n\nScopes requis : `treasury:read`.",
        "operationId": "listCashMovements",
        "parameters": [
          {
            "name": "bank_account_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Compte de trésorerie (Cash account).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "movement_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "INFLOW",
                "OUTFLOW",
                "TRANSFER"
              ]
            },
            "description": "Sens (Direction).",
            "example": "INFLOW"
          },
          {
            "name": "movement_date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Daté à partir du (inclus) (Dated from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "movement_date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Daté jusqu'au (inclus) (Dated until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créé avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CashMovementList"
                },
                "example": {
                  "data": [
                    {
                      "id": "8b9c0d1e-2f3a-4b4c-9d5e-6f7a8b9c0d1e",
                      "bank_account_id": "0d1e2f3a-4b5c-4d6e-8f7a-8b9c0d1e2f3a",
                      "movement_type": "INFLOW",
                      "amount": "118000",
                      "currency": "XOF",
                      "description": "Encaissement facture FA-2026-0001",
                      "reference": "REL-2026-01",
                      "movement_date": "2026-01-20",
                      "source_type": "billing_payment",
                      "source_id": "4d5e6f7a-8b9c-4d0e-a1f2-b3c4d5e6f7a8",
                      "created_at": "2026-01-20T14:00:01.000004Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "treasury:read"
            ]
          },
          {
            "bearer": [
              "treasury:read"
            ]
          }
        ],
        "x-required-scopes": [
          "treasury:read"
        ]
      }
    },
    "/accounting/accounts": {
      "get": {
        "tags": [
          "accounting"
        ],
        "summary": "Lister les comptes",
        "description": "Plan de comptes, par code.\n\nScopes requis : `accounting:read`.",
        "operationId": "listAccounts",
        "parameters": [
          {
            "name": "account_class",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3",
                "4",
                "5",
                "6",
                "7",
                "8",
                "9"
              ]
            },
            "description": "Classe (Class).",
            "example": "1"
          },
          {
            "name": "active",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Actif (Active).",
            "example": true
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Recherche (numéro ou intitulé) (Search (number or name))."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountList"
                },
                "example": {
                  "data": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "code": "411100",
                      "name": "Clients",
                      "name_en": "Customers",
                      "account_class": "4",
                      "parent_code": "411",
                      "is_detail": true,
                      "active": true,
                      "balance": "118000",
                      "currency": "XOF"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "accounting:read"
            ]
          },
          {
            "bearer": [
              "accounting:read"
            ]
          }
        ],
        "x-required-scopes": [
          "accounting:read"
        ]
      }
    },
    "/accounting/entries": {
      "get": {
        "tags": [
          "accounting"
        ],
        "summary": "Lister les écritures comptables",
        "description": "Écritures avec leurs lignes, par date de création ; filtres de journal, de période et d'origine.\n\nScopes requis : `accounting:read`.",
        "operationId": "listJournalEntries",
        "parameters": [
          {
            "name": "journal_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Journal (Journal).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "period_start",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Période : du (inclus) (Period: from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "period_end",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Période : au (inclus) (Period: until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "source_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 32
            },
            "description": "Origine (Source type)."
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créée à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créée avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalEntryList"
                },
                "example": {
                  "data": [
                    {
                      "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
                      "journal_id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
                      "entry_date": "2026-01-05",
                      "piece_number": "VT-2026-0001",
                      "reference": "FA-2026-0001",
                      "description": "Facture FA-2026-0001",
                      "currency": "XOF",
                      "is_balanced": true,
                      "fiscal_period_id": null,
                      "source_type": "billing_invoice",
                      "source_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "created_at": "2026-01-05T08:00:04.031676Z",
                      "lines": [
                        {
                          "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
                          "account_code": "411100",
                          "label": "Facture FA-2026-0001",
                          "debit": "118000",
                          "credit": "0",
                          "currency": "XOF"
                        },
                        {
                          "id": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f7a",
                          "account_code": "701100",
                          "label": "Facture FA-2026-0001",
                          "debit": "0",
                          "credit": "100000",
                          "currency": "XOF"
                        }
                      ]
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "accounting:read"
            ]
          },
          {
            "bearer": [
              "accounting:read"
            ]
          }
        ],
        "x-required-scopes": [
          "accounting:read"
        ]
      }
    },
    "/accounting/trial-balance": {
      "get": {
        "tags": [
          "accounting"
        ],
        "summary": "Balance générale",
        "description": "Totaux et soldes par compte sur la période (period_start et period_end requis), par code de compte.\n\nScopes requis : `accounting:read`.",
        "operationId": "getTrialBalance",
        "parameters": [
          {
            "name": "period_start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Période : du (inclus) (Period: from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "period_end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Période : au (inclus) (Period: until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrialBalance"
                },
                "example": {
                  "data": [
                    {
                      "account_code": "411100",
                      "account_name": "Clients",
                      "debit_total": "118000",
                      "credit_total": "0",
                      "debit_balance": "118000",
                      "credit_balance": "0",
                      "currency": "XOF",
                      "period_start": "2026-01-01",
                      "period_end": "2026-01-31"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "accounting:read"
            ]
          },
          {
            "bearer": [
              "accounting:read"
            ]
          }
        ],
        "x-required-scopes": [
          "accounting:read"
        ]
      }
    },
    "/inventory/items": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "Lister les articles stockés",
        "description": "Articles du stock, par date de création.\n\nScopes requis : `inventory:read`.",
        "operationId": "listInventoryItems",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Recherche (référence ou désignation) (Search (SKU or name))."
          },
          {
            "name": "active",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Actif (Active).",
            "example": true
          },
          {
            "name": "category_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Famille (Category).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InventoryItemList"
                },
                "example": {
                  "data": [
                    {
                      "id": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7a8b",
                      "sku": "ART-0001",
                      "name": "Sac de riz 50 kg",
                      "description": null,
                      "category_id": null,
                      "product_id": null,
                      "unit_of_measure": "unité",
                      "barcode": null,
                      "perishable": true,
                      "shelf_life_days": 365,
                      "valuation_method": "FIFO",
                      "attributes": null,
                      "active": true,
                      "created_at": "2026-01-02T08:00:00.000005Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "inventory:read"
            ]
          },
          {
            "bearer": [
              "inventory:read"
            ]
          }
        ],
        "x-required-scopes": [
          "inventory:read"
        ]
      }
    },
    "/inventory/balances": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "Lister les soldes de stock",
        "description": "Soldes par lot et entrepôt (date as_of facultative).\n\nScopes requis : `inventory:read`.",
        "operationId": "listInventoryBalances",
        "parameters": [
          {
            "name": "warehouse_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Entrepôt (Warehouse).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "item_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Article (Item).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "À la date du (incluse) (As of (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InventoryBalanceList"
                },
                "example": {
                  "data": [
                    {
                      "lot_id": "a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d",
                      "item_id": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7a8b",
                      "warehouse_id": "b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d1e",
                      "quantity": "100",
                      "reserved": "0",
                      "blocked": "0",
                      "available": "100"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "inventory:read"
            ]
          },
          {
            "bearer": [
              "inventory:read"
            ]
          }
        ],
        "x-required-scopes": [
          "inventory:read"
        ]
      }
    },
    "/inventory/movements": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "Lister les mouvements de stock",
        "description": "Mouvements de stock, par date de création.\n\nScopes requis : `inventory:read`.",
        "operationId": "listInventoryMovements",
        "parameters": [
          {
            "name": "item_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Article (Item).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "lot_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Lot (Lot).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "warehouse_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Entrepôt (Warehouse).",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "movement_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 32
            },
            "description": "Type de mouvement (Movement type)."
          },
          {
            "name": "value_date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Valeur à partir du (inclus) (Value date from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "value_date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Valeur jusqu'au (inclus) (Value date until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Enregistré à partir du (inclus) (Recorded from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Enregistré avant le (exclu) (Recorded before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InventoryMovementList"
                },
                "example": {
                  "data": [
                    {
                      "id": "f6a7b8c9-d0e1-4f2a-9b3c-4d5e6f7a8b9c",
                      "lot_id": "a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d",
                      "warehouse_id": "b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d1e",
                      "location_id": null,
                      "movement_type": "RECEIPT",
                      "quantity": "100",
                      "unit_cost": "25000",
                      "currency": "XOF",
                      "value_date": "2026-01-10",
                      "transfer_group_id": null,
                      "reverses_movement_id": null,
                      "reason": null,
                      "source_ref_type": null,
                      "source_ref_id": null,
                      "created_at": "2026-01-10T07:30:00.000006Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "inventory:read"
            ]
          },
          {
            "bearer": [
              "inventory:read"
            ]
          }
        ],
        "x-required-scopes": [
          "inventory:read"
        ]
      }
    },
    "/tenders": {
      "get": {
        "tags": [
          "tenders"
        ],
        "summary": "Lister les avis de marchés publics",
        "description": "Avis publics relayés depuis Tauraco Marchés (données externes non vérifiées), par date de première publication connue ; statut open par défaut.\n\nScopes requis : `tenders:read`.",
        "operationId": "listTenders",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Recherche (Search)."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 120
            },
            "description": "Pays ou zone (ML, ML,SN, UEMOA…) (Country or zone (ML, ML,SN, UEMOA…))."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "closed",
                "cancelled",
                "awarded",
                "unknown",
                "all"
              ]
            },
            "description": "Statut (défaut : open ; all = tous) (Status (default: open; all = any)).",
            "example": "open"
          },
          {
            "name": "deadline_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Date limite à partir du (inclus) (Deadline from (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "deadline_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Date limite jusqu'au (inclus) (Deadline until (inclusive)).",
            "example": "2026-01-01"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenderList"
                },
                "example": {
                  "data": [
                    {
                      "id": "tnd_0001",
                      "slug": "rehabilitation-route-exemple-2026",
                      "title": "Réhabilitation d'une route communale",
                      "summary": "Travaux de réhabilitation.",
                      "buyer_name": "Commune Exemple",
                      "country": "ML",
                      "region": null,
                      "sector": "travaux",
                      "notice_type": "appel_offres",
                      "procedure_type": "ouvert",
                      "tender_kind": "travaux",
                      "status": "open",
                      "is_expired": false,
                      "can_apply": true,
                      "published_at": "2026-01-10T00:00:00Z",
                      "deadline_at": "2026-02-10T17:00:00Z",
                      "deadline_tz": "Africa/Bamako",
                      "budget_amount": "150000000",
                      "currency": "XOF",
                      "source_name": "Journal officiel (exemple)",
                      "source_url": "https://marches.example.org/avis/1",
                      "url": "https://tauraco.io/marches/rehabilitation-route-exemple-2026",
                      "first_seen_at": "2026-01-10T06:00:00Z",
                      "last_seen_at": "2026-01-12T06:00:00Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "502": {
            "description": "Service distant indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#upstream_unavailable",
                  "title": "Service distant indisponible",
                  "status": 502,
                  "detail": "Le service des marchés publics est momentanément indisponible.",
                  "instance": "/public/v1/invoices",
                  "code": "upstream_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "tenders:read"
            ]
          },
          {
            "bearer": [
              "tenders:read"
            ]
          }
        ],
        "x-required-scopes": [
          "tenders:read"
        ]
      }
    },
    "/tenders/{slug}": {
      "get": {
        "tags": [
          "tenders"
        ],
        "summary": "Lire un avis de marché public",
        "description": "Fiche d'un avis (donnée externe non vérifiée) ; 404 si le slug est inconnu.\n\nScopes requis : `tenders:read`.",
        "operationId": "getTender",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant lisible de l'avis (slug de Tauraco Marchés).",
            "example": "rehabilitation-route-exemple-2026"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenderDetailOut"
                },
                "example": {
                  "id": "tnd_0001",
                  "slug": "rehabilitation-route-exemple-2026",
                  "title": "Réhabilitation d'une route communale",
                  "summary": "Travaux de réhabilitation.",
                  "buyer_name": "Commune Exemple",
                  "country": "ML",
                  "region": null,
                  "sector": "travaux",
                  "notice_type": "appel_offres",
                  "procedure_type": "ouvert",
                  "tender_kind": "travaux",
                  "status": "open",
                  "is_expired": false,
                  "can_apply": true,
                  "published_at": "2026-01-10T00:00:00Z",
                  "deadline_at": "2026-02-10T17:00:00Z",
                  "deadline_tz": "Africa/Bamako",
                  "budget_amount": "150000000",
                  "currency": "XOF",
                  "source_name": "Journal officiel (exemple)",
                  "source_url": "https://marches.example.org/avis/1",
                  "url": "https://tauraco.io/marches/rehabilitation-route-exemple-2026",
                  "first_seen_at": "2026-01-10T06:00:00Z",
                  "last_seen_at": "2026-01-12T06:00:00Z",
                  "description": "Travaux de réhabilitation de la route.",
                  "eligibility": "Agrément B",
                  "external_ref": "AO-2026-001",
                  "documents": [
                    {
                      "title": "Dossier d'appel d'offres",
                      "url": "https://marches.example.org/dao/1.pdf"
                    }
                  ],
                  "amendments": [
                    {
                      "id": "amd-1",
                      "seen_at": "2026-01-12T06:00:00Z",
                      "kind": "deadline"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "502": {
            "description": "Service distant indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#upstream_unavailable",
                  "title": "Service distant indisponible",
                  "status": 502,
                  "detail": "Le service des marchés publics est momentanément indisponible.",
                  "instance": "/public/v1/invoices",
                  "code": "upstream_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "tenders:read"
            ]
          },
          {
            "bearer": [
              "tenders:read"
            ]
          }
        ],
        "x-required-scopes": [
          "tenders:read"
        ]
      }
    },
    "/financing/requests": {
      "get": {
        "tags": [
          "financing"
        ],
        "summary": "Lister les demandes de financement",
        "description": "Demandes de financement de l'entreprise, par date de création.\n\nScopes requis : `financing:read`.",
        "operationId": "listFinancingRequests",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "SUBMITTED",
                "UNDER_REVIEW",
                "INFORMATION_REQUESTED",
                "OFFERS_RECEIVED",
                "OFFER_ACCEPTED",
                "DECLINED",
                "WITHDRAWN",
                "FUNDED",
                "SETTLED",
                "CLOSED"
              ]
            },
            "description": "Statut (Status).",
            "example": "DRAFT"
          },
          {
            "name": "product",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "INVOICE_FINANCING",
                "FACTORING",
                "REVERSE_FACTORING",
                "SECURED_FINANCING"
              ]
            },
            "description": "Produit (Product).",
            "example": "INVOICE_FINANCING"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créée à partir du (inclus) (Created from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Créée avant le (exclu) (Created before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifiée à partir du (inclus) (Updated from (inclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "updated_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Modifiée avant le (exclu) (Updated before (exclusive)).",
            "example": "2026-01-01T00:00:00Z"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FinancingRequestList"
                },
                "example": {
                  "data": [
                    {
                      "id": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f",
                      "billing_invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "amount_requested": "100000",
                      "currency": "XOF",
                      "product": "INVOICE_FINANCING",
                      "country": "SN",
                      "status": "SUBMITTED",
                      "marketplace_mode": null,
                      "accepted_offer_id": null,
                      "source_changed": false,
                      "submitted_at": "2026-01-06T10:00:00Z",
                      "expires_at": null,
                      "closed_at": null,
                      "created_at": "2026-01-06T09:59:00.000007Z",
                      "updated_at": "2026-01-06T10:00:00Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "financing:read"
            ]
          },
          {
            "bearer": [
              "financing:read"
            ]
          }
        ],
        "x-required-scopes": [
          "financing:read"
        ]
      }
    },
    "/financing/requests/{request_id}": {
      "get": {
        "tags": [
          "financing"
        ],
        "summary": "Lire une demande de financement",
        "description": "Une demande de l'entreprise ; 404 si absente ou invisible. Cible du lien self des événements financing.* d'audience entreprise.\n\nScopes requis : `financing:read`.",
        "operationId": "getFinancingRequest",
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FinancingRequestOut"
                },
                "example": {
                  "id": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f",
                  "billing_invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                  "amount_requested": "100000",
                  "currency": "XOF",
                  "product": "INVOICE_FINANCING",
                  "country": "SN",
                  "status": "SUBMITTED",
                  "marketplace_mode": null,
                  "accepted_offer_id": null,
                  "source_changed": false,
                  "submitted_at": "2026-01-06T10:00:00Z",
                  "expires_at": null,
                  "closed_at": null,
                  "created_at": "2026-01-06T09:59:00.000007Z",
                  "updated_at": "2026-01-06T10:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "financing:read"
            ]
          },
          {
            "bearer": [
              "financing:read"
            ]
          }
        ],
        "x-required-scopes": [
          "financing:read"
        ]
      }
    },
    "/collateral/depots": {
      "get": {
        "tags": [
          "financing",
          "collateral"
        ],
        "summary": "Lister les dépôts",
        "description": "Stocks de l'entreprise confiés à un tiers détenteur au titre d'une garantie, par date de création. Chaque ligne porte un avertissement juridique : elle constate une remise, elle ne vaut ni inscription ni preuve de rang. Réservé au propriétaire ERP (accès délégué).\n\nScopes requis : `collateral:read`.",
        "operationId": "listCollateralDepots",
        "parameters": [
          {
            "name": "statut_metier",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 48
            },
            "description": "Statut (Status)."
          },
          {
            "name": "type_garantie",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 48
            },
            "description": "Type de garantie (Collateral type)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié au jeu et aux filtres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollateralDepotList"
                },
                "example": {
                  "data": [
                    {
                      "id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
                      "type_garantie": "nantissement_stocks",
                      "nature": "reelle",
                      "pays": "SN",
                      "statut_metier": "constituee",
                      "date_acte": "2026-01-15",
                      "date_peremption": null,
                      "created_at": "2026-01-15T08:30:00Z",
                      "updated_at": "2026-01-15T08:30:00Z",
                      "avertissement_juridique": "Information de suivi : cette ligne constate la remise d'un stock gagé à un tiers détenteur. Elle ne vaut ni inscription au registre compétent, ni preuve de l'opposabilité ou du rang de la sûreté."
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "collateral:read"
            ]
          },
          {
            "bearer": [
              "collateral:read"
            ]
          }
        ],
        "x-required-scopes": [
          "collateral:read"
        ]
      }
    },
    "/collateral/depots/{depot_id}": {
      "get": {
        "tags": [
          "financing",
          "collateral"
        ],
        "summary": "Lire un dépôt",
        "description": "Un dépôt qui grève un lot de l'entreprise ; 404 s'il est absent ou invisible.\n\nScopes requis : `collateral:read`.",
        "operationId": "getCollateralDepot",
        "parameters": [
          {
            "name": "depot_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollateralDepotOut"
                },
                "example": {
                  "id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
                  "type_garantie": "nantissement_stocks",
                  "nature": "reelle",
                  "pays": "SN",
                  "statut_metier": "constituee",
                  "date_acte": "2026-01-15",
                  "date_peremption": null,
                  "created_at": "2026-01-15T08:30:00Z",
                  "updated_at": "2026-01-15T08:30:00Z",
                  "avertissement_juridique": "Information de suivi : cette ligne constate la remise d'un stock gagé à un tiers détenteur. Elle ne vaut ni inscription au registre compétent, ni preuve de l'opposabilité ou du rang de la sûreté."
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "collateral:read"
            ]
          },
          {
            "bearer": [
              "collateral:read"
            ]
          }
        ],
        "x-required-scopes": [
          "collateral:read"
        ]
      }
    },
    "/documents": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "Lister les pièces d'un parent",
        "description": "Métadonnées des pièces d'un parent (v1 : demande de financement de l'entreprise), par date de dépôt. Le scope du parent (financing:read) est exigé en plus : sans lui, ou pour un parent inconnu ou d'une autre entreprise, 404.\n\nScopes requis : `documents:read`.",
        "operationId": "listDocuments",
        "parameters": [
          {
            "name": "parent_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "financing_request"
              ]
            },
            "description": "Type du parent des pièces.",
            "example": "financing_request"
          },
          {
            "name": "parent_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant du parent (une demande de financement de l'entreprise).",
            "example": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Taille de page, de 1 à 200.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentList"
                },
                "example": {
                  "data": [
                    {
                      "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                      "parent_type": "financing_request",
                      "parent_id": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f",
                      "file_name": "bilan-2025.pdf",
                      "content_type": "application/pdf",
                      "size_bytes": 482133,
                      "sha256": "9f2b5c0d4e1a7b3c8d6e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c",
                      "label": "Bilan 2025",
                      "uploaded_by": "company",
                      "reserved_to_one_institution": false,
                      "created_at": "2026-01-06T10:02:00Z",
                      "links": {
                        "self": "/documents/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                        "content": "/documents/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9/content"
                      }
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "documents:read"
            ]
          },
          {
            "bearer": [
              "documents:read"
            ]
          }
        ],
        "x-required-scopes": [
          "documents:read"
        ]
      }
    },
    "/documents/{document_id}": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "Lire les métadonnées d'une pièce",
        "description": "Métadonnées d'une pièce ; 404 si elle est inconnue, d'une autre entreprise, ou si le jeton ne porte pas le scope de son parent.\n\nScopes requis : `documents:read`.",
        "operationId": "getDocument",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentOut"
                },
                "example": {
                  "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                  "parent_type": "financing_request",
                  "parent_id": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f",
                  "file_name": "bilan-2025.pdf",
                  "content_type": "application/pdf",
                  "size_bytes": 482133,
                  "sha256": "9f2b5c0d4e1a7b3c8d6e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c",
                  "label": "Bilan 2025",
                  "uploaded_by": "company",
                  "reserved_to_one_institution": false,
                  "created_at": "2026-01-06T10:02:00Z",
                  "links": {
                    "self": "/documents/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                    "content": "/documents/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9/content"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "documents:read"
            ]
          },
          {
            "bearer": [
              "documents:read"
            ]
          }
        ],
        "x-required-scopes": [
          "documents:read"
        ]
      }
    },
    "/documents/{document_id}/content": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "Télécharger le contenu d'une pièce",
        "description": "Contenu d'une pièce, en flux (Cache-Control: private, no-store ; X-Content-SHA256). 404 si la pièce est inconnue, d'une autre entreprise, ou sans le scope de son parent. Chaque téléchargement est journalisé.\n\nScopes requis : `documents:read`.",
        "operationId": "getDocumentContent",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Contenu de la pièce.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "description": "attachment; filename=\"…\" (nom neutralisé, ASCII).",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "private, no-store",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-SHA256": {
                "description": "Empreinte SHA-256 du contenu (hexadécimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "documents:read"
            ]
          },
          {
            "bearer": [
              "documents:read"
            ]
          }
        ],
        "x-required-scopes": [
          "documents:read"
        ]
      }
    },
    "/invoices/{invoice_id}/pdf": {
      "get": {
        "tags": [
          "documents",
          "invoices"
        ],
        "summary": "Télécharger le PDF d'une facture",
        "description": "La facture rendue en PDF à la demande (même rendu que l'ERP), Cache-Control: private, no-store. 404 si la facture est absente ou d'une autre entreprise.\n\nScopes requis : `invoices:read`.",
        "operationId": "getInvoicePdf",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "PDF de la facture.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "description": "attachment; filename=\"…\" (nom neutralisé, ASCII).",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "private, no-store",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-SHA256": {
                "description": "Empreinte SHA-256 du contenu (hexadécimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "invoices:read"
            ]
          },
          {
            "bearer": [
              "invoices:read"
            ]
          }
        ],
        "x-required-scopes": [
          "invoices:read"
        ]
      }
    },
    "/exports": {
      "get": {
        "tags": [
          "exports"
        ],
        "summary": "Lister ses exports",
        "description": "Jobs d'export créés par cette application (et ce sujet), du plus récent au plus ancien.\n\nScopes requis : `exports:read`.",
        "operationId": "listExports",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "QUEUED",
                "RUNNING",
                "SUCCEEDED",
                "FAILED",
                "CANCELLED",
                "EXPIRED"
              ]
            },
            "description": "Ne garder que les jobs de cet état.",
            "example": "SUCCEEDED"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2048
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "Taille de page, de 1 à 100.",
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportJobList"
                },
                "example": {
                  "data": [
                    {
                      "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                      "status": "SUCCEEDED",
                      "format": "csv",
                      "datasets": [
                        {
                          "dataset": "invoices",
                          "columns": [],
                          "filters": {
                            "created_after": "2026-01-01T00:00:00Z"
                          }
                        }
                      ],
                      "format_options": {},
                      "include_pii": false,
                      "row_count": 1250,
                      "byte_size": 182044,
                      "sha256": "4a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
                      "file_name": "invoices_20260105-080000.csv",
                      "delivery": "download",
                      "delivery_status": null,
                      "error": null,
                      "progress_rows": 1250,
                      "cancel_requested": false,
                      "via": "public_api",
                      "attempt": 1,
                      "queued_at": "2026-01-05T08:00:00Z",
                      "started_at": "2026-01-05T08:00:02Z",
                      "finished_at": "2026-01-05T08:00:09Z",
                      "expires_at": "2026-02-04T08:00:09Z",
                      "retry_of_id": null,
                      "links": {
                        "self": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                        "download": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e/download"
                      }
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "410": {
            "description": "Export expiré",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#export_expired",
                  "title": "Export expiré",
                  "status": 410,
                  "detail": "Cet export a expiré.",
                  "instance": "/public/v1/invoices",
                  "code": "export_expired",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:read"
            ]
          },
          {
            "bearer": [
              "exports:read"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:read"
        ]
      },
      "post": {
        "tags": [
          "exports"
        ],
        "summary": "Demander un export",
        "description": "Met en file un export (un à dix jeux, format du catalogue GET /integrations/formats). Idempotent par Idempotency-Key. Le job s'exécute avec les droits de l'application, relus à l'exécution ; suivre GET /exports/{job_id} ou l'événement export.completed.\n\nScopes requis : `exports:write`.",
        "operationId": "createExport",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportJobOut"
                },
                "example": {
                  "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                  "status": "SUCCEEDED",
                  "format": "csv",
                  "datasets": [
                    {
                      "dataset": "invoices",
                      "columns": [],
                      "filters": {
                        "created_after": "2026-01-01T00:00:00Z"
                      }
                    }
                  ],
                  "format_options": {},
                  "include_pii": false,
                  "row_count": 1250,
                  "byte_size": 182044,
                  "sha256": "4a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
                  "file_name": "invoices_20260105-080000.csv",
                  "delivery": "download",
                  "delivery_status": null,
                  "error": null,
                  "progress_rows": 1250,
                  "cancel_requested": false,
                  "via": "public_api",
                  "attempt": 1,
                  "queued_at": "2026-01-05T08:00:00Z",
                  "started_at": "2026-01-05T08:00:02Z",
                  "finished_at": "2026-01-05T08:00:09Z",
                  "expires_at": "2026-02-04T08:00:09Z",
                  "retry_of_id": null,
                  "links": {
                    "self": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                    "download": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e/download"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "410": {
            "description": "Export expiré",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#export_expired",
                  "title": "Export expiré",
                  "status": 410,
                  "detail": "Cet export a expiré.",
                  "instance": "/public/v1/invoices",
                  "code": "export_expired",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "description": "Demande d'export (exports.service.ExportRequest).",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportRequest"
              },
              "example": {
                "datasets": [
                  {
                    "dataset": "invoices",
                    "filters": {
                      "created_after": "2026-01-01T00:00:00Z"
                    }
                  }
                ],
                "format": "csv",
                "format_options": {},
                "include_pii": false,
                "delivery": "download"
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:write"
            ]
          },
          {
            "bearer": [
              "exports:write"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:write"
        ]
      }
    },
    "/exports/{job_id}": {
      "get": {
        "tags": [
          "exports"
        ],
        "summary": "Lire un export",
        "description": "Un job d'export de cette application ; 404 s'il est inconnu ou d'un autre auteur.\n\nScopes requis : `exports:read`.",
        "operationId": "getExport",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportJobOut"
                },
                "example": {
                  "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                  "status": "SUCCEEDED",
                  "format": "csv",
                  "datasets": [
                    {
                      "dataset": "invoices",
                      "columns": [],
                      "filters": {
                        "created_after": "2026-01-01T00:00:00Z"
                      }
                    }
                  ],
                  "format_options": {},
                  "include_pii": false,
                  "row_count": 1250,
                  "byte_size": 182044,
                  "sha256": "4a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
                  "file_name": "invoices_20260105-080000.csv",
                  "delivery": "download",
                  "delivery_status": null,
                  "error": null,
                  "progress_rows": 1250,
                  "cancel_requested": false,
                  "via": "public_api",
                  "attempt": 1,
                  "queued_at": "2026-01-05T08:00:00Z",
                  "started_at": "2026-01-05T08:00:02Z",
                  "finished_at": "2026-01-05T08:00:09Z",
                  "expires_at": "2026-02-04T08:00:09Z",
                  "retry_of_id": null,
                  "links": {
                    "self": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                    "download": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e/download"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "410": {
            "description": "Export expiré",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#export_expired",
                  "title": "Export expiré",
                  "status": 410,
                  "detail": "Cet export a expiré.",
                  "instance": "/public/v1/invoices",
                  "code": "export_expired",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:read"
            ]
          },
          {
            "bearer": [
              "exports:read"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:read"
        ]
      }
    },
    "/exports/{job_id}/cancel": {
      "post": {
        "tags": [
          "exports"
        ],
        "summary": "Annuler un export",
        "description": "Annule un job en file, ou demande l'arrêt d'un job en cours ; 409 s'il est terminé. Idempotent par Idempotency-Key.\n\nScopes requis : `exports:write`.",
        "operationId": "cancelExport",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportJobOut"
                },
                "example": {
                  "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                  "status": "SUCCEEDED",
                  "format": "csv",
                  "datasets": [
                    {
                      "dataset": "invoices",
                      "columns": [],
                      "filters": {
                        "created_after": "2026-01-01T00:00:00Z"
                      }
                    }
                  ],
                  "format_options": {},
                  "include_pii": false,
                  "row_count": 1250,
                  "byte_size": 182044,
                  "sha256": "4a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
                  "file_name": "invoices_20260105-080000.csv",
                  "delivery": "download",
                  "delivery_status": null,
                  "error": null,
                  "progress_rows": 1250,
                  "cancel_requested": false,
                  "via": "public_api",
                  "attempt": 1,
                  "queued_at": "2026-01-05T08:00:00Z",
                  "started_at": "2026-01-05T08:00:02Z",
                  "finished_at": "2026-01-05T08:00:09Z",
                  "expires_at": "2026-02-04T08:00:09Z",
                  "retry_of_id": null,
                  "links": {
                    "self": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                    "download": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e/download"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "410": {
            "description": "Export expiré",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#export_expired",
                  "title": "Export expiré",
                  "status": 410,
                  "detail": "Cet export a expiré.",
                  "instance": "/public/v1/invoices",
                  "code": "export_expired",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:write"
            ]
          },
          {
            "bearer": [
              "exports:write"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:write"
        ]
      }
    },
    "/exports/{job_id}/download": {
      "get": {
        "tags": [
          "exports"
        ],
        "summary": "Télécharger un export",
        "description": "Fichier d'un export réussi, en flux, au porteur du jeton (Cache-Control: private, no-store ; X-Content-SHA256). 409 export_not_ready tant qu'il n'a pas réussi, 410 export_expired après la purge.\n\nScopes requis : `exports:read`.",
        "operationId": "downloadExport",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Fichier de l'export, en flux.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "description": "attachment; filename=\"…\" (nom neutralisé).",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-SHA256": {
                "description": "Empreinte SHA-256 du fichier.",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "private, no-store",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "410": {
            "description": "Export expiré",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#export_expired",
                  "title": "Export expiré",
                  "status": 410,
                  "detail": "Cet export a expiré.",
                  "instance": "/public/v1/invoices",
                  "code": "export_expired",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:read"
            ]
          },
          {
            "bearer": [
              "exports:read"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:read"
        ]
      }
    },
    "/exports/{job_id}/download-link": {
      "post": {
        "tags": [
          "exports"
        ],
        "summary": "Obtenir un lien de téléchargement signé",
        "description": "Lien signé à usage unique et de courte durée (HUB_DOWNLOAD_LINK_TTL, 60 s par défaut) vers GET /exports/{job_id}/file, à ouvrir sans en-tête Authorization. 409 si l'export n'est pas prêt, 410 s'il a expiré. Idempotent par Idempotency-Key (un rejeu rend url à null).\n\nScopes requis : `exports:read`.",
        "operationId": "createExportDownloadLink",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadLinkOut"
                },
                "example": {
                  "url": "https://api.tauraco.io/public/v1/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e/file?token=d1.eyJqIjoi…",
                  "expires_at": "2026-01-05T08:01:09Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "410": {
            "description": "Export expiré",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#export_expired",
                  "title": "Export expiré",
                  "status": 410,
                  "detail": "Cet export a expiré.",
                  "instance": "/public/v1/invoices",
                  "code": "export_expired",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:read"
            ]
          },
          {
            "bearer": [
              "exports:read"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:read"
        ]
      }
    },
    "/exports/{job_id}/file": {
      "get": {
        "tags": [
          "exports"
        ],
        "summary": "Télécharger un export par lien signé",
        "description": "Fichier d'un export par le lien signé de POST /exports/{job_id}/download-link : sans en-tête Authorization, une seule fois, avant expiration (401 sinon). Les droits de l'application sont relus en base à ce moment (404 si elle n'y a plus accès). Referrer-Policy: no-referrer. Débit limité par adresse (429 rate_limited avec Retry-After).",
        "operationId": "downloadExportByLink",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 1024
            },
            "description": "Jeton du lien signé (d1.…), à usage unique.",
            "example": "d1.eyJqIjoi…"
          }
        ],
        "responses": {
          "200": {
            "description": "Fichier de l'export, en flux.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "description": "attachment; filename=\"…\" (nom neutralisé).",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-SHA256": {
                "description": "Empreinte SHA-256 du fichier.",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "private, no-store",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "410": {
            "description": "Export expiré",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#export_expired",
                  "title": "Export expiré",
                  "status": 410,
                  "detail": "Cet export a expiré.",
                  "instance": "/public/v1/invoices",
                  "code": "export_expired",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "x-tauraco-signed-link": true,
        "security": [],
        "x-required-scopes": []
      }
    },
    "/webhooks/event-types": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Lister les types d'événements abonnables",
        "description": "Types auxquels cette application peut s'abonner : audience du tenant et scope de lecture porté par le jeton.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "listWebhookEventTypes",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEventTypeList"
                },
                "example": {
                  "data": [
                    {
                      "type": "invoice.paid",
                      "label": "Facture réglée",
                      "read_scope": "invoices:read",
                      "amounts": true
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Lister ses endpoints",
        "description": "Endpoints de webhook créés par cette application.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "listWebhooks",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointList"
                },
                "example": {
                  "data": [
                    {
                      "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                      "url": "https://integrations.exemple.test/tauraco/webhooks",
                      "events": [
                        "invoice.paid",
                        "payment.recorded"
                      ],
                      "description": "ERP du groupe",
                      "is_active": true,
                      "api_version": "v2",
                      "secret_hint": "…a1b2",
                      "failure_count": 0,
                      "failing_since": null,
                      "disabled_at": null,
                      "disabled_reason": null,
                      "created_at": "2026-01-05T08:00:00Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      },
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Créer un endpoint",
        "description": "Crée un endpoint HTTPS (anti-SSRF) abonné à des types dont l'application porte le scope de lecture (sinon 403 insufficient_scope). Le secret de signature n'est rendu qu'ici ; un rejeu par Idempotency-Key le rend à null.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "createWebhook",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointSecretOut"
                },
                "example": {
                  "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                  "url": "https://integrations.exemple.test/tauraco/webhooks",
                  "events": [
                    "invoice.paid",
                    "payment.recorded"
                  ],
                  "description": "ERP du groupe",
                  "is_active": true,
                  "api_version": "v2",
                  "secret_hint": "…a1b2",
                  "failure_count": 0,
                  "failing_since": null,
                  "disabled_at": null,
                  "disabled_reason": null,
                  "created_at": "2026-01-05T08:00:00Z",
                  "secret": "whsec_exemple0000000000000000000000000000"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "description": "Corps de ``POST /webhooks``.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointCreate"
              },
              "example": {
                "url": "https://integrations.exemple.test/tauraco/webhooks",
                "events": [
                  "invoice.paid",
                  "payment.recorded"
                ],
                "description": "ERP du groupe"
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks/{endpoint_id}": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Lire un endpoint",
        "description": "Un endpoint de cette application ; 404 sinon.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "getWebhook",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointOut"
                },
                "example": {
                  "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                  "url": "https://integrations.exemple.test/tauraco/webhooks",
                  "events": [
                    "invoice.paid",
                    "payment.recorded"
                  ],
                  "description": "ERP du groupe",
                  "is_active": true,
                  "api_version": "v2",
                  "secret_hint": "…a1b2",
                  "failure_count": 0,
                  "failing_since": null,
                  "disabled_at": null,
                  "disabled_reason": null,
                  "created_at": "2026-01-05T08:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      },
      "patch": {
        "tags": [
          "webhooks"
        ],
        "summary": "Modifier un endpoint",
        "description": "Modifie l'URL (revalidée), les types (scope de lecture revérifié) ou la description.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "updateWebhook",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointOut"
                },
                "example": {
                  "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                  "url": "https://integrations.exemple.test/tauraco/webhooks",
                  "events": [
                    "invoice.paid",
                    "payment.recorded"
                  ],
                  "description": "ERP du groupe",
                  "is_active": true,
                  "api_version": "v2",
                  "secret_hint": "…a1b2",
                  "failure_count": 0,
                  "failing_since": null,
                  "disabled_at": null,
                  "disabled_reason": null,
                  "created_at": "2026-01-05T08:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "description": "Corps de ``PATCH /webhooks/{endpoint_id}`` (champs absents inchangés).",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointUpdate"
              },
              "example": {
                "events": [
                  "invoice.created",
                  "invoice.paid"
                ]
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      },
      "delete": {
        "tags": [
          "webhooks"
        ],
        "summary": "Supprimer un endpoint",
        "description": "Supprime l'endpoint et ses livraisons.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "deleteWebhook",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response",
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks/{endpoint_id}/rotate-secret": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Faire tourner le secret",
        "description": "Nouveau secret de signature, rendu une seule fois ; l'ancien cesse aussitôt de signer.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "rotateWebhookSecret",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointSecretOut"
                },
                "example": {
                  "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                  "url": "https://integrations.exemple.test/tauraco/webhooks",
                  "events": [
                    "invoice.paid",
                    "payment.recorded"
                  ],
                  "description": "ERP du groupe",
                  "is_active": true,
                  "api_version": "v2",
                  "secret_hint": "…a1b2",
                  "failure_count": 0,
                  "failing_since": null,
                  "disabled_at": null,
                  "disabled_reason": null,
                  "created_at": "2026-01-05T08:00:00Z",
                  "secret": "whsec_exemple0000000000000000000000000000"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks/{endpoint_id}/enable": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Réactiver un endpoint",
        "description": "Réactive l'endpoint (compteurs d'échec remis à zéro).\n\nScopes requis : `webhooks:manage`.",
        "operationId": "enableWebhook",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointOut"
                },
                "example": {
                  "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                  "url": "https://integrations.exemple.test/tauraco/webhooks",
                  "events": [
                    "invoice.paid",
                    "payment.recorded"
                  ],
                  "description": "ERP du groupe",
                  "is_active": true,
                  "api_version": "v2",
                  "secret_hint": "…a1b2",
                  "failure_count": 0,
                  "failing_since": null,
                  "disabled_at": null,
                  "disabled_reason": null,
                  "created_at": "2026-01-05T08:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks/{endpoint_id}/disable": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Désactiver un endpoint",
        "description": "Désactive l'endpoint (disabled_reason = manual).\n\nScopes requis : `webhooks:manage`.",
        "operationId": "disableWebhook",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointOut"
                },
                "example": {
                  "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                  "url": "https://integrations.exemple.test/tauraco/webhooks",
                  "events": [
                    "invoice.paid",
                    "payment.recorded"
                  ],
                  "description": "ERP du groupe",
                  "is_active": true,
                  "api_version": "v2",
                  "secret_hint": "…a1b2",
                  "failure_count": 0,
                  "failing_since": null,
                  "disabled_at": null,
                  "disabled_reason": null,
                  "created_at": "2026-01-05T08:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks/{endpoint_id}/test": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Envoyer un événement de test",
        "description": "Émet webhook.test vers cet endpoint seul ; 409 s'il est désactivé.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "testWebhook",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestOut"
                },
                "example": {
                  "event_id": "evt_0a1b2c3d4e5f60718293a4b5c6d7e8f9",
                  "delivery_id": "8c9d0e1f-2a3b-4c4d-8e5f-6a7b8c9d0e1f"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks/{endpoint_id}/deliveries": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Lister les livraisons d'un endpoint",
        "description": "Livraisons de l'endpoint, les plus récentes d'abord (sans charge utile).\n\nScopes requis : `webhooks:manage`.",
        "operationId": "listWebhookDeliveries",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "DELIVERING",
                "DELIVERED",
                "DEAD",
                "CANCELLED",
                "FAILED",
                "EXHAUSTED"
              ]
            },
            "description": "Ne garder que les livraisons de cet état.",
            "example": "FAILED"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 512
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Taille de page, de 1 à 100.",
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryList"
                },
                "example": {
                  "data": [
                    {
                      "id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
                      "event_id": "evt_3f2a9c0d6b1e4a7f8c5d2e1b0a9f8e7d",
                      "event_type": "invoice.paid",
                      "status": "DELIVERED",
                      "attempts": 1,
                      "max_attempts": 7,
                      "next_retry_at": null,
                      "last_status_code": 200,
                      "last_error": null,
                      "delivered_at": "2026-01-05T08:00:01Z",
                      "replayed_from_id": null,
                      "created_at": "2026-01-05T08:00:00Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks/{endpoint_id}/deliveries/{delivery_id}": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Lire une livraison",
        "description": "Une livraison de l'endpoint (sans charge utile) ; 404 sinon.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "getWebhookDelivery",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "delivery_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryOut"
                },
                "example": {
                  "id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
                  "event_id": "evt_3f2a9c0d6b1e4a7f8c5d2e1b0a9f8e7d",
                  "event_type": "invoice.paid",
                  "status": "DELIVERED",
                  "attempts": 1,
                  "max_attempts": 7,
                  "next_retry_at": null,
                  "last_status_code": 200,
                  "last_error": null,
                  "delivered_at": "2026-01-05T08:00:01Z",
                  "replayed_from_id": null,
                  "created_at": "2026-01-05T08:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/webhooks/{endpoint_id}/deliveries/{delivery_id}/replay": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Rejouer une livraison",
        "description": "Nouvelle livraison du même événement (même event_id) ; 409 pour une livraison en cours, un endpoint désactivé ou un événement purgé.\n\nScopes requis : `webhooks:manage`.",
        "operationId": "replayWebhookDelivery",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "delivery_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryOut"
                },
                "example": {
                  "id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
                  "event_id": "evt_3f2a9c0d6b1e4a7f8c5d2e1b0a9f8e7d",
                  "event_type": "invoice.paid",
                  "status": "DELIVERED",
                  "attempts": 1,
                  "max_attempts": 7,
                  "next_retry_at": null,
                  "last_status_code": 200,
                  "last_error": null,
                  "delivered_at": "2026-01-05T08:00:01Z",
                  "replayed_from_id": null,
                  "created_at": "2026-01-05T08:00:00Z"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          },
          {
            "bearer": [
              "webhooks:manage"
            ]
          }
        ],
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/integrations/datasets": {
      "get": {
        "tags": [
          "integrations"
        ],
        "summary": "Lister les jeux exportables",
        "description": "Jeux de données que cette application peut exporter : scope porté, droits relus, module ouvert ; colonnes servies (sans données personnelles ni bancaires), filtres, formats.\n\nScopes requis : `exports:read`.",
        "operationId": "listIntegrationDatasets",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetList"
                },
                "example": {
                  "data": [
                    {
                      "code": "invoices",
                      "module": "billing",
                      "label": "Factures clients",
                      "scope": "invoices:read",
                      "formats": [
                        "csv",
                        "json",
                        "xlsx"
                      ],
                      "differential": true,
                      "columns": [
                        {
                          "name": "number",
                          "label": "Numéro",
                          "type": "string"
                        }
                      ],
                      "filters": [
                        {
                          "name": "created_after",
                          "type": "datetime",
                          "label": "Créée après",
                          "required": false,
                          "enum_values": null
                        }
                      ]
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:read"
            ]
          },
          {
            "bearer": [
              "exports:read"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:read"
        ]
      }
    },
    "/integrations/formats": {
      "get": {
        "tags": [
          "integrations"
        ],
        "summary": "Lister les formats d'export",
        "description": "Formats d'export utilisables et leur maturité.\n\nScopes requis : `exports:read`.",
        "operationId": "listIntegrationFormats",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportFormatList"
                },
                "example": {
                  "data": [
                    {
                      "code": "csv",
                      "label": "CSV",
                      "extension": "csv",
                      "maturity": "available",
                      "multi_dataset": false,
                      "disclaimer": null
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:read"
            ]
          },
          {
            "bearer": [
              "exports:read"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:read"
        ]
      }
    },
    "/integrations/connections": {
      "get": {
        "tags": [
          "integrations"
        ],
        "summary": "Lister les connexions de livraison",
        "description": "Connexions du tenant utilisables comme livraison d'un export (sans configuration ni secret). 404 si les connecteurs ne sont pas ouverts.\n\nScopes requis : `exports:read`.",
        "operationId": "listIntegrationConnections",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectionList"
                },
                "example": {
                  "data": [
                    {
                      "id": "9d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
                      "connector_code": "sftp",
                      "name": "SFTP du cabinet",
                      "status": "active",
                      "last_test_at": "2026-01-05T08:00:00Z",
                      "last_test_status": "ok",
                      "created_at": "2026-01-04T10:00:00Z"
                    }
                  ],
                  "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
                  "has_more": true
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "exports:read"
            ]
          },
          {
            "bearer": [
              "exports:read"
            ]
          }
        ],
        "x-required-scopes": [
          "exports:read"
        ]
      }
    },
    "/bank/inbox": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lister la boîte de réception",
        "description": "Dossiers transmis à l'institution (``bank.corbeille``), par onglet et par filtre, paginés par curseur.\n\nScopes requis : `bank:inbox:read`.",
        "operationId": "bankListInbox",
        "parameters": [
          {
            "name": "tab",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "new",
                    "in_review",
                    "information_requested",
                    "offer_submitted",
                    "closed"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Onglet de la boîte de réception.",
              "title": "Tab"
            },
            "description": "Onglet de la boîte de réception."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 2
                },
                {
                  "type": "null"
                }
              ],
              "description": "Pays de la demande (ISO 3166-1 alpha-2).",
              "title": "Country"
            },
            "description": "Pays de la demande (ISO 3166-1 alpha-2)."
          },
          {
            "name": "product",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 48
                },
                {
                  "type": "null"
                }
              ],
              "description": "Produit de financement demandé.",
              "title": "Product"
            },
            "description": "Produit de financement demandé."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 3,
                  "maxLength": 3
                },
                {
                  "type": "null"
                }
              ],
              "description": "Devise de la demande (ISO 4217).",
              "title": "Currency"
            },
            "description": "Devise de la demande (ISO 4217)."
          },
          {
            "name": "verification_level",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 48
                },
                {
                  "type": "null"
                }
              ],
              "description": "Niveau de vérification du dossier.",
              "title": "Verification Level"
            },
            "description": "Niveau de vérification du dossier."
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "received",
                    "amount",
                    "due_date"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Tri factuel : réception, montant ou échéance.",
              "title": "Sort"
            },
            "description": "Tri factuel : réception, montant ou échéance."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "Taille de page, de 1 à 200.",
              "default": 50,
              "title": "Limit"
            },
            "description": "Taille de page, de 1 à 200."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2048
                },
                {
                  "type": "null"
                }
              ],
              "description": "Curseur opaque rendu par la page précédente (next_cursor), lié à la liste et aux filtres.",
              "title": "Cursor"
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié à la liste et aux filtres."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankInboxOut"
                },
                "example": {
                  "institution": {
                    "tenant_id": "t_banque_exemple",
                    "name": "Banque Exemple SA"
                  },
                  "counters": {
                    "new": 1,
                    "in_review": 0,
                    "information_requested": 0,
                    "offer_submitted": 0,
                    "closed": 0
                  },
                  "total": 1,
                  "items": [
                    {
                      "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
                      "company_name": "PME Exemple SARL",
                      "debtor_name": "Acheteur Exemple SA",
                      "amount_requested": "1000000",
                      "currency": "XOF",
                      "due_date": "2026-12-31",
                      "product": "INVOICE_FINANCING",
                      "country": "SN",
                      "verification_level": "DOCUMENT_VERIFIE",
                      "recipient_status": "SENT",
                      "request_status": "SUBMITTED",
                      "received_at": "2026-11-02T09:30:00Z",
                      "source_changed": false,
                      "my_offer_id": null,
                      "my_offer_status": null,
                      "links": {
                        "self": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f"
                      }
                    }
                  ],
                  "next_cursor": null,
                  "has_more": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:inbox:read"
            ]
          },
          {
            "bearer": [
              "bank:inbox:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:inbox:read"
        ]
      }
    },
    "/bank/requests/{request_id}": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lire un dossier de financement",
        "description": "Dossier tel qu'il a été soumis (snapshot figé), chronologie, pièces et compléments.\n\nServi à une banque destinataire n'ayant pas décliné, y compris après le retrait de\nla demande par l'entreprise (j.19). Première consultation horodatée comme dans le\nportail (``bank.ouvrir``). Audit ``HUB_BANK_DOSSIER_VIEWED`` à chaque appel.\n\nScopes requis : `bank:requests:read`.",
        "operationId": "bankGetRequest",
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankRequestOut"
                },
                "example": {
                  "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
                  "request_status": "OFFERS_RECEIVED",
                  "recipient_status": "OFFER_SUBMITTED",
                  "product": "INVOICE_FINANCING",
                  "country": "SN",
                  "currency": "XOF",
                  "amount_requested": "1000000",
                  "submitted_at": "2026-11-02T09:30:00Z",
                  "received_at": "2026-11-02T09:30:00Z",
                  "viewed_at": "2026-11-02T11:02:00Z",
                  "snapshot": {
                    "version": 1,
                    "pris_le": "2026-11-02T09:30:00Z",
                    "pays": "SN",
                    "facture": {
                      "numero": "F-2026-0042",
                      "date_emission": "2026-10-20",
                      "echeance": "2026-12-31",
                      "devise": "XOF",
                      "montant_ht": 1000000,
                      "montant_taxes": 0,
                      "montant_total": 1000000,
                      "montant_regle": 0,
                      "statut": "SENT"
                    },
                    "cedant": {
                      "denomination": "PME Exemple SARL",
                      "pays": "SN"
                    },
                    "debiteur": {
                      "denomination": "Acheteur Exemple SA",
                      "pays": "SN"
                    },
                    "verification": {
                      "niveau": "DOCUMENT_VERIFIE"
                    }
                  },
                  "source_changed": false,
                  "source_change_detail": null,
                  "asset_id": null,
                  "my_offer": {
                    "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "version": 1,
                    "status": "SUBMITTED",
                    "amount": "950000",
                    "currency": "XOF",
                    "duration_days": 60,
                    "valid_until": "2026-11-30",
                    "submitted_at": "2026-11-03T10:00:00Z"
                  },
                  "capabilities": {
                    "read": true,
                    "instruct": true,
                    "decide": false
                  },
                  "timeline": [
                    {
                      "type": "REQUEST_SUBMITTED",
                      "occurred_at": "2026-11-02T09:30:00Z",
                      "side": "COMPANY",
                      "detail": {
                        "destinataires": 2,
                        "niveau_verification": "DOCUMENT_VERIFIE"
                      }
                    }
                  ],
                  "documents": [
                    {
                      "id": "2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c",
                      "file_name": "facture.pdf",
                      "content_type": "application/pdf",
                      "size_bytes": 182340,
                      "label": "Facture",
                      "uploaded_by_side": "COMPANY",
                      "reserved_for_institution": false,
                      "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c",
                      "created_at": "2026-11-02T09:25:00Z",
                      "links": {
                        "content": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f/documents/2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c/content"
                      }
                    }
                  ],
                  "information_requests": [
                    {
                      "id": "6d7e8f90-a1b2-4c3d-8e4f-5a6b7c8d9e0f",
                      "kind": "DOCUMENT_REQUEST",
                      "side": "INSTITUTION",
                      "text": "Merci de joindre le bon de commande signé.",
                      "document_id": null,
                      "parent_id": null,
                      "created_at": "2026-11-03T08:15:00Z",
                      "resolved_at": null
                    }
                  ],
                  "links": {
                    "self": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:requests:read"
            ]
          },
          {
            "bearer": [
              "bank:requests:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:requests:read"
        ]
      }
    },
    "/bank/requests/{request_id}/documents": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lister les pièces d'un dossier",
        "description": "Métadonnées des pièces servies à l'institution (dossier et pièces qui lui sont réservées).\n\nScopes requis : `bank:documents:read`.",
        "operationId": "bankListRequestDocuments",
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankDocumentsOut"
                },
                "example": {
                  "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
                  "items": [
                    {
                      "id": "2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c",
                      "file_name": "facture.pdf",
                      "content_type": "application/pdf",
                      "size_bytes": 182340,
                      "label": "Facture",
                      "uploaded_by_side": "COMPANY",
                      "reserved_for_institution": false,
                      "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c",
                      "created_at": "2026-11-02T09:25:00Z",
                      "links": {
                        "content": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f/documents/2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c/content"
                      }
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:documents:read"
            ]
          },
          {
            "bearer": [
              "bank:documents:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:documents:read"
        ]
      }
    },
    "/bank/requests/{request_id}/documents/{document_id}/content": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Télécharger le contenu d'une pièce",
        "description": "Contenu d'une pièce, en flux (``no-store``, ``nosniff``, ``X-Content-SHA256``).\n\nAudit ``HUB_BANK_DOCUMENT_DOWNLOADED`` (``sha256``) commité avant le premier octet.\n\nScopes requis : `bank:documents:read`.",
        "operationId": "bankGetRequestDocument",
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Contenu de la pièce.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "description": "attachment; filename=\"…\" (nom neutralisé, ASCII).",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "private, no-store",
                "schema": {
                  "type": "string"
                }
              },
              "X-Content-SHA256": {
                "description": "Empreinte SHA-256 du contenu (hexadécimal).",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:documents:read"
            ]
          },
          {
            "bearer": [
              "bank:documents:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:documents:read"
        ]
      }
    },
    "/bank/requests/{request_id}/information-requests": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lister les demandes de complément",
        "description": "Fil des compléments entre l'institution et l'entreprise (demandes, réponses, traitement).\n\nScopes requis : `bank:requests:read`.",
        "operationId": "bankListInformationRequests",
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankInformationRequestsOut"
                },
                "example": {
                  "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
                  "items": [
                    {
                      "id": "6d7e8f90-a1b2-4c3d-8e4f-5a6b7c8d9e0f",
                      "kind": "DOCUMENT_REQUEST",
                      "side": "INSTITUTION",
                      "text": "Merci de joindre le bon de commande signé.",
                      "document_id": null,
                      "parent_id": null,
                      "created_at": "2026-11-03T08:15:00Z",
                      "resolved_at": null
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:requests:read"
            ]
          },
          {
            "bearer": [
              "bank:requests:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:requests:read"
        ]
      },
      "post": {
        "tags": [
          "bank"
        ],
        "summary": "Demander un complément",
        "description": "Demande une pièce, une précision ou une confirmation à l'entreprise (``OPERATEUR``).\n\nScopes requis : `bank:info-requests:write`.",
        "operationId": "bankCreateInformationRequest",
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InformationRequestIn"
              },
              "example": {
                "text": "Merci de joindre le bon de commande signé.",
                "kind": "DOCUMENT_REQUEST"
              }
            }
          },
          "description": ""
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InformationRequestCreatedOut"
                },
                "example": {
                  "id": "6d7e8f90-a1b2-4c3d-8e4f-5a6b7c8d9e0f",
                  "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
                  "kind": "DOCUMENT_REQUEST",
                  "created_at": "2026-11-03T08:15:00Z",
                  "links": {
                    "self": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:info-requests:write"
            ]
          },
          {
            "bearer": [
              "bank:info-requests:write"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:info-requests:write"
        ]
      }
    },
    "/bank/facilities": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lister les facilités",
        "description": "Facilités de l'institution, avec le reste dû dérivé du registre de servicing (lecture seule).\n\nScopes requis : `bank:repayments:read`.",
        "operationId": "bankListFacilities",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "Taille de page, de 1 à 200.",
              "default": 50,
              "title": "Limit"
            },
            "description": "Taille de page, de 1 à 200."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2048
                },
                {
                  "type": "null"
                }
              ],
              "description": "Curseur opaque rendu par la page précédente (next_cursor), lié à la liste et aux filtres.",
              "title": "Cursor"
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié à la liste et aux filtres."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankFacilitiesOut"
                },
                "example": {
                  "items": [
                    {
                      "id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                      "facility_type": "RECEIVABLES_FACILITY",
                      "country": "SN",
                      "currency": "XOF",
                      "facility_limit": "50000000",
                      "committed_limit": "50000000",
                      "utilized_amount": "12000000",
                      "available_limit": "38000000",
                      "status": "ACTIVE",
                      "borrowing_base_required": true,
                      "effective_from": "2026-01-01",
                      "effective_to": "2026-12-31",
                      "principal_outstanding": "12000000",
                      "interest_and_margin_outstanding": "180000",
                      "fees_outstanding": "25000",
                      "total_outstanding": "12205000"
                    }
                  ],
                  "next_cursor": null,
                  "has_more": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:repayments:read"
            ]
          },
          {
            "bearer": [
              "bank:repayments:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:repayments:read"
        ]
      }
    },
    "/bank/facilities/{facility_id}": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lire une facilité",
        "description": "Une facilité et sa position (``ledger.position``).\n\nScopes requis : `bank:repayments:read`.",
        "operationId": "bankGetFacility",
        "parameters": [
          {
            "name": "facility_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankFacilityOut"
                },
                "example": {
                  "id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                  "facility_type": "RECEIVABLES_FACILITY",
                  "country": "SN",
                  "currency": "XOF",
                  "facility_limit": "50000000",
                  "committed_limit": "50000000",
                  "utilized_amount": "12000000",
                  "available_limit": "38000000",
                  "status": "ACTIVE",
                  "borrowing_base_required": true,
                  "effective_from": "2026-01-01",
                  "effective_to": "2026-12-31",
                  "principal_outstanding": "12000000",
                  "interest_and_margin_outstanding": "180000",
                  "fees_outstanding": "25000",
                  "total_outstanding": "12205000"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:repayments:read"
            ]
          },
          {
            "bearer": [
              "bank:repayments:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:repayments:read"
        ]
      }
    },
    "/bank/repayments": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lister les échéances",
        "description": "Échéancier de l'institution (miroir de ``echeances_banque``), de la plus proche à la plus lointaine.\n\nScopes requis : `bank:repayments:read`.",
        "operationId": "bankListRepayments",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 32
                },
                {
                  "type": "null"
                }
              ],
              "description": "Statut de l'échéance (DUE, PARTIALLY_PAID, PAID, OVERDUE, WRITTEN_OFF).",
              "title": "Status"
            },
            "description": "Statut de l'échéance (DUE, PARTIALLY_PAID, PAID, OVERDUE, WRITTEN_OFF)."
          },
          {
            "name": "due_before",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Échéances dues au plus tard à cette date (incluse).",
              "title": "Due Before"
            },
            "description": "Échéances dues au plus tard à cette date (incluse)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "Taille de page, de 1 à 200.",
              "default": 50,
              "title": "Limit"
            },
            "description": "Taille de page, de 1 à 200."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2048
                },
                {
                  "type": "null"
                }
              ],
              "description": "Curseur opaque rendu par la page précédente (next_cursor), lié à la liste et aux filtres.",
              "title": "Cursor"
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié à la liste et aux filtres."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankRepaymentsOut"
                },
                "example": {
                  "total": 1,
                  "items": [
                    {
                      "id": "7a8b9c0d-1e2f-4a3b-9c4d-5e6f7a8b9c0d",
                      "facility_id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                      "due_date": "2026-11-30",
                      "principal_due": "1000000",
                      "interest_or_margin_due": "15000",
                      "fees_due": "0",
                      "amount_paid": "250000",
                      "total_due": "1015000",
                      "outstanding": "765000",
                      "currency": "XOF",
                      "status": "PARTIALLY_PAID"
                    }
                  ],
                  "next_cursor": null,
                  "has_more": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:repayments:read"
            ]
          },
          {
            "bearer": [
              "bank:repayments:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:repayments:read"
        ]
      }
    },
    "/bank/facilities/{facility_id}/reconciliations": {
      "post": {
        "tags": [
          "bank"
        ],
        "summary": "Enregistrer un rapprochement",
        "description": "Compare l'encours dérivé à celui annoncé par la banque ; un écart crée une exception, rien n'est corrigé.\n\nScopes requis : `bank:reconciliation:write`.",
        "operationId": "bankCreateReconciliation",
        "parameters": [
          {
            "name": "facility_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReconciliationIn"
              },
              "example": {
                "reported_outstanding": "12355000",
                "as_of": "2026-11-02",
                "matched_on": {
                  "statement": "REL-2026-11"
                },
                "reason": "Relevé de fin de mois"
              }
            }
          },
          "description": "Encours annoncé par la banque à une date donnée (``as_of`` obligatoire, jamais défaulté)."
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankReconciliationOut"
                },
                "example": {
                  "id": "9b0c1d2e-3f4a-4b5c-8d6e-7f8a9b0c1d2e",
                  "facility_id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                  "as_of": "2026-11-02",
                  "expected_outstanding": "12205000",
                  "reported_outstanding": "12355000",
                  "difference": "-150000",
                  "currency": "XOF",
                  "status": "EXCEPTION",
                  "matched_on": {
                    "statement": "REL-2026-11"
                  },
                  "reason": "Relevé de fin de mois",
                  "resolution_note": null,
                  "resolved_at": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:reconciliation:write"
            ]
          },
          {
            "bearer": [
              "bank:reconciliation:write"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:reconciliation:write"
        ]
      }
    },
    "/bank/reconciliations/exceptions": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lister les écarts de rapprochement",
        "description": "Écarts ouverts de l'institution, du plus ancien au plus récent (``ledger.exceptions``).\n\nScopes requis : `bank:repayments:read`.",
        "operationId": "bankListReconciliationExceptions",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "Taille de page, de 1 à 200.",
              "default": 50,
              "title": "Limit"
            },
            "description": "Taille de page, de 1 à 200."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2048
                },
                {
                  "type": "null"
                }
              ],
              "description": "Curseur opaque rendu par la page précédente (next_cursor), lié à la liste et aux filtres.",
              "title": "Cursor"
            },
            "description": "Curseur opaque rendu par la page précédente (next_cursor), lié à la liste et aux filtres."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankReconciliationExceptionsOut"
                },
                "example": {
                  "total": 1,
                  "items": [
                    {
                      "id": "9b0c1d2e-3f4a-4b5c-8d6e-7f8a9b0c1d2e",
                      "facility_id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                      "as_of": "2026-11-02",
                      "expected_outstanding": "12205000",
                      "reported_outstanding": "12355000",
                      "difference": "-150000",
                      "currency": "XOF",
                      "status": "EXCEPTION",
                      "matched_on": {
                        "statement": "REL-2026-11"
                      },
                      "reason": "Relevé de fin de mois",
                      "resolution_note": null,
                      "resolved_at": null
                    }
                  ],
                  "next_cursor": null,
                  "has_more": false
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:repayments:read"
            ]
          },
          {
            "bearer": [
              "bank:repayments:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:repayments:read"
        ]
      }
    },
    "/bank/reconciliations/{reconciliation_id}/resolve": {
      "post": {
        "tags": [
          "bank"
        ],
        "summary": "Résoudre un écart de rapprochement",
        "description": "Clôt une exception en disant ce qui l'expliquait ; l'écart n'est jamais effacé.\n\nScopes requis : `bank:reconciliation:write`.",
        "operationId": "bankResolveReconciliation",
        "parameters": [
          {
            "name": "reconciliation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Clé d'idempotence choisie par l'appelant (255 caractères ASCII au plus), conservée 24 h : un rejeu identique rend la réponse d'origine (Idempotent-Replayed: true), un corps différent 422 idempotency_key_reused, un appel concurrent 409 idempotency_in_progress.",
            "example": "7f3c2a9e-commande-0042"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolutionIn"
              },
              "example": {
                "note": "Virement du 31/10 non encore comptabilisé."
              }
            }
          },
          "description": ""
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankReconciliationOut"
                },
                "example": {
                  "id": "9b0c1d2e-3f4a-4b5c-8d6e-7f8a9b0c1d2e",
                  "facility_id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                  "as_of": "2026-11-02",
                  "expected_outstanding": "12205000",
                  "reported_outstanding": "12355000",
                  "difference": "-150000",
                  "currency": "XOF",
                  "status": "EXCEPTION",
                  "matched_on": {
                    "statement": "REL-2026-11"
                  },
                  "reason": "Relevé de fin de mois",
                  "resolution_note": null,
                  "resolved_at": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "409": {
            "description": "Requête idempotente en cours",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#idempotency_in_progress",
                  "title": "Requête idempotente en cours",
                  "status": 409,
                  "detail": "Une requête avec cette clé d'idempotence est en cours.",
                  "instance": "/public/v1/invoices",
                  "code": "idempotency_in_progress",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "413": {
            "description": "Corps de requête trop volumineux",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#payload_too_large",
                  "title": "Corps de requête trop volumineux",
                  "status": 413,
                  "detail": "Corps de requête limité à 1 Mo.",
                  "instance": "/public/v1/invoices",
                  "code": "payload_too_large",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "415": {
            "description": "Type de contenu non pris en charge",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unsupported_media_type",
                  "title": "Type de contenu non pris en charge",
                  "status": 415,
                  "detail": "Corps JSON attendu (Content-Type: application/json).",
                  "instance": "/public/v1/invoices",
                  "code": "unsupported_media_type",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:reconciliation:write"
            ]
          },
          {
            "bearer": [
              "bank:reconciliation:write"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:reconciliation:write"
        ]
      }
    },
    "/bank/collateral": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lister les garanties",
        "description": "Garanties au bénéfice de l'institution (``collateral_lecture.lister_garanties``), alertes comprises.\n\nChaque ligne et la réponse portent ``avertissement_juridique`` : une donnée Tauraco\nn'est jamais la preuve juridique définitive d'une sûreté opposable.\n\nScopes requis : `bank:collateral:read`.",
        "operationId": "bankListGuarantees",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 48
                },
                {
                  "type": "null"
                }
              ],
              "description": "Type de garantie (par exemple NANTISSEMENT).",
              "title": "Type"
            },
            "description": "Type de garantie (par exemple NANTISSEMENT)."
          },
          {
            "name": "business_status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 48
                },
                {
                  "type": "null"
                }
              ],
              "description": "Statut métier de la garantie.",
              "title": "Business Status"
            },
            "description": "Statut métier de la garantie."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 2
                },
                {
                  "type": "null"
                }
              ],
              "description": "Pays de la garantie (ISO 3166-1 alpha-2).",
              "title": "Country"
            },
            "description": "Pays de la garantie (ISO 3166-1 alpha-2)."
          },
          {
            "name": "with_alert",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Seulement les garanties qui portent une alerte (true) ou aucune (false).",
              "title": "With Alert"
            },
            "description": "Seulement les garanties qui portent une alerte (true) ou aucune (false)."
          },
          {
            "name": "expiring_before",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Garanties dont la péremption tombe au plus tard à cette date.",
              "title": "Expiring Before"
            },
            "description": "Garanties dont la péremption tombe au plus tard à cette date."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "Taille de page, de 1 à 200.",
              "default": 50,
              "title": "Limit"
            },
            "description": "Taille de page, de 1 à 200."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GuaranteesOut"
                },
                "example": {
                  "total": 1,
                  "truncated": false,
                  "items": [
                    {
                      "guarantee_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "type": "NANTISSEMENT",
                      "nature": "REELLE",
                      "country": "SN",
                      "regime_code": "OHADA_NANT_CREANCE_V2010",
                      "business_status": "projet",
                      "deed_date": "2026-03-02",
                      "expiry_date": "2031-03-02",
                      "grantor": "PME Exemple SARL",
                      "beneficiary": "Banque Exemple SA",
                      "security_agent": null,
                      "asset_ids": [
                        "5f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c"
                      ],
                      "obligations": [
                        {
                          "obligation_id": "3d4e5f6a-7b8c-4d9e-af0a-1b2c3d4e5f6a",
                          "obligation_type": "avance",
                          "amount": "9000000",
                          "currency": "XOF",
                          "due_date": "2026-06-30",
                          "status": "en_cours",
                          "settled_amount": "0",
                          "outstanding": "9000000"
                        }
                      ],
                      "alerts": [
                        {
                          "alert_id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                          "type": "PEREMPTION_INSCRIPTION",
                          "severity": "AVERTISSEMENT",
                          "status": "OPEN"
                        }
                      ],
                      "competent_registry": "Registre du commerce et du crédit mobilier (exemple)",
                      "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi."
                    }
                  ],
                  "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi."
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:collateral:read"
            ]
          },
          {
            "bearer": [
              "bank:collateral:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:collateral:read"
        ]
      }
    },
    "/bank/collateral/{guarantee_id}": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lire une garantie",
        "description": "Fiche d'une garantie pour son bénéficiaire (``workflow.vue_financeur``), **sans** ``dossier_prive``.\n\nScopes requis : `bank:collateral:read`.",
        "operationId": "bankGetGuarantee",
        "parameters": [
          {
            "name": "guarantee_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Date d'évaluation de la garantie ; aujourd'hui par défaut.",
              "title": "As Of"
            },
            "description": "Date d'évaluation de la garantie ; aujourd'hui par défaut."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GuaranteeDetailOut"
                },
                "example": {
                  "guarantee_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                  "as_of": "2026-11-04",
                  "evaluation": {
                    "garantie_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                    "as_of": "2026-11-04",
                    "source_juridique": "DEMO_FICTIF",
                    "etats": {
                      "opposable_aux_tiers": {
                        "subject": "opposable_aux_tiers",
                        "status": "EVALUATED",
                        "value": true,
                        "evaluated_as_of": "2026-11-04"
                      }
                    }
                  },
                  "obligations": [
                    {
                      "obligation_id": "3d4e5f6a-7b8c-4d9e-af0a-1b2c3d4e5f6a",
                      "obligation_type": "avance",
                      "amount": "9000000",
                      "currency": "XOF",
                      "due_date": "2026-06-30",
                      "status": "en_cours",
                      "settled_amount": "0",
                      "outstanding": "9000000"
                    }
                  ],
                  "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi.",
                  "links": {
                    "self": "https://api.tauraco.io/public/v1/bank/collateral/1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:collateral:read"
            ]
          },
          {
            "bearer": [
              "bank:collateral:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:collateral:read"
        ]
      }
    },
    "/bank/collateral/{guarantee_id}/events": {
      "get": {
        "tags": [
          "bank"
        ],
        "summary": "Lister la chronologie d'une garantie",
        "description": "Chronologie des événements et de leurs preuves (``collateral_lecture.evenements_garantie``).\n\nScopes requis : `bank:collateral:read`.",
        "operationId": "bankListGuaranteeEvents",
        "parameters": [
          {
            "name": "guarantee_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Identifiant de la ressource (UUID) ; un identifiant inconnu, mal formé ou d'une autre entreprise rend 404.",
            "example": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GuaranteeEventsOut"
                },
                "example": {
                  "guarantee_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                  "events": [
                    {
                      "event_id": "6a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d",
                      "type": "inscription_rccm",
                      "effective_date": "2026-03-09",
                      "recorded_date": "2026-03-10",
                      "actor": "Banque Exemple SA",
                      "comment": null,
                      "proof_expected_missing": false,
                      "proofs": [
                        {
                          "proof_id": "8c9d0e1f-2a3b-4c4d-8e5f-6a7b8c9d0e1f",
                          "nature": "recepisse_rccm",
                          "external_number": "RCCM-EX-2026-0001",
                          "issuer": null,
                          "registry_office": "Greffe du tribunal de commerce (exemple)",
                          "document_date": "2026-03-09",
                          "version": 1,
                          "replaces_proof_id": null,
                          "document_available": true,
                          "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c"
                        }
                      ]
                    }
                  ],
                  "deeds": [
                    {
                      "deed_id": "0e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
                      "status": "SIGNE",
                      "template_code": "COLLATERAL_ACTE_GENERIQUE_V1",
                      "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c",
                      "document_available": true,
                      "created_at": "2026-03-02T10:00:00Z"
                    }
                  ],
                  "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi."
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Identifiant de corrélation de la requête.",
                "schema": {
                  "type": "string"
                }
              },
              "Tauraco-Version": {
                "description": "Version de l'API qui a servi la réponse.",
                "schema": {
                  "type": "string",
                  "example": "2026-11-01"
                }
              },
              "RateLimit-Limit": {
                "description": "Requêtes admises par minute pour l'application.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requêtes restantes dans la minute en cours.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Secondes avant la remise à zéro du seau.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Limit": {
                "description": "Quota journalier de l'application (jour UTC).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Quota-Remaining": {
                "description": "Requêtes restantes dans le quota du jour (omis sur un refus de débit).",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#invalid_request",
                  "title": "Requête invalide",
                  "status": 400,
                  "detail": "Paramètre invalide : sort.",
                  "instance": "/public/v1/invoices",
                  "code": "invalid_request",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "sort",
                      "message": "paramètre inconnu pour cette opération"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentification requise",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#unauthenticated",
                  "title": "Authentification requise",
                  "status": 401,
                  "detail": "Jeton d'accès absent.",
                  "instance": "/public/v1/invoices",
                  "code": "unauthenticated",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Scope insuffisant",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope",
                  "title": "Scope insuffisant",
                  "status": 403,
                  "detail": "Le jeton ne porte pas le scope requis.",
                  "instance": "/public/v1/invoices",
                  "code": "insufficient_scope",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "required_scopes": [
                    "invoices:read"
                  ]
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer realm=\"tauraco\", error=…, scope=…, resource_metadata=…",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Ressource introuvable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#not_found",
                  "title": "Ressource introuvable",
                  "status": 404,
                  "detail": "Ressource introuvable",
                  "instance": "/public/v1/invoices",
                  "code": "not_found",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "422": {
            "description": "Données invalides",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#validation_failed",
                  "title": "Données invalides",
                  "status": 422,
                  "detail": "Filtres invalides.",
                  "instance": "/public/v1/invoices",
                  "code": "validation_failed",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "errors": [
                    {
                      "field": "created_after",
                      "message": "date et heure ISO 8601 attendue"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Trop de requêtes",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#rate_limited",
                  "title": "Trop de requêtes",
                  "status": 429,
                  "detail": "Trop de requêtes",
                  "instance": "/public/v1/invoices",
                  "code": "rate_limited",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 12
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#internal_error",
                  "title": "Erreur interne",
                  "status": 500,
                  "detail": "Erreur interne",
                  "instance": "/public/v1/invoices",
                  "code": "internal_error",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d"
                }
              }
            }
          },
          "503": {
            "description": "Service momentanément indisponible",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://docs.tauraco.ai/developers/erreurs#service_unavailable",
                  "title": "Service momentanément indisponible",
                  "status": 503,
                  "detail": "Service momentanément indisponible",
                  "instance": "/public/v1/invoices",
                  "code": "service_unavailable",
                  "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
                  "retry_after": 30
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Secondes avant de réessayer.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "oauth2": [
              "bank:collateral:read"
            ]
          },
          {
            "bearer": [
              "bank:collateral:read"
            ]
          }
        ],
        "x-required-scopes": [
          "bank:collateral:read"
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AccountList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/AccountOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "AccountList",
        "description": "Page de comptes.",
        "examples": [
          {
            "data": [
              {
                "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                "code": "411100",
                "name": "Clients",
                "name_en": "Customers",
                "account_class": "4",
                "parent_code": "411",
                "is_detail": true,
                "active": true,
                "balance": "118000",
                "currency": "XOF"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "AccountOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Numéro de compte (Account number)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Intitulé (Name)."
          },
          "name_en": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name En",
            "description": "Intitulé (anglais) (Name (English))."
          },
          "account_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Class",
            "description": "Classe (Class).",
            "x-enum-values": [
              "1",
              "2",
              "3",
              "4",
              "5",
              "6",
              "7",
              "8",
              "9"
            ]
          },
          "parent_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Code",
            "description": "Compte parent (Parent account)."
          },
          "is_detail": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Detail",
            "description": "Compte de détail (Detail account)."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "Actif (Active)."
          },
          "balance": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Balance",
            "description": "Solde (Balance)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "name_en",
          "account_class",
          "parent_code",
          "is_detail",
          "active",
          "balance",
          "currency"
        ],
        "title": "AccountOut",
        "description": "Un compte du plan comptable.",
        "examples": [
          {
            "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
            "code": "411100",
            "name": "Clients",
            "name_en": "Customers",
            "account_class": "4",
            "parent_code": "411",
            "is_detail": true,
            "active": true,
            "balance": "118000",
            "currency": "XOF"
          }
        ],
        "x-tauraco-dataset": "accounts"
      },
      "BankCapabilitiesOut": {
        "properties": {
          "read": {
            "type": "boolean",
            "title": "Read"
          },
          "instruct": {
            "type": "boolean",
            "title": "Instruct"
          },
          "decide": {
            "type": "boolean",
            "title": "Decide"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "read",
          "instruct",
          "decide"
        ],
        "title": "BankCapabilitiesOut",
        "examples": [
          {
            "read": true,
            "instruct": true,
            "decide": false
          }
        ]
      },
      "BankDocumentOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "file_name": {
            "type": "string",
            "title": "File Name"
          },
          "content_type": {
            "type": "string",
            "title": "Content Type"
          },
          "size_bytes": {
            "type": "integer",
            "title": "Size Bytes"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "uploaded_by_side": {
            "type": "string",
            "title": "Uploaded By Side"
          },
          "reserved_for_institution": {
            "type": "boolean",
            "title": "Reserved For Institution"
          },
          "sha256": {
            "type": "string",
            "title": "Sha256"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
          },
          "links": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Links"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "file_name",
          "content_type",
          "size_bytes",
          "uploaded_by_side",
          "reserved_for_institution",
          "sha256",
          "created_at",
          "links"
        ],
        "title": "BankDocumentOut",
        "examples": [
          {
            "id": "2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c",
            "file_name": "facture.pdf",
            "content_type": "application/pdf",
            "size_bytes": 182340,
            "label": "Facture",
            "uploaded_by_side": "COMPANY",
            "reserved_for_institution": false,
            "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c",
            "created_at": "2026-11-02T09:25:00Z",
            "links": {
              "content": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f/documents/2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c/content"
            }
          }
        ]
      },
      "BankDocumentsOut": {
        "properties": {
          "request_id": {
            "type": "string",
            "title": "Request Id"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/BankDocumentOut"
            },
            "type": "array",
            "title": "Items"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "request_id",
          "items"
        ],
        "title": "BankDocumentsOut",
        "examples": [
          {
            "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
            "items": [
              {
                "id": "2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c",
                "file_name": "facture.pdf",
                "content_type": "application/pdf",
                "size_bytes": 182340,
                "label": "Facture",
                "uploaded_by_side": "COMPANY",
                "reserved_for_institution": false,
                "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c",
                "created_at": "2026-11-02T09:25:00Z",
                "links": {
                  "content": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f/documents/2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c/content"
                }
              }
            ]
          }
        ]
      },
      "BankFacilitiesOut": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/BankFacilityOut"
            },
            "type": "array",
            "title": "Items"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor"
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "items",
          "has_more"
        ],
        "title": "BankFacilitiesOut",
        "examples": [
          {
            "items": [
              {
                "id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                "facility_type": "RECEIVABLES_FACILITY",
                "country": "SN",
                "currency": "XOF",
                "facility_limit": "50000000",
                "committed_limit": "50000000",
                "utilized_amount": "12000000",
                "available_limit": "38000000",
                "status": "ACTIVE",
                "borrowing_base_required": true,
                "effective_from": "2026-01-01",
                "effective_to": "2026-12-31",
                "principal_outstanding": "12000000",
                "interest_and_margin_outstanding": "180000",
                "fees_outstanding": "25000",
                "total_outstanding": "12205000"
              }
            ],
            "next_cursor": null,
            "has_more": false
          }
        ]
      },
      "BankFacilityOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "facility_type": {
            "type": "string",
            "title": "Facility Type"
          },
          "country": {
            "type": "string",
            "title": "Country"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "facility_limit": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Facility Limit"
          },
          "committed_limit": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Committed Limit"
          },
          "utilized_amount": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Utilized Amount"
          },
          "available_limit": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Available Limit"
          },
          "status": {
            "type": "string",
            "title": "Status"
          },
          "borrowing_base_required": {
            "type": "boolean",
            "title": "Borrowing Base Required"
          },
          "effective_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Effective From"
          },
          "effective_to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Effective To"
          },
          "principal_outstanding": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Principal Outstanding"
          },
          "interest_and_margin_outstanding": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Interest And Margin Outstanding"
          },
          "fees_outstanding": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Fees Outstanding"
          },
          "total_outstanding": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Total Outstanding"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "facility_type",
          "country",
          "currency",
          "facility_limit",
          "committed_limit",
          "utilized_amount",
          "available_limit",
          "status",
          "borrowing_base_required",
          "principal_outstanding",
          "interest_and_margin_outstanding",
          "fees_outstanding",
          "total_outstanding"
        ],
        "title": "BankFacilityOut",
        "examples": [
          {
            "id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
            "facility_type": "RECEIVABLES_FACILITY",
            "country": "SN",
            "currency": "XOF",
            "facility_limit": "50000000",
            "committed_limit": "50000000",
            "utilized_amount": "12000000",
            "available_limit": "38000000",
            "status": "ACTIVE",
            "borrowing_base_required": true,
            "effective_from": "2026-01-01",
            "effective_to": "2026-12-31",
            "principal_outstanding": "12000000",
            "interest_and_margin_outstanding": "180000",
            "fees_outstanding": "25000",
            "total_outstanding": "12205000"
          }
        ]
      },
      "BankInboxItemOut": {
        "properties": {
          "request_id": {
            "type": "string",
            "title": "Request Id"
          },
          "company_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Company Name"
          },
          "debtor_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Debtor Name"
          },
          "amount_requested": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount Requested"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency"
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "product": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product"
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country"
          },
          "verification_level": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Verification Level"
          },
          "recipient_status": {
            "type": "string",
            "title": "Recipient Status"
          },
          "request_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Request Status"
          },
          "received_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Received At"
          },
          "source_changed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Changed"
          },
          "my_offer_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "My Offer Id"
          },
          "my_offer_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "My Offer Status"
          },
          "links": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LinksOut"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "request_id",
          "recipient_status"
        ],
        "title": "BankInboxItemOut",
        "description": "Ligne de la boîte de réception.\n\nPour une demande que l'institution a **déclinée** (``recipient_status = DECLINED``),\nseuls ``request_id``, ``recipient_status`` et ``received_at`` sont servis : tous les\nchamps métier (entreprise, débiteur, montant, échéance, statut de la demande…) et\n``links`` valent ``null``, comme le dossier lui répond 404 (PLAN lot 2C, j.19). La\nligne reste comptée, pour que ``total`` et la pagination ne bougent pas.",
        "examples": [
          {
            "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
            "company_name": "PME Exemple SARL",
            "debtor_name": "Acheteur Exemple SA",
            "amount_requested": "1000000",
            "currency": "XOF",
            "due_date": "2026-12-31",
            "product": "INVOICE_FINANCING",
            "country": "SN",
            "verification_level": "DOCUMENT_VERIFIE",
            "recipient_status": "SENT",
            "request_status": "SUBMITTED",
            "received_at": "2026-11-02T09:30:00Z",
            "source_changed": false,
            "my_offer_id": null,
            "my_offer_status": null,
            "links": {
              "self": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f"
            }
          }
        ]
      },
      "BankInboxOut": {
        "properties": {
          "institution": {
            "$ref": "#/components/schemas/InstitutionOut"
          },
          "counters": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Counters"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/BankInboxItemOut"
            },
            "type": "array",
            "title": "Items"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor"
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "institution",
          "counters",
          "total",
          "items",
          "has_more"
        ],
        "title": "BankInboxOut",
        "examples": [
          {
            "institution": {
              "tenant_id": "t_banque_exemple",
              "name": "Banque Exemple SA"
            },
            "counters": {
              "new": 1,
              "in_review": 0,
              "information_requested": 0,
              "offer_submitted": 0,
              "closed": 0
            },
            "total": 1,
            "items": [
              {
                "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
                "company_name": "PME Exemple SARL",
                "debtor_name": "Acheteur Exemple SA",
                "amount_requested": "1000000",
                "currency": "XOF",
                "due_date": "2026-12-31",
                "product": "INVOICE_FINANCING",
                "country": "SN",
                "verification_level": "DOCUMENT_VERIFIE",
                "recipient_status": "SENT",
                "request_status": "SUBMITTED",
                "received_at": "2026-11-02T09:30:00Z",
                "source_changed": false,
                "my_offer_id": null,
                "my_offer_status": null,
                "links": {
                  "self": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f"
                }
              }
            ],
            "next_cursor": null,
            "has_more": false
          }
        ]
      },
      "BankInformationRequestOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "kind": {
            "type": "string",
            "title": "Kind"
          },
          "side": {
            "type": "string",
            "title": "Side"
          },
          "text": {
            "type": "string",
            "title": "Text"
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id"
          },
          "parent_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Id"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
          },
          "resolved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolved At"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "kind",
          "side",
          "text",
          "created_at"
        ],
        "title": "BankInformationRequestOut",
        "examples": [
          {
            "id": "6d7e8f90-a1b2-4c3d-8e4f-5a6b7c8d9e0f",
            "kind": "DOCUMENT_REQUEST",
            "side": "INSTITUTION",
            "text": "Merci de joindre le bon de commande signé.",
            "document_id": null,
            "parent_id": null,
            "created_at": "2026-11-03T08:15:00Z",
            "resolved_at": null
          }
        ]
      },
      "BankInformationRequestsOut": {
        "properties": {
          "request_id": {
            "type": "string",
            "title": "Request Id"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/BankInformationRequestOut"
            },
            "type": "array",
            "title": "Items"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "request_id",
          "items"
        ],
        "title": "BankInformationRequestsOut",
        "examples": [
          {
            "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
            "items": [
              {
                "id": "6d7e8f90-a1b2-4c3d-8e4f-5a6b7c8d9e0f",
                "kind": "DOCUMENT_REQUEST",
                "side": "INSTITUTION",
                "text": "Merci de joindre le bon de commande signé.",
                "document_id": null,
                "parent_id": null,
                "created_at": "2026-11-03T08:15:00Z",
                "resolved_at": null
              }
            ]
          }
        ]
      },
      "BankOfferOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "version": {
            "type": "integer",
            "title": "Version"
          },
          "status": {
            "type": "string",
            "title": "Status"
          },
          "amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency"
          },
          "duration_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Duration Days"
          },
          "valid_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid Until"
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "version",
          "status"
        ],
        "title": "BankOfferOut",
        "description": "Offre courante de **cette** institution (jamais celle d'une concurrente).",
        "examples": [
          {
            "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
            "version": 1,
            "status": "SUBMITTED",
            "amount": "950000",
            "currency": "XOF",
            "duration_days": 60,
            "valid_until": "2026-11-30",
            "submitted_at": "2026-11-03T10:00:00Z"
          }
        ]
      },
      "BankReconciliationExceptionsOut": {
        "properties": {
          "total": {
            "type": "integer",
            "title": "Total"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/BankReconciliationOut"
            },
            "type": "array",
            "title": "Items"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor"
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "total",
          "items",
          "has_more"
        ],
        "title": "BankReconciliationExceptionsOut",
        "examples": [
          {
            "total": 1,
            "items": [
              {
                "id": "9b0c1d2e-3f4a-4b5c-8d6e-7f8a9b0c1d2e",
                "facility_id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                "as_of": "2026-11-02",
                "expected_outstanding": "12205000",
                "reported_outstanding": "12355000",
                "difference": "-150000",
                "currency": "XOF",
                "status": "EXCEPTION",
                "matched_on": {
                  "statement": "REL-2026-11"
                },
                "reason": "Relevé de fin de mois",
                "resolution_note": null,
                "resolved_at": null
              }
            ],
            "next_cursor": null,
            "has_more": false
          }
        ]
      },
      "BankReconciliationOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "facility_id": {
            "type": "string",
            "title": "Facility Id"
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of"
          },
          "expected_outstanding": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Expected Outstanding"
          },
          "reported_outstanding": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Reported Outstanding"
          },
          "difference": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Difference"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "status": {
            "type": "string",
            "title": "Status"
          },
          "matched_on": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Matched On"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason"
          },
          "resolution_note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolution Note"
          },
          "resolved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolved At"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "facility_id",
          "as_of",
          "expected_outstanding",
          "reported_outstanding",
          "difference",
          "currency",
          "status"
        ],
        "title": "BankReconciliationOut",
        "examples": [
          {
            "id": "9b0c1d2e-3f4a-4b5c-8d6e-7f8a9b0c1d2e",
            "facility_id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
            "as_of": "2026-11-02",
            "expected_outstanding": "12205000",
            "reported_outstanding": "12355000",
            "difference": "-150000",
            "currency": "XOF",
            "status": "EXCEPTION",
            "matched_on": {
              "statement": "REL-2026-11"
            },
            "reason": "Relevé de fin de mois",
            "resolution_note": null,
            "resolved_at": null
          }
        ]
      },
      "BankRepaymentOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "facility_id": {
            "type": "string",
            "title": "Facility Id"
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date"
          },
          "principal_due": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Principal Due"
          },
          "interest_or_margin_due": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Interest Or Margin Due"
          },
          "fees_due": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Fees Due"
          },
          "amount_paid": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Amount Paid"
          },
          "total_due": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Total Due"
          },
          "outstanding": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Outstanding"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "status": {
            "type": "string",
            "title": "Status"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "facility_id",
          "due_date",
          "principal_due",
          "interest_or_margin_due",
          "fees_due",
          "amount_paid",
          "total_due",
          "outstanding",
          "currency",
          "status"
        ],
        "title": "BankRepaymentOut",
        "examples": [
          {
            "id": "7a8b9c0d-1e2f-4a3b-9c4d-5e6f7a8b9c0d",
            "facility_id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
            "due_date": "2026-11-30",
            "principal_due": "1000000",
            "interest_or_margin_due": "15000",
            "fees_due": "0",
            "amount_paid": "250000",
            "total_due": "1015000",
            "outstanding": "765000",
            "currency": "XOF",
            "status": "PARTIALLY_PAID"
          }
        ]
      },
      "BankRepaymentsOut": {
        "properties": {
          "total": {
            "type": "integer",
            "title": "Total"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/BankRepaymentOut"
            },
            "type": "array",
            "title": "Items"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor"
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "total",
          "items",
          "has_more"
        ],
        "title": "BankRepaymentsOut",
        "examples": [
          {
            "total": 1,
            "items": [
              {
                "id": "7a8b9c0d-1e2f-4a3b-9c4d-5e6f7a8b9c0d",
                "facility_id": "4e5f6a7b-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
                "due_date": "2026-11-30",
                "principal_due": "1000000",
                "interest_or_margin_due": "15000",
                "fees_due": "0",
                "amount_paid": "250000",
                "total_due": "1015000",
                "outstanding": "765000",
                "currency": "XOF",
                "status": "PARTIALLY_PAID"
              }
            ],
            "next_cursor": null,
            "has_more": false
          }
        ]
      },
      "BankRequestOut": {
        "properties": {
          "request_id": {
            "type": "string",
            "title": "Request Id"
          },
          "request_status": {
            "type": "string",
            "title": "Request Status"
          },
          "recipient_status": {
            "type": "string",
            "title": "Recipient Status"
          },
          "product": {
            "type": "string",
            "title": "Product"
          },
          "country": {
            "type": "string",
            "title": "Country"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "amount_requested": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Amount Requested"
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At"
          },
          "received_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Received At"
          },
          "viewed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Viewed At"
          },
          "snapshot": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Snapshot"
          },
          "source_changed": {
            "type": "boolean",
            "title": "Source Changed"
          },
          "source_change_detail": {
            "title": "Source Change Detail"
          },
          "asset_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asset Id"
          },
          "my_offer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BankOfferOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "capabilities": {
            "$ref": "#/components/schemas/BankCapabilitiesOut"
          },
          "timeline": {
            "items": {
              "$ref": "#/components/schemas/BankTimelineEventOut"
            },
            "type": "array",
            "title": "Timeline"
          },
          "documents": {
            "items": {
              "$ref": "#/components/schemas/BankDocumentOut"
            },
            "type": "array",
            "title": "Documents"
          },
          "information_requests": {
            "items": {
              "$ref": "#/components/schemas/BankInformationRequestOut"
            },
            "type": "array",
            "title": "Information Requests"
          },
          "links": {
            "$ref": "#/components/schemas/LinksOut"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "request_id",
          "request_status",
          "recipient_status",
          "product",
          "country",
          "currency",
          "amount_requested",
          "source_changed",
          "capabilities",
          "timeline",
          "documents",
          "information_requests",
          "links"
        ],
        "title": "BankRequestOut",
        "description": "Dossier tel qu'il a été soumis (snapshot figé), et l'état de la relation avec l'institution.",
        "examples": [
          {
            "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
            "request_status": "OFFERS_RECEIVED",
            "recipient_status": "OFFER_SUBMITTED",
            "product": "INVOICE_FINANCING",
            "country": "SN",
            "currency": "XOF",
            "amount_requested": "1000000",
            "submitted_at": "2026-11-02T09:30:00Z",
            "received_at": "2026-11-02T09:30:00Z",
            "viewed_at": "2026-11-02T11:02:00Z",
            "snapshot": {
              "version": 1,
              "pris_le": "2026-11-02T09:30:00Z",
              "pays": "SN",
              "facture": {
                "numero": "F-2026-0042",
                "date_emission": "2026-10-20",
                "echeance": "2026-12-31",
                "devise": "XOF",
                "montant_ht": 1000000,
                "montant_taxes": 0,
                "montant_total": 1000000,
                "montant_regle": 0,
                "statut": "SENT"
              },
              "cedant": {
                "denomination": "PME Exemple SARL",
                "pays": "SN"
              },
              "debiteur": {
                "denomination": "Acheteur Exemple SA",
                "pays": "SN"
              },
              "verification": {
                "niveau": "DOCUMENT_VERIFIE"
              }
            },
            "source_changed": false,
            "source_change_detail": null,
            "asset_id": null,
            "my_offer": {
              "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
              "version": 1,
              "status": "SUBMITTED",
              "amount": "950000",
              "currency": "XOF",
              "duration_days": 60,
              "valid_until": "2026-11-30",
              "submitted_at": "2026-11-03T10:00:00Z"
            },
            "capabilities": {
              "read": true,
              "instruct": true,
              "decide": false
            },
            "timeline": [
              {
                "type": "REQUEST_SUBMITTED",
                "occurred_at": "2026-11-02T09:30:00Z",
                "side": "COMPANY",
                "detail": {
                  "destinataires": 2,
                  "niveau_verification": "DOCUMENT_VERIFIE"
                }
              }
            ],
            "documents": [
              {
                "id": "2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c",
                "file_name": "facture.pdf",
                "content_type": "application/pdf",
                "size_bytes": 182340,
                "label": "Facture",
                "uploaded_by_side": "COMPANY",
                "reserved_for_institution": false,
                "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c",
                "created_at": "2026-11-02T09:25:00Z",
                "links": {
                  "content": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f/documents/2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c/content"
                }
              }
            ],
            "information_requests": [
              {
                "id": "6d7e8f90-a1b2-4c3d-8e4f-5a6b7c8d9e0f",
                "kind": "DOCUMENT_REQUEST",
                "side": "INSTITUTION",
                "text": "Merci de joindre le bon de commande signé.",
                "document_id": null,
                "parent_id": null,
                "created_at": "2026-11-03T08:15:00Z",
                "resolved_at": null
              }
            ],
            "links": {
              "self": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f"
            }
          }
        ]
      },
      "BankTimelineEventOut": {
        "properties": {
          "type": {
            "type": "string",
            "title": "Type"
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "title": "Occurred At"
          },
          "side": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Side"
          },
          "detail": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Detail"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "type",
          "occurred_at"
        ],
        "title": "BankTimelineEventOut",
        "examples": [
          {
            "type": "REQUEST_SUBMITTED",
            "occurred_at": "2026-11-02T09:30:00Z",
            "side": "COMPANY",
            "detail": {
              "destinataires": 2,
              "niveau_verification": "DOCUMENT_VERIFIE"
            }
          }
        ]
      },
      "BillList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/BillOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "BillList",
        "description": "Page de factures fournisseurs.",
        "examples": [
          {
            "data": [
              {
                "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                "bill_number": "FF-2026-0042",
                "supplier_id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                "issue_date": "2026-01-08",
                "due_date": "2026-02-07",
                "currency": "XOF",
                "subtotal": "250000",
                "tax_total": "45000",
                "total": "295000",
                "amount_paid": "0",
                "status": "APPROVED",
                "approved_at": "2026-01-09T10:00:00Z",
                "created_at": "2026-01-08T11:12:13.000001Z",
                "updated_at": "2026-01-09T10:00:00Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "BillOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "bill_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bill Number",
            "description": "Numéro (Number)."
          },
          "supplier_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Supplier Id",
            "description": "Fournisseur (Supplier)."
          },
          "issue_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Issue Date",
            "description": "Date d'émission (Issue date)."
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "Date d'échéance (Due date)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "subtotal": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtotal",
            "description": "Total HT (Subtotal)."
          },
          "tax_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Total",
            "description": "Total taxes (Tax total)."
          },
          "total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Total TTC (Total)."
          },
          "amount_paid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount Paid",
            "description": "Montant réglé (Amount paid)."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Statut (Status).",
            "x-enum-values": [
              "DRAFT",
              "RECEIVED",
              "APPROVED",
              "PARTIALLY_PAID",
              "PAID",
              "OVERDUE",
              "CANCELLED"
            ]
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "Bon à payer le (Approved at)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créée le (Created at)."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "Modifiée le (Updated at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "bill_number",
          "supplier_id",
          "issue_date",
          "due_date",
          "currency",
          "subtotal",
          "tax_total",
          "total",
          "amount_paid",
          "status",
          "approved_at",
          "created_at",
          "updated_at"
        ],
        "title": "BillOut",
        "description": "Une facture fournisseur.",
        "examples": [
          {
            "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
            "bill_number": "FF-2026-0042",
            "supplier_id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
            "issue_date": "2026-01-08",
            "due_date": "2026-02-07",
            "currency": "XOF",
            "subtotal": "250000",
            "tax_total": "45000",
            "total": "295000",
            "amount_paid": "0",
            "status": "APPROVED",
            "approved_at": "2026-01-09T10:00:00Z",
            "created_at": "2026-01-08T11:12:13.000001Z",
            "updated_at": "2026-01-09T10:00:00Z"
          }
        ],
        "x-tauraco-dataset": "bills"
      },
      "CashMovementList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/CashMovementOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "CashMovementList",
        "description": "Page de mouvements de trésorerie.",
        "examples": [
          {
            "data": [
              {
                "id": "8b9c0d1e-2f3a-4b4c-9d5e-6f7a8b9c0d1e",
                "bank_account_id": "0d1e2f3a-4b5c-4d6e-8f7a-8b9c0d1e2f3a",
                "movement_type": "INFLOW",
                "amount": "118000",
                "currency": "XOF",
                "description": "Encaissement facture FA-2026-0001",
                "reference": "REL-2026-01",
                "movement_date": "2026-01-20",
                "source_type": "billing_payment",
                "source_id": "4d5e6f7a-8b9c-4d0e-a1f2-b3c4d5e6f7a8",
                "created_at": "2026-01-20T14:00:01.000004Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "CashMovementOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "bank_account_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account Id",
            "description": "Compte de trésorerie (Cash account)."
          },
          "movement_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Movement Type",
            "description": "Sens (Direction).",
            "x-enum-values": [
              "INFLOW",
              "OUTFLOW",
              "TRANSFER"
            ]
          },
          "amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "Montant (Amount)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Libellé (Description)."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Référence (Reference)."
          },
          "movement_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Movement Date",
            "description": "Date du mouvement (Movement date)."
          },
          "source_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Type",
            "description": "Origine (Source type)."
          },
          "source_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Id",
            "description": "Pièce d'origine (Source document)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créé le (Created at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "bank_account_id",
          "movement_type",
          "amount",
          "currency",
          "description",
          "reference",
          "movement_date",
          "source_type",
          "source_id",
          "created_at"
        ],
        "title": "CashMovementOut",
        "description": "Un mouvement de trésorerie (entrée, sortie ou virement interne).",
        "examples": [
          {
            "id": "8b9c0d1e-2f3a-4b4c-9d5e-6f7a8b9c0d1e",
            "bank_account_id": "0d1e2f3a-4b5c-4d6e-8f7a-8b9c0d1e2f3a",
            "movement_type": "INFLOW",
            "amount": "118000",
            "currency": "XOF",
            "description": "Encaissement facture FA-2026-0001",
            "reference": "REL-2026-01",
            "movement_date": "2026-01-20",
            "source_type": "billing_payment",
            "source_id": "4d5e6f7a-8b9c-4d0e-a1f2-b3c4d5e6f7a8",
            "created_at": "2026-01-20T14:00:01.000004Z"
          }
        ],
        "x-tauraco-dataset": "cash_movements"
      },
      "CollateralDepotList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/CollateralDepotOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "CollateralDepotList",
        "description": "Page de dépôts (stocks confiés à un tiers détenteur).",
        "examples": [
          {
            "data": [
              {
                "id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
                "type_garantie": "nantissement_stocks",
                "nature": "reelle",
                "pays": "SN",
                "statut_metier": "constituee",
                "date_acte": "2026-01-15",
                "date_peremption": null,
                "created_at": "2026-01-15T08:30:00Z",
                "updated_at": "2026-01-15T08:30:00Z",
                "avertissement_juridique": "Information de suivi : cette ligne constate la remise d'un stock gagé à un tiers détenteur. Elle ne vaut ni inscription au registre compétent, ni preuve de l'opposabilité ou du rang de la sûreté."
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "CollateralDepotOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "type_garantie": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Type Garantie",
            "description": "Type de garantie (Collateral type)."
          },
          "nature": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Nature",
            "description": "Nature (Nature)."
          },
          "pays": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pays",
            "description": "Pays (Country)."
          },
          "statut_metier": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Statut Metier",
            "description": "Statut (Status)."
          },
          "date_acte": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Date Acte",
            "description": "Date de l'acte (Deed date)."
          },
          "date_peremption": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Date Peremption",
            "description": "Date de péremption (Expiry date)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créé le (Created at)."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "Modifié le (Updated at)."
          },
          "avertissement_juridique": {
            "type": "string",
            "title": "Avertissement Juridique",
            "description": "Avertissement juridique (Legal notice)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "type_garantie",
          "nature",
          "pays",
          "statut_metier",
          "date_acte",
          "date_peremption",
          "created_at",
          "updated_at",
          "avertissement_juridique"
        ],
        "title": "CollateralDepotOut",
        "description": "Un dépôt : garantie confiée à un tiers détenteur, constatée (ni inscription, ni preuve de rang).",
        "examples": [
          {
            "id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
            "type_garantie": "nantissement_stocks",
            "nature": "reelle",
            "pays": "SN",
            "statut_metier": "constituee",
            "date_acte": "2026-01-15",
            "date_peremption": null,
            "created_at": "2026-01-15T08:30:00Z",
            "updated_at": "2026-01-15T08:30:00Z",
            "avertissement_juridique": "Information de suivi : cette ligne constate la remise d'un stock gagé à un tiers détenteur. Elle ne vaut ni inscription au registre compétent, ni preuve de l'opposabilité ou du rang de la sûreté."
          }
        ],
        "x-tauraco-dataset": "collateral_depots"
      },
      "CompanyOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Raison sociale (Company name)."
          },
          "legal_form": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Legal Form",
            "description": "Forme juridique (Legal form)."
          },
          "registration_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Registration Number",
            "description": "Immatriculation (RCCM, SIREN) (Registration number)."
          },
          "tax_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Number",
            "description": "Identifiant fiscal (Tax number)."
          },
          "full_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Full Address",
            "description": "Adresse (Address)."
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Pays (Country)."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "Téléphone (Phone)."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail (Email)."
          },
          "website": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Website",
            "description": "Site web (Website)."
          },
          "base_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base Currency",
            "description": "Devise de tenue (Base currency)."
          },
          "accounting_regime": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accounting Regime",
            "description": "Référentiel comptable (Accounting framework)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "name",
          "legal_form",
          "registration_number",
          "tax_number",
          "full_address",
          "country",
          "phone",
          "email",
          "website",
          "base_currency",
          "accounting_regime"
        ],
        "title": "CompanyOut",
        "description": "Profil de l'entreprise du jeton (identité légale et coordonnées professionnelles).",
        "examples": [
          {
            "id": "8d3b6c1e-2f4a-4b7c-9e1d-5a6b7c8d9e0f",
            "name": "Société Exemple SARL",
            "legal_form": "SARL",
            "registration_number": "RB/BKO/2026/B/0001",
            "tax_number": "084000000X",
            "full_address": "Rue 100, Bamako, Mali",
            "country": "ML",
            "phone": "+223 20 00 00 00",
            "email": "contact@exemple.test",
            "website": "https://exemple.test",
            "base_currency": "XOF",
            "accounting_regime": "OHADA"
          }
        ],
        "x-tauraco-dataset": "company"
      },
      "ConnectionList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ConnectionOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "ConnectionList",
        "description": "Connexions du tenant (page unique).",
        "examples": [
          {
            "data": [
              {
                "id": "9d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
                "connector_code": "sftp",
                "name": "SFTP du cabinet",
                "status": "active",
                "last_test_at": "2026-01-05T08:00:00Z",
                "last_test_status": "ok",
                "created_at": "2026-01-04T10:00:00Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "ConnectionOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant de la connexion (UUID)."
          },
          "connector_code": {
            "type": "string",
            "title": "Connector Code",
            "description": "Code du connecteur."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Nom donné par l'entreprise."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "État de la connexion."
          },
          "last_test_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Test At",
            "description": "Dernier test (UTC)."
          },
          "last_test_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Test Status",
            "description": "Résultat du dernier test."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Création (UTC)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "connector_code",
          "name",
          "status",
          "last_test_at",
          "last_test_status",
          "created_at"
        ],
        "title": "ConnectionOut",
        "description": "Une connexion de livraison du tenant (sans configuration ni secret).",
        "examples": [
          {
            "id": "9d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
            "connector_code": "sftp",
            "name": "SFTP du cabinet",
            "status": "active",
            "last_test_at": "2026-01-05T08:00:00Z",
            "last_test_status": "ok",
            "created_at": "2026-01-04T10:00:00Z"
          }
        ]
      },
      "CustomerList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/CustomerOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "CustomerList",
        "description": "Page de clients.",
        "examples": [
          {
            "data": [
              {
                "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                "name": "Client Exemple",
                "legal_name": "Client Exemple SA",
                "city": "Dakar",
                "country": "SN",
                "tax_id": "SN-0000000",
                "siren": null,
                "siret": null,
                "tva_intra": null,
                "currency": "XOF",
                "einvoicing_routing_code": null,
                "created_at": "2026-01-05T08:00:01.007919Z",
                "updated_at": "2026-01-05T08:00:01.007919Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "CustomerOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Nom (Name)."
          },
          "legal_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Legal Name",
            "description": "Raison sociale (Legal name)."
          },
          "city": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "City",
            "description": "Ville (City)."
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Pays (Country)."
          },
          "tax_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Id",
            "description": "Identifiant fiscal (Tax identifier)."
          },
          "siren": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Siren",
            "description": "SIREN (SIREN)."
          },
          "siret": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Siret",
            "description": "SIRET (SIRET)."
          },
          "tva_intra": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tva Intra",
            "description": "TVA intracommunautaire (EU VAT number)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "einvoicing_routing_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Einvoicing Routing Code",
            "description": "Code de routage e-facture (E-invoicing routing code)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créé le (Created at)."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "Modifié le (Updated at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "name",
          "legal_name",
          "city",
          "country",
          "tax_id",
          "siren",
          "siret",
          "tva_intra",
          "currency",
          "einvoicing_routing_code",
          "created_at",
          "updated_at"
        ],
        "title": "CustomerOut",
        "description": "Un client de l'entreprise.",
        "examples": [
          {
            "id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
            "name": "Client Exemple",
            "legal_name": "Client Exemple SA",
            "city": "Dakar",
            "country": "SN",
            "tax_id": "SN-0000000",
            "siren": null,
            "siret": null,
            "tva_intra": null,
            "currency": "XOF",
            "einvoicing_routing_code": null,
            "created_at": "2026-01-05T08:00:01.007919Z",
            "updated_at": "2026-01-05T08:00:01.007919Z"
          }
        ],
        "x-tauraco-dataset": "customers"
      },
      "DatasetColumnOut": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Nom de la colonne."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Libellé."
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "Type logique (string, money, date, datetime…)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "name",
          "label",
          "type"
        ],
        "title": "DatasetColumnOut",
        "description": "Une colonne servie d'un jeu."
      },
      "DatasetFilterOut": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Nom du filtre (paramètre de liste ou clé de filters d'un export)."
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "Type du filtre."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Libellé."
          },
          "required": {
            "type": "boolean",
            "title": "Required",
            "description": "Vrai si le filtre est obligatoire."
          },
          "enum_values": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Enum Values",
            "description": "Valeurs admises (filtre énuméré)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "name",
          "type",
          "label",
          "required",
          "enum_values"
        ],
        "title": "DatasetFilterOut",
        "description": "Un filtre admis par un jeu."
      },
      "DatasetList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/DatasetOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "DatasetList",
        "description": "Jeux exportables par l'application (page unique).",
        "examples": [
          {
            "data": [
              {
                "code": "invoices",
                "module": "billing",
                "label": "Factures clients",
                "scope": "invoices:read",
                "formats": [
                  "csv",
                  "json",
                  "xlsx"
                ],
                "differential": true,
                "columns": [
                  {
                    "name": "number",
                    "label": "Numéro",
                    "type": "string"
                  }
                ],
                "filters": [
                  {
                    "name": "created_after",
                    "type": "datetime",
                    "label": "Créée après",
                    "required": false,
                    "enum_values": null
                  }
                ]
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "DatasetOut": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Code du jeu (datasets[].dataset d'un export)."
          },
          "module": {
            "type": "string",
            "title": "Module",
            "description": "Module métier."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Libellé."
          },
          "scope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scope",
            "description": "Scope de lecture du jeu."
          },
          "formats": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Formats",
            "description": "Formats d'export acceptés pour ce jeu."
          },
          "differential": {
            "type": "boolean",
            "title": "Differential",
            "description": "Vrai si le jeu admet un export différentiel."
          },
          "columns": {
            "items": {
              "$ref": "#/components/schemas/DatasetColumnOut"
            },
            "type": "array",
            "title": "Columns",
            "description": "Colonnes servies (hors données personnelles et bancaires)."
          },
          "filters": {
            "items": {
              "$ref": "#/components/schemas/DatasetFilterOut"
            },
            "type": "array",
            "title": "Filters",
            "description": "Filtres admis."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "code",
          "module",
          "label",
          "scope",
          "formats",
          "differential",
          "columns",
          "filters"
        ],
        "title": "DatasetOut",
        "description": "Un jeu de données exportable par l'application.",
        "examples": [
          {
            "code": "invoices",
            "module": "billing",
            "label": "Factures clients",
            "scope": "invoices:read",
            "formats": [
              "csv",
              "json",
              "xlsx"
            ],
            "differential": true,
            "columns": [
              {
                "name": "number",
                "label": "Numéro",
                "type": "string"
              }
            ],
            "filters": [
              {
                "name": "created_after",
                "type": "datetime",
                "label": "Créée après",
                "required": false,
                "enum_values": null
              }
            ]
          }
        ]
      },
      "DocumentLinks": {
        "properties": {
          "self": {
            "type": "string",
            "title": "Self",
            "description": "Métadonnées de la pièce."
          },
          "content": {
            "type": "string",
            "title": "Content",
            "description": "Contenu de la pièce, en flux."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "self",
          "content"
        ],
        "title": "DocumentLinks",
        "description": "Liens relatifs à la racine de l'API (``/public/v1``)."
      },
      "DocumentList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/DocumentOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "DocumentList",
        "description": "Pièces d'un parent, par date de dépôt.",
        "examples": [
          {
            "data": [
              {
                "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                "parent_type": "financing_request",
                "parent_id": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f",
                "file_name": "bilan-2025.pdf",
                "content_type": "application/pdf",
                "size_bytes": 482133,
                "sha256": "9f2b5c0d4e1a7b3c8d6e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c",
                "label": "Bilan 2025",
                "uploaded_by": "company",
                "reserved_to_one_institution": false,
                "created_at": "2026-01-06T10:02:00Z",
                "links": {
                  "self": "/documents/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                  "content": "/documents/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9/content"
                }
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "DocumentOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant de la pièce (UUID)."
          },
          "parent_type": {
            "type": "string",
            "const": "financing_request",
            "title": "Parent Type",
            "description": "Type du parent."
          },
          "parent_id": {
            "type": "string",
            "title": "Parent Id",
            "description": "Identifiant du parent."
          },
          "file_name": {
            "type": "string",
            "title": "File Name",
            "description": "Nom du fichier déposé."
          },
          "content_type": {
            "type": "string",
            "title": "Content Type",
            "description": "Type MIME déclaré au dépôt."
          },
          "size_bytes": {
            "type": "integer",
            "title": "Size Bytes",
            "description": "Taille en octets."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "Empreinte SHA-256 du contenu (hexadécimal), renvoyée aussi en X-Content-SHA256."
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label",
            "description": "Libellé saisi au dépôt."
          },
          "uploaded_by": {
            "type": "string",
            "title": "Uploaded By",
            "description": "Côté qui a déposé la pièce : company ou institution."
          },
          "reserved_to_one_institution": {
            "type": "boolean",
            "title": "Reserved To One Institution",
            "description": "Vrai si la pièce, déposée par l'entreprise, n'est destinée qu'à une seule banque."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "Date du dépôt (UTC)."
          },
          "links": {
            "$ref": "#/components/schemas/DocumentLinks"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "parent_type",
          "parent_id",
          "file_name",
          "content_type",
          "size_bytes",
          "sha256",
          "label",
          "uploaded_by",
          "reserved_to_one_institution",
          "created_at",
          "links"
        ],
        "title": "DocumentOut",
        "description": "Métadonnées d'une pièce rattachée à son parent.",
        "examples": [
          {
            "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
            "parent_type": "financing_request",
            "parent_id": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f",
            "file_name": "bilan-2025.pdf",
            "content_type": "application/pdf",
            "size_bytes": 482133,
            "sha256": "9f2b5c0d4e1a7b3c8d6e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c",
            "label": "Bilan 2025",
            "uploaded_by": "company",
            "reserved_to_one_institution": false,
            "created_at": "2026-01-06T10:02:00Z",
            "links": {
              "self": "/documents/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
              "content": "/documents/5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9/content"
            }
          }
        ]
      },
      "DownloadLinkOut": {
        "properties": {
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "URL à ouvrir sans en-tête Authorization (une seule fois, avant expires_at) ; null dans une réponse rejouée."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "title": "Expires At",
            "description": "Expiration du lien (UTC)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "url",
          "expires_at"
        ],
        "title": "DownloadLinkOut",
        "description": "Lien de téléchargement signé, à usage unique et de courte durée.",
        "examples": [
          {
            "url": "https://api.tauraco.io/public/v1/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e/file?token=d1.eyJqIjoi…",
            "expires_at": "2026-01-05T08:01:09Z"
          }
        ]
      },
      "ExportFormatList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ExportFormatOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "ExportFormatList",
        "description": "Formats d'export (page unique).",
        "examples": [
          {
            "data": [
              {
                "code": "csv",
                "label": "CSV",
                "extension": "csv",
                "maturity": "available",
                "multi_dataset": false,
                "disclaimer": null
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "ExportFormatOut": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Code du format (format d'un export)."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Libellé."
          },
          "extension": {
            "type": "string",
            "title": "Extension",
            "description": "Extension du fichier produit."
          },
          "maturity": {
            "type": "string",
            "title": "Maturity",
            "description": "available, beta ou configuration_required."
          },
          "multi_dataset": {
            "type": "boolean",
            "title": "Multi Dataset",
            "description": "Vrai si le format accepte plusieurs jeux dans un même fichier."
          },
          "disclaimer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disclaimer",
            "description": "Avertissement d'usage, s'il y a lieu."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "code",
          "label",
          "extension",
          "maturity",
          "multi_dataset",
          "disclaimer"
        ],
        "title": "ExportFormatOut",
        "description": "Un format d'export enregistré.",
        "examples": [
          {
            "code": "csv",
            "label": "CSV",
            "extension": "csv",
            "maturity": "available",
            "multi_dataset": false,
            "disclaimer": null
          }
        ]
      },
      "ExportJobDataset": {
        "properties": {
          "dataset": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dataset",
            "description": "Code du jeu de données."
          },
          "columns": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Columns",
            "description": "Colonnes demandées ; vide = colonnes par défaut du jeu."
          },
          "filters": {
            "additionalProperties": true,
            "type": "object",
            "title": "Filters",
            "description": "Filtres demandés, tels que validés."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "dataset",
          "columns",
          "filters"
        ],
        "title": "ExportJobDataset",
        "description": "Un jeu d'un job : code, colonnes demandées (vide = colonnes par défaut), filtres."
      },
      "ExportJobError": {
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Code d'erreur ; null dans une réponse rejouée."
          },
          "message": {
            "type": "string",
            "title": "Message",
            "description": "Message lisible, sans détail interne."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "title": "ExportJobError",
        "description": "Cause d'un échec (code de la liste fermée, message lisible)."
      },
      "ExportJobLinks": {
        "properties": {
          "self": {
            "type": "string",
            "title": "Self",
            "description": "Le job."
          },
          "download": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Download",
            "description": "Fichier en flux (porteur) ; null tant que le job n'a pas réussi."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "self",
          "download"
        ],
        "title": "ExportJobLinks",
        "description": "Liens relatifs à la racine de l'API (``/public/v1``)."
      },
      "ExportJobList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ExportJobOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "ExportJobList",
        "description": "Page de jobs d'export, du plus récent au plus ancien.",
        "examples": [
          {
            "data": [
              {
                "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                "status": "SUCCEEDED",
                "format": "csv",
                "datasets": [
                  {
                    "dataset": "invoices",
                    "columns": [],
                    "filters": {
                      "created_after": "2026-01-01T00:00:00Z"
                    }
                  }
                ],
                "format_options": {},
                "include_pii": false,
                "row_count": 1250,
                "byte_size": 182044,
                "sha256": "4a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
                "file_name": "invoices_20260105-080000.csv",
                "delivery": "download",
                "delivery_status": null,
                "error": null,
                "progress_rows": 1250,
                "cancel_requested": false,
                "via": "public_api",
                "attempt": 1,
                "queued_at": "2026-01-05T08:00:00Z",
                "started_at": "2026-01-05T08:00:02Z",
                "finished_at": "2026-01-05T08:00:09Z",
                "expires_at": "2026-02-04T08:00:09Z",
                "retry_of_id": null,
                "links": {
                  "self": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                  "download": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e/download"
                }
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "ExportJobOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant du job (UUID)."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "QUEUED, RUNNING, SUCCEEDED, FAILED, CANCELLED ou EXPIRED."
          },
          "format": {
            "type": "string",
            "title": "Format",
            "description": "Code du format."
          },
          "datasets": {
            "items": {
              "$ref": "#/components/schemas/ExportJobDataset"
            },
            "type": "array",
            "title": "Datasets",
            "description": "Jeux exportés."
          },
          "format_options": {
            "additionalProperties": true,
            "type": "object",
            "title": "Format Options",
            "description": "Options du format."
          },
          "include_pii": {
            "type": "boolean",
            "title": "Include Pii",
            "description": "Vrai si l'export inclut des données personnelles."
          },
          "row_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Row Count",
            "description": "Lignes écrites (job réussi)."
          },
          "byte_size": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Byte Size",
            "description": "Taille du fichier en octets."
          },
          "sha256": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sha256",
            "description": "Empreinte SHA-256 du fichier."
          },
          "file_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File Name",
            "description": "Nom du fichier."
          },
          "delivery": {
            "type": "string",
            "title": "Delivery",
            "description": "Livraison : download, ou sftp:<connexion>."
          },
          "delivery_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivery Status",
            "description": "État de la livraison distante (sent, failed)."
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExportJobError"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cause de l'échec, s'il y a lieu."
          },
          "progress_rows": {
            "type": "integer",
            "title": "Progress Rows",
            "description": "Lignes déjà écrites."
          },
          "cancel_requested": {
            "type": "boolean",
            "title": "Cancel Requested",
            "description": "Vrai si une annulation a été demandée."
          },
          "via": {
            "type": "string",
            "title": "Via",
            "description": "Canal de la demande : spa, public_api, mcp ou schedule."
          },
          "attempt": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Attempt",
            "description": "Numéro d'essai."
          },
          "queued_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Queued At",
            "description": "Mise en file (UTC)."
          },
          "started_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Started At",
            "description": "Début d'exécution (UTC)."
          },
          "finished_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finished At",
            "description": "Fin d'exécution (UTC)."
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At",
            "description": "Purge du fichier (UTC), 30 jours après le succès."
          },
          "retry_of_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Retry Of Id",
            "description": "Job relancé par celui-ci, s'il y a lieu."
          },
          "links": {
            "$ref": "#/components/schemas/ExportJobLinks"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "status",
          "format",
          "datasets",
          "format_options",
          "include_pii",
          "row_count",
          "byte_size",
          "sha256",
          "file_name",
          "delivery",
          "delivery_status",
          "error",
          "progress_rows",
          "cancel_requested",
          "via",
          "attempt",
          "queued_at",
          "started_at",
          "finished_at",
          "expires_at",
          "retry_of_id",
          "links"
        ],
        "title": "ExportJobOut",
        "description": "Un job d'export et son état.",
        "examples": [
          {
            "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
            "status": "SUCCEEDED",
            "format": "csv",
            "datasets": [
              {
                "dataset": "invoices",
                "columns": [],
                "filters": {
                  "created_after": "2026-01-01T00:00:00Z"
                }
              }
            ],
            "format_options": {},
            "include_pii": false,
            "row_count": 1250,
            "byte_size": 182044,
            "sha256": "4a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
            "file_name": "invoices_20260105-080000.csv",
            "delivery": "download",
            "delivery_status": null,
            "error": null,
            "progress_rows": 1250,
            "cancel_requested": false,
            "via": "public_api",
            "attempt": 1,
            "queued_at": "2026-01-05T08:00:00Z",
            "started_at": "2026-01-05T08:00:02Z",
            "finished_at": "2026-01-05T08:00:09Z",
            "expires_at": "2026-02-04T08:00:09Z",
            "retry_of_id": null,
            "links": {
              "self": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
              "download": "/exports/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e/download"
            }
          }
        ]
      },
      "FinancingRequestList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/FinancingRequestOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "FinancingRequestList",
        "description": "Page de demandes de financement.",
        "examples": [
          {
            "data": [
              {
                "id": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f",
                "billing_invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                "amount_requested": "100000",
                "currency": "XOF",
                "product": "INVOICE_FINANCING",
                "country": "SN",
                "status": "SUBMITTED",
                "marketplace_mode": null,
                "accepted_offer_id": null,
                "source_changed": false,
                "submitted_at": "2026-01-06T10:00:00Z",
                "expires_at": null,
                "closed_at": null,
                "created_at": "2026-01-06T09:59:00.000007Z",
                "updated_at": "2026-01-06T10:00:00Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "FinancingRequestOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "billing_invoice_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Billing Invoice Id",
            "description": "Facture (Invoice)."
          },
          "amount_requested": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount Requested",
            "description": "Montant demandé (Amount requested)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "product": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product",
            "description": "Produit (Product).",
            "x-enum-values": [
              "INVOICE_FINANCING",
              "FACTORING",
              "REVERSE_FACTORING",
              "SECURED_FINANCING"
            ]
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Pays (Country)."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Statut (Status).",
            "x-enum-values": [
              "DRAFT",
              "SUBMITTED",
              "UNDER_REVIEW",
              "INFORMATION_REQUESTED",
              "OFFERS_RECEIVED",
              "OFFER_ACCEPTED",
              "DECLINED",
              "WITHDRAWN",
              "FUNDED",
              "SETTLED",
              "CLOSED"
            ]
          },
          "marketplace_mode": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Marketplace Mode",
            "description": "Mise en concurrence (Marketplace mode)."
          },
          "accepted_offer_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accepted Offer Id",
            "description": "Offre retenue (Accepted offer)."
          },
          "source_changed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Changed",
            "description": "Facture modifiée depuis la soumission (Invoice changed since submission)."
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At",
            "description": "Soumise le (Submitted at)."
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At",
            "description": "Expire le (Expires at)."
          },
          "closed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed At",
            "description": "Close le (Closed at)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créée le (Created at)."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "Modifiée le (Updated at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "billing_invoice_id",
          "amount_requested",
          "currency",
          "product",
          "country",
          "status",
          "marketplace_mode",
          "accepted_offer_id",
          "source_changed",
          "submitted_at",
          "expires_at",
          "closed_at",
          "created_at",
          "updated_at"
        ],
        "title": "FinancingRequestOut",
        "description": "Une demande de financement adossée à une facture.",
        "examples": [
          {
            "id": "c9d0e1f2-a3b4-4c5d-8e6f-7a8b9c0d1e2f",
            "billing_invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "amount_requested": "100000",
            "currency": "XOF",
            "product": "INVOICE_FINANCING",
            "country": "SN",
            "status": "SUBMITTED",
            "marketplace_mode": null,
            "accepted_offer_id": null,
            "source_changed": false,
            "submitted_at": "2026-01-06T10:00:00Z",
            "expires_at": null,
            "closed_at": null,
            "created_at": "2026-01-06T09:59:00.000007Z",
            "updated_at": "2026-01-06T10:00:00Z"
          }
        ],
        "x-tauraco-dataset": "financing_requests"
      },
      "GuaranteeAlertOut": {
        "properties": {
          "alert_id": {
            "type": "string",
            "title": "Alert Id"
          },
          "type": {
            "type": "string",
            "title": "Type"
          },
          "severity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Severity"
          },
          "status": {
            "type": "string",
            "title": "Status"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "alert_id",
          "type",
          "status"
        ],
        "title": "GuaranteeAlertOut",
        "examples": [
          {
            "alert_id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
            "type": "PEREMPTION_INSCRIPTION",
            "severity": "AVERTISSEMENT",
            "status": "OPEN"
          }
        ]
      },
      "GuaranteeDeedOut": {
        "properties": {
          "deed_id": {
            "type": "string",
            "title": "Deed Id"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status"
          },
          "template_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Template Code"
          },
          "sha256": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sha256"
          },
          "document_available": {
            "type": "boolean",
            "title": "Document Available"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "deed_id",
          "document_available"
        ],
        "title": "GuaranteeDeedOut",
        "examples": [
          {
            "deed_id": "0e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
            "status": "SIGNE",
            "template_code": "COLLATERAL_ACTE_GENERIQUE_V1",
            "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c",
            "document_available": true,
            "created_at": "2026-03-02T10:00:00Z"
          }
        ]
      },
      "GuaranteeDetailOut": {
        "properties": {
          "guarantee_id": {
            "type": "string",
            "title": "Guarantee Id"
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of"
          },
          "evaluation": {
            "additionalProperties": true,
            "type": "object",
            "title": "Evaluation"
          },
          "obligations": {
            "items": {
              "$ref": "#/components/schemas/GuaranteeObligationOut"
            },
            "type": "array",
            "title": "Obligations"
          },
          "avertissement_juridique": {
            "type": "string",
            "title": "Avertissement Juridique"
          },
          "links": {
            "$ref": "#/components/schemas/LinksOut"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "guarantee_id",
          "as_of",
          "evaluation",
          "obligations",
          "avertissement_juridique",
          "links"
        ],
        "title": "GuaranteeDetailOut",
        "description": "Fiche d'une garantie pour son bénéficiaire : évaluation du moteur et obligations, sans dossier privé.",
        "examples": [
          {
            "guarantee_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "as_of": "2026-11-04",
            "evaluation": {
              "garantie_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
              "as_of": "2026-11-04",
              "source_juridique": "DEMO_FICTIF",
              "etats": {
                "opposable_aux_tiers": {
                  "subject": "opposable_aux_tiers",
                  "status": "EVALUATED",
                  "value": true,
                  "evaluated_as_of": "2026-11-04"
                }
              }
            },
            "obligations": [
              {
                "obligation_id": "3d4e5f6a-7b8c-4d9e-af0a-1b2c3d4e5f6a",
                "obligation_type": "avance",
                "amount": "9000000",
                "currency": "XOF",
                "due_date": "2026-06-30",
                "status": "en_cours",
                "settled_amount": "0",
                "outstanding": "9000000"
              }
            ],
            "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi.",
            "links": {
              "self": "https://api.tauraco.io/public/v1/bank/collateral/1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
            }
          }
        ]
      },
      "GuaranteeEventOut": {
        "properties": {
          "event_id": {
            "type": "string",
            "title": "Event Id"
          },
          "type": {
            "type": "string",
            "title": "Type"
          },
          "effective_date": {
            "type": "string",
            "format": "date",
            "title": "Effective Date"
          },
          "recorded_date": {
            "type": "string",
            "format": "date",
            "title": "Recorded Date"
          },
          "actor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Actor"
          },
          "comment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment"
          },
          "proof_expected_missing": {
            "type": "boolean",
            "title": "Proof Expected Missing"
          },
          "proofs": {
            "items": {
              "$ref": "#/components/schemas/GuaranteeProofOut"
            },
            "type": "array",
            "title": "Proofs"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "event_id",
          "type",
          "effective_date",
          "recorded_date",
          "proof_expected_missing",
          "proofs"
        ],
        "title": "GuaranteeEventOut",
        "examples": [
          {
            "event_id": "6a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d",
            "type": "inscription_rccm",
            "effective_date": "2026-03-09",
            "recorded_date": "2026-03-10",
            "actor": "Banque Exemple SA",
            "comment": null,
            "proof_expected_missing": false,
            "proofs": [
              {
                "proof_id": "8c9d0e1f-2a3b-4c4d-8e5f-6a7b8c9d0e1f",
                "nature": "recepisse_rccm",
                "external_number": "RCCM-EX-2026-0001",
                "issuer": null,
                "registry_office": "Greffe du tribunal de commerce (exemple)",
                "document_date": "2026-03-09",
                "version": 1,
                "replaces_proof_id": null,
                "document_available": true,
                "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c"
              }
            ]
          }
        ]
      },
      "GuaranteeEventsOut": {
        "properties": {
          "guarantee_id": {
            "type": "string",
            "title": "Guarantee Id"
          },
          "events": {
            "items": {
              "$ref": "#/components/schemas/GuaranteeEventOut"
            },
            "type": "array",
            "title": "Events"
          },
          "deeds": {
            "items": {
              "$ref": "#/components/schemas/GuaranteeDeedOut"
            },
            "type": "array",
            "title": "Deeds"
          },
          "avertissement_juridique": {
            "type": "string",
            "title": "Avertissement Juridique"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "guarantee_id",
          "events",
          "deeds",
          "avertissement_juridique"
        ],
        "title": "GuaranteeEventsOut",
        "examples": [
          {
            "guarantee_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "events": [
              {
                "event_id": "6a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d",
                "type": "inscription_rccm",
                "effective_date": "2026-03-09",
                "recorded_date": "2026-03-10",
                "actor": "Banque Exemple SA",
                "comment": null,
                "proof_expected_missing": false,
                "proofs": [
                  {
                    "proof_id": "8c9d0e1f-2a3b-4c4d-8e5f-6a7b8c9d0e1f",
                    "nature": "recepisse_rccm",
                    "external_number": "RCCM-EX-2026-0001",
                    "issuer": null,
                    "registry_office": "Greffe du tribunal de commerce (exemple)",
                    "document_date": "2026-03-09",
                    "version": 1,
                    "replaces_proof_id": null,
                    "document_available": true,
                    "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c"
                  }
                ]
              }
            ],
            "deeds": [
              {
                "deed_id": "0e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
                "status": "SIGNE",
                "template_code": "COLLATERAL_ACTE_GENERIQUE_V1",
                "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c",
                "document_available": true,
                "created_at": "2026-03-02T10:00:00Z"
              }
            ],
            "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi."
          }
        ]
      },
      "GuaranteeObligationOut": {
        "properties": {
          "obligation_id": {
            "type": "string",
            "title": "Obligation Id"
          },
          "obligation_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Obligation Type"
          },
          "amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency"
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status"
          },
          "settled_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settled Amount"
          },
          "outstanding": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Outstanding"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "obligation_id"
        ],
        "title": "GuaranteeObligationOut",
        "examples": [
          {
            "obligation_id": "3d4e5f6a-7b8c-4d9e-af0a-1b2c3d4e5f6a",
            "obligation_type": "avance",
            "amount": "9000000",
            "currency": "XOF",
            "due_date": "2026-06-30",
            "status": "en_cours",
            "settled_amount": "0",
            "outstanding": "9000000"
          }
        ]
      },
      "GuaranteeOut": {
        "properties": {
          "guarantee_id": {
            "type": "string",
            "title": "Guarantee Id"
          },
          "type": {
            "type": "string",
            "title": "Type"
          },
          "nature": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Nature"
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country"
          },
          "regime_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Regime Code"
          },
          "business_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Business Status"
          },
          "deed_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deed Date"
          },
          "expiry_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expiry Date"
          },
          "grantor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Grantor"
          },
          "beneficiary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Beneficiary"
          },
          "security_agent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Security Agent"
          },
          "asset_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Asset Ids"
          },
          "obligations": {
            "items": {
              "$ref": "#/components/schemas/GuaranteeObligationOut"
            },
            "type": "array",
            "title": "Obligations"
          },
          "alerts": {
            "items": {
              "$ref": "#/components/schemas/GuaranteeAlertOut"
            },
            "type": "array",
            "title": "Alerts"
          },
          "competent_registry": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Competent Registry"
          },
          "avertissement_juridique": {
            "type": "string",
            "title": "Avertissement Juridique"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "guarantee_id",
          "type",
          "asset_ids",
          "obligations",
          "alerts",
          "avertissement_juridique"
        ],
        "title": "GuaranteeOut",
        "examples": [
          {
            "guarantee_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "type": "NANTISSEMENT",
            "nature": "REELLE",
            "country": "SN",
            "regime_code": "OHADA_NANT_CREANCE_V2010",
            "business_status": "projet",
            "deed_date": "2026-03-02",
            "expiry_date": "2031-03-02",
            "grantor": "PME Exemple SARL",
            "beneficiary": "Banque Exemple SA",
            "security_agent": null,
            "asset_ids": [
              "5f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c"
            ],
            "obligations": [
              {
                "obligation_id": "3d4e5f6a-7b8c-4d9e-af0a-1b2c3d4e5f6a",
                "obligation_type": "avance",
                "amount": "9000000",
                "currency": "XOF",
                "due_date": "2026-06-30",
                "status": "en_cours",
                "settled_amount": "0",
                "outstanding": "9000000"
              }
            ],
            "alerts": [
              {
                "alert_id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                "type": "PEREMPTION_INSCRIPTION",
                "severity": "AVERTISSEMENT",
                "status": "OPEN"
              }
            ],
            "competent_registry": "Registre du commerce et du crédit mobilier (exemple)",
            "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi."
          }
        ]
      },
      "GuaranteeProofOut": {
        "properties": {
          "proof_id": {
            "type": "string",
            "title": "Proof Id"
          },
          "nature": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Nature"
          },
          "external_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Number"
          },
          "issuer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Issuer"
          },
          "registry_office": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Registry Office"
          },
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date"
          },
          "version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Version"
          },
          "replaces_proof_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Replaces Proof Id"
          },
          "document_available": {
            "type": "boolean",
            "title": "Document Available"
          },
          "sha256": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sha256"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "proof_id",
          "document_available"
        ],
        "title": "GuaranteeProofOut",
        "examples": [
          {
            "proof_id": "8c9d0e1f-2a3b-4c4d-8e5f-6a7b8c9d0e1f",
            "nature": "recepisse_rccm",
            "external_number": "RCCM-EX-2026-0001",
            "issuer": null,
            "registry_office": "Greffe du tribunal de commerce (exemple)",
            "document_date": "2026-03-09",
            "version": 1,
            "replaces_proof_id": null,
            "document_available": true,
            "sha256": "4f8b2c1d9e7a6b5c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c"
          }
        ]
      },
      "GuaranteesOut": {
        "properties": {
          "total": {
            "type": "integer",
            "title": "Total"
          },
          "truncated": {
            "type": "boolean",
            "title": "Truncated"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/GuaranteeOut"
            },
            "type": "array",
            "title": "Items"
          },
          "avertissement_juridique": {
            "type": "string",
            "title": "Avertissement Juridique"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "total",
          "truncated",
          "items",
          "avertissement_juridique"
        ],
        "title": "GuaranteesOut",
        "description": "Garanties au bénéfice de l'institution, au plus ``limit``.\n\n``total`` compte les lignes servies ; ``truncated`` vaut ``true`` quand d'autres\ngaranties répondent aux filtres au-delà de ``limit`` (au plafond de 200, une liste\npleine est toujours déclarée tronquée) : resserrer les filtres pour les obtenir.",
        "examples": [
          {
            "total": 1,
            "truncated": false,
            "items": [
              {
                "guarantee_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                "type": "NANTISSEMENT",
                "nature": "REELLE",
                "country": "SN",
                "regime_code": "OHADA_NANT_CREANCE_V2010",
                "business_status": "projet",
                "deed_date": "2026-03-02",
                "expiry_date": "2031-03-02",
                "grantor": "PME Exemple SARL",
                "beneficiary": "Banque Exemple SA",
                "security_agent": null,
                "asset_ids": [
                  "5f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c"
                ],
                "obligations": [
                  {
                    "obligation_id": "3d4e5f6a-7b8c-4d9e-af0a-1b2c3d4e5f6a",
                    "obligation_type": "avance",
                    "amount": "9000000",
                    "currency": "XOF",
                    "due_date": "2026-06-30",
                    "status": "en_cours",
                    "settled_amount": "0",
                    "outstanding": "9000000"
                  }
                ],
                "alerts": [
                  {
                    "alert_id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                    "type": "PEREMPTION_INSCRIPTION",
                    "severity": "AVERTISSEMENT",
                    "status": "OPEN"
                  }
                ],
                "competent_registry": "Registre du commerce et du crédit mobilier (exemple)",
                "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi."
              }
            ],
            "avertissement_juridique": "Information de suivi : les données de garantie enregistrées dans Tauraco ne sont jamais la preuve juridique définitive d'une sûreté opposable. Elles ne valent ni inscription au registre compétent, ni preuve de l'existence, de l'opposabilité ou du rang de la sûreté ; seuls les actes et les formalités accomplies auprès du registre compétent font foi."
          }
        ]
      },
      "InformationRequestCreatedOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "request_id": {
            "type": "string",
            "title": "Request Id"
          },
          "kind": {
            "type": "string",
            "title": "Kind"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
          },
          "links": {
            "$ref": "#/components/schemas/LinksOut"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "request_id",
          "kind",
          "created_at",
          "links"
        ],
        "title": "InformationRequestCreatedOut",
        "examples": [
          {
            "id": "6d7e8f90-a1b2-4c3d-8e4f-5a6b7c8d9e0f",
            "request_id": "8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f",
            "kind": "DOCUMENT_REQUEST",
            "created_at": "2026-11-03T08:15:00Z",
            "links": {
              "self": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f"
            }
          }
        ]
      },
      "InformationRequestIn": {
        "properties": {
          "text": {
            "type": "string",
            "maxLength": 8000,
            "minLength": 1,
            "title": "Text"
          },
          "kind": {
            "type": "string",
            "enum": [
              "DOCUMENT_REQUEST",
              "QUESTION",
              "CONFIRMATION_REQUEST"
            ],
            "title": "Kind",
            "default": "DOCUMENT_REQUEST"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "text"
        ],
        "title": "InformationRequestIn"
      },
      "InstitutionOut": {
        "properties": {
          "tenant_id": {
            "type": "string",
            "title": "Tenant Id"
          },
          "name": {
            "type": "string",
            "title": "Name"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "tenant_id",
          "name"
        ],
        "title": "InstitutionOut",
        "examples": [
          {
            "tenant_id": "t_banque_exemple",
            "name": "Banque Exemple SA"
          }
        ]
      },
      "InventoryBalanceList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/InventoryBalanceOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "InventoryBalanceList",
        "description": "Page de soldes de stock.",
        "examples": [
          {
            "data": [
              {
                "lot_id": "a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d",
                "item_id": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7a8b",
                "warehouse_id": "b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d1e",
                "quantity": "100",
                "reserved": "0",
                "blocked": "0",
                "available": "100"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "InventoryBalanceOut": {
        "properties": {
          "lot_id": {
            "type": "string",
            "title": "Lot Id",
            "description": "Lot (Lot)."
          },
          "item_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item Id",
            "description": "Article (Item)."
          },
          "warehouse_id": {
            "type": "string",
            "title": "Warehouse Id",
            "description": "Entrepôt (Warehouse)."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Valeur décimale, en chaîne.",
                "examples": [
                  "12.5"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity",
            "description": "Quantité (Quantity)."
          },
          "reserved": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Valeur décimale, en chaîne.",
                "examples": [
                  "12.5"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Reserved",
            "description": "Réservée (Reserved)."
          },
          "blocked": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Valeur décimale, en chaîne.",
                "examples": [
                  "12.5"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Blocked",
            "description": "Bloquée (Blocked)."
          },
          "available": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Valeur décimale, en chaîne.",
                "examples": [
                  "12.5"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Available",
            "description": "Disponible (Available)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "lot_id",
          "item_id",
          "warehouse_id",
          "quantity",
          "reserved",
          "blocked",
          "available"
        ],
        "title": "InventoryBalanceOut",
        "description": "Solde d'un lot dans un entrepôt.",
        "examples": [
          {
            "lot_id": "a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d",
            "item_id": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7a8b",
            "warehouse_id": "b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d1e",
            "quantity": "100",
            "reserved": "0",
            "blocked": "0",
            "available": "100"
          }
        ],
        "x-tauraco-dataset": "inventory_balances"
      },
      "InventoryItemList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/InventoryItemOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "InventoryItemList",
        "description": "Page d'articles.",
        "examples": [
          {
            "data": [
              {
                "id": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7a8b",
                "sku": "ART-0001",
                "name": "Sac de riz 50 kg",
                "description": null,
                "category_id": null,
                "product_id": null,
                "unit_of_measure": "unité",
                "barcode": null,
                "perishable": true,
                "shelf_life_days": 365,
                "valuation_method": "FIFO",
                "attributes": null,
                "active": true,
                "created_at": "2026-01-02T08:00:00.000005Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "InventoryItemOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sku",
            "description": "Référence (SKU) (SKU)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Désignation (Name)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Description (Description)."
          },
          "category_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Category Id",
            "description": "Famille (Category)."
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product Id",
            "description": "Produit de vente (Sales product)."
          },
          "unit_of_measure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Of Measure",
            "description": "Unité (Unit of measure)."
          },
          "barcode": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Barcode",
            "description": "Code-barres (Barcode)."
          },
          "perishable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Perishable",
            "description": "Périssable (Perishable)."
          },
          "shelf_life_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Shelf Life Days",
            "description": "Durée de conservation (jours) (Shelf life (days))."
          },
          "valuation_method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valuation Method",
            "description": "Méthode de valorisation (Valuation method)."
          },
          "attributes": {
            "title": "Attributes",
            "description": "Attributs libres de l'article (objet JSON), si renseignés."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "Actif (Active)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créé le (Created at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "sku",
          "name",
          "description",
          "category_id",
          "product_id",
          "unit_of_measure",
          "barcode",
          "perishable",
          "shelf_life_days",
          "valuation_method",
          "attributes",
          "active",
          "created_at"
        ],
        "title": "InventoryItemOut",
        "description": "Un article stocké.",
        "examples": [
          {
            "id": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7a8b",
            "sku": "ART-0001",
            "name": "Sac de riz 50 kg",
            "description": null,
            "category_id": null,
            "product_id": null,
            "unit_of_measure": "unité",
            "barcode": null,
            "perishable": true,
            "shelf_life_days": 365,
            "valuation_method": "FIFO",
            "attributes": null,
            "active": true,
            "created_at": "2026-01-02T08:00:00.000005Z"
          }
        ],
        "x-tauraco-dataset": "inventory_items"
      },
      "InventoryMovementList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/InventoryMovementOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "InventoryMovementList",
        "description": "Page de mouvements de stock.",
        "examples": [
          {
            "data": [
              {
                "id": "f6a7b8c9-d0e1-4f2a-9b3c-4d5e6f7a8b9c",
                "lot_id": "a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d",
                "warehouse_id": "b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d1e",
                "location_id": null,
                "movement_type": "RECEIPT",
                "quantity": "100",
                "unit_cost": "25000",
                "currency": "XOF",
                "value_date": "2026-01-10",
                "transfer_group_id": null,
                "reverses_movement_id": null,
                "reason": null,
                "source_ref_type": null,
                "source_ref_id": null,
                "created_at": "2026-01-10T07:30:00.000006Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "InventoryMovementOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "lot_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lot Id",
            "description": "Lot (Lot)."
          },
          "warehouse_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse Id",
            "description": "Entrepôt (Warehouse)."
          },
          "location_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Location Id",
            "description": "Emplacement (Location)."
          },
          "movement_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Movement Type",
            "description": "Type de mouvement (Movement type)."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Valeur décimale, en chaîne.",
                "examples": [
                  "12.5"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity",
            "description": "Quantité (Quantity)."
          },
          "unit_cost": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Cost",
            "description": "Coût unitaire (Unit cost)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "value_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value Date",
            "description": "Date de valeur (Value date)."
          },
          "transfer_group_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Transfer Group Id",
            "description": "Transfert (Transfer group)."
          },
          "reverses_movement_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reverses Movement Id",
            "description": "Mouvement contre-passé (Reversed movement)."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Motif (Reason)."
          },
          "source_ref_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Ref Type",
            "description": "Type de pièce d'origine (Source document type)."
          },
          "source_ref_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Ref Id",
            "description": "Pièce d'origine (Source document)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Enregistré le (Recorded at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "lot_id",
          "warehouse_id",
          "location_id",
          "movement_type",
          "quantity",
          "unit_cost",
          "currency",
          "value_date",
          "transfer_group_id",
          "reverses_movement_id",
          "reason",
          "source_ref_type",
          "source_ref_id",
          "created_at"
        ],
        "title": "InventoryMovementOut",
        "description": "Un mouvement de stock (entrée, sortie, transfert, ajustement).",
        "examples": [
          {
            "id": "f6a7b8c9-d0e1-4f2a-9b3c-4d5e6f7a8b9c",
            "lot_id": "a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d",
            "warehouse_id": "b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d1e",
            "location_id": null,
            "movement_type": "RECEIPT",
            "quantity": "100",
            "unit_cost": "25000",
            "currency": "XOF",
            "value_date": "2026-01-10",
            "transfer_group_id": null,
            "reverses_movement_id": null,
            "reason": null,
            "source_ref_type": null,
            "source_ref_id": null,
            "created_at": "2026-01-10T07:30:00.000006Z"
          }
        ],
        "x-tauraco-dataset": "inventory_movements"
      },
      "InvoiceDetailOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Numéro (Number)."
          },
          "customer_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Id",
            "description": "Identifiant du client (Customer identifier)."
          },
          "customer_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Name",
            "description": "Client (Customer)."
          },
          "issue_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Issue Date",
            "description": "Date d'émission (Issue date)."
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "Date d'échéance (Due date)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "subtotal": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtotal",
            "description": "Total HT (Subtotal)."
          },
          "tax_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Total",
            "description": "Total taxes (Tax total)."
          },
          "total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Total TTC (Total)."
          },
          "amount_paid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount Paid",
            "description": "Montant réglé (Amount paid)."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Statut (Status).",
            "x-enum-values": [
              "DRAFT",
              "SENT",
              "PARTIALLY_PAID",
              "PAID",
              "OVERDUE",
              "CANCELLED",
              "FINANCING_REQUESTED"
            ]
          },
          "facturx_profile": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Facturx Profile",
            "description": "Profil Factur-X (Factur-X profile)."
          },
          "tva_details": {
            "title": "Tva Details",
            "description": "Ventilation de la TVA (objet JSON), si renseignée."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créée le (Created at)."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "Modifiée le (Updated at)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/InvoiceLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "Lignes de la facture, dans l'ordre de saisie.",
            "x-tauraco-derived": true
          },
          "lines_truncated": {
            "type": "boolean",
            "title": "Lines Truncated",
            "description": "Vrai si la facture compte plus de lignes que la réponse n'en porte.",
            "x-tauraco-derived": true
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "number",
          "customer_id",
          "customer_name",
          "issue_date",
          "due_date",
          "currency",
          "subtotal",
          "tax_total",
          "total",
          "amount_paid",
          "status",
          "facturx_profile",
          "tva_details",
          "created_at",
          "updated_at",
          "lines",
          "lines_truncated"
        ],
        "title": "InvoiceDetailOut",
        "description": "Facture client avec ses lignes.",
        "examples": [
          {
            "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "number": "FA-2026-0001",
            "customer_id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
            "customer_name": "Client Exemple",
            "issue_date": "2026-01-05",
            "due_date": "2026-02-04",
            "currency": "XOF",
            "subtotal": "100000",
            "tax_total": "18000",
            "total": "118000",
            "amount_paid": "0",
            "status": "SENT",
            "facturx_profile": null,
            "tva_details": null,
            "created_at": "2026-01-05T08:00:03.023757Z",
            "updated_at": "2026-01-05T08:00:03.023757Z",
            "lines": [
              {
                "id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
                "sort_order": 0,
                "product_id": null,
                "description": "Prestation de conseil",
                "quantity": 2,
                "unit_price": "50000",
                "tax_rate_bps": 1800,
                "tva_rate_type": null,
                "line_total": "100000",
                "tax_amount": "18000",
                "currency": "XOF"
              }
            ],
            "lines_truncated": false
          }
        ],
        "x-tauraco-dataset": "invoices"
      },
      "InvoiceLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "sort_order": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sort Order",
            "description": "Rang (Position)."
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product Id",
            "description": "Produit (Product)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Désignation (Description)."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity",
            "description": "Quantité (Quantity)."
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Price",
            "description": "Prix unitaire HT (Unit price)."
          },
          "tax_rate_bps": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate Bps",
            "description": "Taux de taxe (points de base) (Tax rate (basis points))."
          },
          "tva_rate_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tva Rate Type",
            "description": "Type de taux de TVA (VAT rate type)."
          },
          "line_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Line Total",
            "description": "Total HT de la ligne (Line total)."
          },
          "tax_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Amount",
            "description": "Montant de taxe (Tax amount)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "sort_order",
          "product_id",
          "description",
          "quantity",
          "unit_price",
          "tax_rate_bps",
          "tva_rate_type",
          "line_total",
          "tax_amount",
          "currency"
        ],
        "title": "InvoiceLineOut",
        "description": "Ligne d'une facture client.",
        "examples": [
          {
            "id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
            "sort_order": 0,
            "product_id": null,
            "description": "Prestation de conseil",
            "quantity": 2,
            "unit_price": "50000",
            "tax_rate_bps": 1800,
            "tva_rate_type": null,
            "line_total": "100000",
            "tax_amount": "18000",
            "currency": "XOF"
          }
        ],
        "x-tauraco-dataset": "invoice_lines"
      },
      "InvoiceList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/InvoiceOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "InvoiceList",
        "description": "Page de factures clients.",
        "examples": [
          {
            "data": [
              {
                "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                "number": "FA-2026-0001",
                "customer_id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                "customer_name": "Client Exemple",
                "issue_date": "2026-01-05",
                "due_date": "2026-02-04",
                "currency": "XOF",
                "subtotal": "100000",
                "tax_total": "18000",
                "total": "118000",
                "amount_paid": "0",
                "status": "SENT",
                "facturx_profile": null,
                "tva_details": null,
                "created_at": "2026-01-05T08:00:03.023757Z",
                "updated_at": "2026-01-05T08:00:03.023757Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "InvoiceOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Numéro (Number)."
          },
          "customer_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Id",
            "description": "Identifiant du client (Customer identifier)."
          },
          "customer_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Name",
            "description": "Client (Customer)."
          },
          "issue_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Issue Date",
            "description": "Date d'émission (Issue date)."
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "Date d'échéance (Due date)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "subtotal": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtotal",
            "description": "Total HT (Subtotal)."
          },
          "tax_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Total",
            "description": "Total taxes (Tax total)."
          },
          "total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Total TTC (Total)."
          },
          "amount_paid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount Paid",
            "description": "Montant réglé (Amount paid)."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Statut (Status).",
            "x-enum-values": [
              "DRAFT",
              "SENT",
              "PARTIALLY_PAID",
              "PAID",
              "OVERDUE",
              "CANCELLED",
              "FINANCING_REQUESTED"
            ]
          },
          "facturx_profile": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Facturx Profile",
            "description": "Profil Factur-X (Factur-X profile)."
          },
          "tva_details": {
            "title": "Tva Details",
            "description": "Ventilation de la TVA (objet JSON), si renseignée."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créée le (Created at)."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "Modifiée le (Updated at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "number",
          "customer_id",
          "customer_name",
          "issue_date",
          "due_date",
          "currency",
          "subtotal",
          "tax_total",
          "total",
          "amount_paid",
          "status",
          "facturx_profile",
          "tva_details",
          "created_at",
          "updated_at"
        ],
        "title": "InvoiceOut",
        "description": "En-tête d'une facture client.",
        "examples": [
          {
            "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "number": "FA-2026-0001",
            "customer_id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
            "customer_name": "Client Exemple",
            "issue_date": "2026-01-05",
            "due_date": "2026-02-04",
            "currency": "XOF",
            "subtotal": "100000",
            "tax_total": "18000",
            "total": "118000",
            "amount_paid": "0",
            "status": "SENT",
            "facturx_profile": null,
            "tva_details": null,
            "created_at": "2026-01-05T08:00:03.023757Z",
            "updated_at": "2026-01-05T08:00:03.023757Z"
          }
        ],
        "x-tauraco-dataset": "invoices"
      },
      "JournalEntryList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/JournalEntryOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "JournalEntryList",
        "description": "Page d'écritures comptables.",
        "examples": [
          {
            "data": [
              {
                "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
                "journal_id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
                "entry_date": "2026-01-05",
                "piece_number": "VT-2026-0001",
                "reference": "FA-2026-0001",
                "description": "Facture FA-2026-0001",
                "currency": "XOF",
                "is_balanced": true,
                "fiscal_period_id": null,
                "source_type": "billing_invoice",
                "source_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                "created_at": "2026-01-05T08:00:04.031676Z",
                "lines": [
                  {
                    "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
                    "account_code": "411100",
                    "label": "Facture FA-2026-0001",
                    "debit": "118000",
                    "credit": "0",
                    "currency": "XOF"
                  },
                  {
                    "id": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f7a",
                    "account_code": "701100",
                    "label": "Facture FA-2026-0001",
                    "debit": "0",
                    "credit": "100000",
                    "currency": "XOF"
                  }
                ]
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "JournalEntryOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "journal_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Id",
            "description": "Journal (Journal)."
          },
          "entry_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Date",
            "description": "Date d'écriture (Entry date)."
          },
          "piece_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Piece Number",
            "description": "Numéro de pièce (Document number)."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Référence (Reference)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Libellé (Description)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "is_balanced": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Balanced",
            "description": "Équilibrée (Balanced)."
          },
          "fiscal_period_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fiscal Period Id",
            "description": "Période fiscale (Fiscal period)."
          },
          "source_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Type",
            "description": "Origine (Source type)."
          },
          "source_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Id",
            "description": "Pièce d'origine (Source document)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créée le (Created at)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/JournalLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "Lignes de l'écriture (débit et crédit).",
            "x-tauraco-derived": true
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "journal_id",
          "entry_date",
          "piece_number",
          "reference",
          "description",
          "currency",
          "is_balanced",
          "fiscal_period_id",
          "source_type",
          "source_id",
          "created_at",
          "lines"
        ],
        "title": "JournalEntryOut",
        "description": "Écriture comptable avec ses lignes.",
        "examples": [
          {
            "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
            "journal_id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
            "entry_date": "2026-01-05",
            "piece_number": "VT-2026-0001",
            "reference": "FA-2026-0001",
            "description": "Facture FA-2026-0001",
            "currency": "XOF",
            "is_balanced": true,
            "fiscal_period_id": null,
            "source_type": "billing_invoice",
            "source_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "created_at": "2026-01-05T08:00:04.031676Z",
            "lines": [
              {
                "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
                "account_code": "411100",
                "label": "Facture FA-2026-0001",
                "debit": "118000",
                "credit": "0",
                "currency": "XOF"
              },
              {
                "id": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f7a",
                "account_code": "701100",
                "label": "Facture FA-2026-0001",
                "debit": "0",
                "credit": "100000",
                "currency": "XOF"
              }
            ]
          }
        ],
        "x-tauraco-dataset": "journal_entries"
      },
      "JournalLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "account_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Code",
            "description": "Compte (Account)."
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label",
            "description": "Libellé (Label)."
          },
          "debit": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Debit",
            "description": "Débit (Debit)."
          },
          "credit": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit",
            "description": "Crédit (Credit)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "account_code",
          "label",
          "debit",
          "credit",
          "currency"
        ],
        "title": "JournalLineOut",
        "description": "Ligne d'une écriture comptable.",
        "examples": [
          {
            "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
            "account_code": "411100",
            "label": "Facture FA-2026-0001",
            "debit": "118000",
            "credit": "0",
            "currency": "XOF"
          }
        ],
        "x-tauraco-dataset": "journal_lines"
      },
      "LinksOut": {
        "properties": {
          "self": {
            "type": "string",
            "title": "Self"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "self"
        ],
        "title": "LinksOut",
        "examples": [
          {
            "self": "https://api.tauraco.io/public/v1/bank/requests/8c1d2e3f-4a5b-4c6d-9e7f-0a1b2c3d4e5f"
          }
        ]
      },
      "MeOut": {
        "properties": {
          "client_id": {
            "type": "string",
            "title": "Client Id",
            "description": "Identifiant public de l'application (tc_…)."
          },
          "client_name": {
            "type": "string",
            "title": "Client Name",
            "description": "Nom de l'application."
          },
          "client_kind": {
            "type": "string",
            "title": "Client Kind",
            "description": "Type d'application : partner, bank, mcp_client ou internal."
          },
          "company_id": {
            "type": "string",
            "title": "Company Id",
            "description": "Identifiant de l'entreprise qui a accordé l'accès (GET /companies/me)."
          },
          "grant_id": {
            "type": "string",
            "title": "Grant Id",
            "description": "Identifiant de l'autorisation (octroi) en cours."
          },
          "grant_flow": {
            "type": "string",
            "title": "Grant Flow",
            "description": "Flux de l'autorisation : client_credentials ou authorization_code."
          },
          "delegated": {
            "type": "boolean",
            "title": "Delegated",
            "description": "Vrai si l'accès est délégué par un utilisateur (authorization_code)."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "Scopes effectifs du jeton (jeton ∩ autorisation), triés."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "client_id",
          "client_name",
          "client_kind",
          "company_id",
          "grant_id",
          "grant_flow",
          "delegated",
          "scopes"
        ],
        "title": "MeOut",
        "description": "L'appelant : application, entreprise et autorisations portées par le jeton.",
        "examples": [
          {
            "client_id": "tc_live_abcdefghijklmnopqrstuvwx",
            "client_name": "Connecteur Exemple",
            "client_kind": "partner",
            "company_id": "8d3b6c1e-2f4a-4b7c-9e1d-5a6b7c8d9e0f",
            "grant_id": "0b9f8e7d-6c5b-4a39-8271-605f4e3d2c1b",
            "grant_flow": "client_credentials",
            "delegated": false,
            "scopes": [
              "company:read",
              "invoices:read"
            ]
          }
        ]
      },
      "PaymentList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/PaymentOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "PaymentList",
        "description": "Page d'encaissements.",
        "examples": [
          {
            "data": [
              {
                "id": "4d5e6f7a-8b9c-4d0e-a1f2-b3c4d5e6f7a8",
                "invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                "amount": "118000",
                "currency": "XOF",
                "method": "BANK_TRANSFER",
                "paid_at": "2026-01-20T14:00:00Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "PaymentOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "invoice_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Id",
            "description": "Facture (Invoice)."
          },
          "amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "Montant (Amount)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "Moyen de paiement (Payment method).",
            "x-enum-values": [
              "CASH",
              "BANK_TRANSFER",
              "MOBILE_MONEY",
              "CHECK",
              "CARD"
            ]
          },
          "paid_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Paid At",
            "description": "Payé le (Paid at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "invoice_id",
          "amount",
          "currency",
          "method",
          "paid_at"
        ],
        "title": "PaymentOut",
        "description": "Un encaissement client rattaché à une facture.",
        "examples": [
          {
            "id": "4d5e6f7a-8b9c-4d0e-a1f2-b3c4d5e6f7a8",
            "invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "amount": "118000",
            "currency": "XOF",
            "method": "BANK_TRANSFER",
            "paid_at": "2026-01-20T14:00:00Z"
          }
        ],
        "x-tauraco-dataset": "payments"
      },
      "ProductList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ProductOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "ProductList",
        "description": "Page de produits.",
        "examples": [
          {
            "data": [
              {
                "id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
                "name": "Prestation de conseil",
                "description": "Journée de conseil",
                "unit_price": "50000",
                "currency": "XOF",
                "tax_rate_bps": 1800,
                "unit": "jour",
                "active": true,
                "created_at": "2026-01-02T08:00:00.000003Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "ProductOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Nom (Name)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Description (Description)."
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Price",
            "description": "Prix unitaire HT (Unit price)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "tax_rate_bps": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate Bps",
            "description": "Taux de taxe (points de base) (Tax rate (basis points))."
          },
          "unit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit",
            "description": "Unité (Unit)."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "Actif (Active)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créé le (Created at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "name",
          "description",
          "unit_price",
          "currency",
          "tax_rate_bps",
          "unit",
          "active",
          "created_at"
        ],
        "title": "ProductOut",
        "description": "Un produit ou une prestation facturable.",
        "examples": [
          {
            "id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
            "name": "Prestation de conseil",
            "description": "Journée de conseil",
            "unit_price": "50000",
            "currency": "XOF",
            "tax_rate_bps": 1800,
            "unit": "jour",
            "active": true,
            "created_at": "2026-01-02T08:00:00.000003Z"
          }
        ],
        "x-tauraco-dataset": "products"
      },
      "PurchaseOrderList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/PurchaseOrderOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "PurchaseOrderList",
        "description": "Page de bons de commande.",
        "examples": [
          {
            "data": [
              {
                "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
                "po_number": "BC-2026-0007",
                "supplier_id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                "issue_date": "2026-01-03",
                "currency": "XOF",
                "total": "295000",
                "status": "CONFIRMED",
                "linked_bill_id": null,
                "created_at": "2026-01-03T09:00:00.000002Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "PurchaseOrderOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "po_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Po Number",
            "description": "Numéro (Number)."
          },
          "supplier_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Supplier Id",
            "description": "Fournisseur (Supplier)."
          },
          "issue_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Issue Date",
            "description": "Date d'émission (Issue date)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Total (Total)."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Statut (Status).",
            "x-enum-values": [
              "DRAFT",
              "SENT",
              "CONFIRMED",
              "RECEIVED",
              "CANCELLED"
            ]
          },
          "linked_bill_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Linked Bill Id",
            "description": "Facture fournisseur liée (Linked bill)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créé le (Created at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "po_number",
          "supplier_id",
          "issue_date",
          "currency",
          "total",
          "status",
          "linked_bill_id",
          "created_at"
        ],
        "title": "PurchaseOrderOut",
        "description": "Un bon de commande fournisseur.",
        "examples": [
          {
            "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
            "po_number": "BC-2026-0007",
            "supplier_id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
            "issue_date": "2026-01-03",
            "currency": "XOF",
            "total": "295000",
            "status": "CONFIRMED",
            "linked_bill_id": null,
            "created_at": "2026-01-03T09:00:00.000002Z"
          }
        ],
        "x-tauraco-dataset": "purchase_orders"
      },
      "ReconciliationIn": {
        "properties": {
          "reported_outstanding": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Reported Outstanding",
            "ge": 0
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of"
          },
          "matched_on": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Matched On"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "reported_outstanding",
          "as_of"
        ],
        "title": "ReconciliationIn",
        "description": "Encours annoncé par la banque à une date donnée (``as_of`` obligatoire, jamais défaulté)."
      },
      "ResolutionIn": {
        "properties": {
          "note": {
            "type": "string",
            "maxLength": 4000,
            "minLength": 1,
            "title": "Note"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "note"
        ],
        "title": "ResolutionIn"
      },
      "SupplierList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/SupplierOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "SupplierList",
        "description": "Page de fournisseurs.",
        "examples": [
          {
            "data": [
              {
                "id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
                "name": "Fournisseur Exemple",
                "city": "Abidjan",
                "country": "CI",
                "tax_id": "CI-0000000",
                "currency": "XOF",
                "payment_terms_days": 30,
                "status": "VALIDATED",
                "validated_at": "2026-01-06T09:30:00Z",
                "created_at": "2026-01-05T08:00:02.015838Z",
                "updated_at": "2026-01-06T09:30:00Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "SupplierOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Nom (Name)."
          },
          "city": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "City",
            "description": "Ville (City)."
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Pays (Country)."
          },
          "tax_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Id",
            "description": "Identifiant fiscal (Tax identifier)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Délai de paiement (jours) (Payment terms (days))."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Statut (Status).",
            "x-enum-values": [
              "DRAFT",
              "PENDING_VALIDATION",
              "VALIDATED",
              "SUSPENDED",
              "PAYMENT_UPDATE_PENDING"
            ]
          },
          "validated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Validated At",
            "description": "Validé le (Validated at)."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Créé le (Created at)."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "Modifié le (Updated at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "name",
          "city",
          "country",
          "tax_id",
          "currency",
          "payment_terms_days",
          "status",
          "validated_at",
          "created_at",
          "updated_at"
        ],
        "title": "SupplierOut",
        "description": "Un fournisseur de l'entreprise.",
        "examples": [
          {
            "id": "6a5b4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
            "name": "Fournisseur Exemple",
            "city": "Abidjan",
            "country": "CI",
            "tax_id": "CI-0000000",
            "currency": "XOF",
            "payment_terms_days": 30,
            "status": "VALIDATED",
            "validated_at": "2026-01-06T09:30:00Z",
            "created_at": "2026-01-05T08:00:02.015838Z",
            "updated_at": "2026-01-06T09:30:00Z"
          }
        ],
        "x-tauraco-dataset": "suppliers"
      },
      "TenderAmendmentOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "seen_at": {
            "type": "string",
            "format": "date-time",
            "title": "Seen At"
          },
          "kind": {
            "type": "string",
            "title": "Kind"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "seen_at",
          "kind"
        ],
        "title": "TenderAmendmentOut",
        "description": "Modificatif d'un avis : date et nature (sans le détail libre).",
        "examples": [
          {
            "id": "amd-1",
            "seen_at": "2026-01-12T06:00:00Z",
            "kind": "deadline"
          }
        ]
      },
      "TenderDetailOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Slug",
            "description": "Référence de l'avis (Notice slug)."
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title",
            "description": "Objet (Title)."
          },
          "summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary",
            "description": "Résumé (Summary)."
          },
          "buyer_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Name",
            "description": "Acheteur (Buyer)."
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Pays (Country)."
          },
          "region": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Region",
            "description": "Région (Region)."
          },
          "sector": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sector",
            "description": "Secteur (Sector)."
          },
          "notice_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notice Type",
            "description": "Type d'avis (Notice type)."
          },
          "procedure_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Procedure Type",
            "description": "Procédure (Procedure)."
          },
          "tender_kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tender Kind",
            "description": "Nature (Kind)."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Statut (Status).",
            "x-enum-values": [
              "open",
              "closed",
              "cancelled",
              "awarded",
              "unknown"
            ]
          },
          "is_expired": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Expired",
            "description": "Échu (Expired)."
          },
          "can_apply": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Can Apply",
            "description": "Candidature possible (Open to applications)."
          },
          "published_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published At",
            "description": "Publié le (Published at)."
          },
          "deadline_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deadline At",
            "description": "Date limite (Deadline)."
          },
          "deadline_tz": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deadline Tz",
            "description": "Fuseau de la date limite (Deadline time zone)."
          },
          "budget_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Valeur décimale, en chaîne.",
                "examples": [
                  "12.5"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Budget Amount",
            "description": "Budget estimé (Estimated budget)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "source_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Name",
            "description": "Source (Source)."
          },
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Url",
            "description": "Avis officiel (Official notice)."
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "Page Tauraco (Tauraco page)."
          },
          "first_seen_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Seen At",
            "description": "Repéré le (First seen at)."
          },
          "last_seen_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Seen At",
            "description": "Vu pour la dernière fois le (Last seen at)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Description de l'avis.",
            "x-tauraco-derived": true
          },
          "eligibility": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Eligibility",
            "description": "Conditions d'éligibilité.",
            "x-tauraco-derived": true
          },
          "external_ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Ref",
            "description": "Référence de l'avis chez l'acheteur.",
            "x-tauraco-derived": true
          },
          "documents": {
            "items": {
              "$ref": "#/components/schemas/TenderDocumentOut"
            },
            "type": "array",
            "title": "Documents",
            "description": "Pièces publiées.",
            "x-tauraco-derived": true
          },
          "amendments": {
            "items": {
              "$ref": "#/components/schemas/TenderAmendmentOut"
            },
            "type": "array",
            "title": "Amendments",
            "description": "Modificatifs publiés.",
            "x-tauraco-derived": true
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "slug",
          "title",
          "summary",
          "buyer_name",
          "country",
          "region",
          "sector",
          "notice_type",
          "procedure_type",
          "tender_kind",
          "status",
          "is_expired",
          "can_apply",
          "published_at",
          "deadline_at",
          "deadline_tz",
          "budget_amount",
          "currency",
          "source_name",
          "source_url",
          "url",
          "first_seen_at",
          "last_seen_at",
          "description",
          "eligibility",
          "external_ref",
          "documents",
          "amendments"
        ],
        "title": "TenderDetailOut",
        "description": "Fiche d'un avis de marché public (donnée externe non vérifiée).",
        "examples": [
          {
            "id": "tnd_0001",
            "slug": "rehabilitation-route-exemple-2026",
            "title": "Réhabilitation d'une route communale",
            "summary": "Travaux de réhabilitation.",
            "buyer_name": "Commune Exemple",
            "country": "ML",
            "region": null,
            "sector": "travaux",
            "notice_type": "appel_offres",
            "procedure_type": "ouvert",
            "tender_kind": "travaux",
            "status": "open",
            "is_expired": false,
            "can_apply": true,
            "published_at": "2026-01-10T00:00:00Z",
            "deadline_at": "2026-02-10T17:00:00Z",
            "deadline_tz": "Africa/Bamako",
            "budget_amount": "150000000",
            "currency": "XOF",
            "source_name": "Journal officiel (exemple)",
            "source_url": "https://marches.example.org/avis/1",
            "url": "https://tauraco.io/marches/rehabilitation-route-exemple-2026",
            "first_seen_at": "2026-01-10T06:00:00Z",
            "last_seen_at": "2026-01-12T06:00:00Z",
            "description": "Travaux de réhabilitation de la route.",
            "eligibility": "Agrément B",
            "external_ref": "AO-2026-001",
            "documents": [
              {
                "title": "Dossier d'appel d'offres",
                "url": "https://marches.example.org/dao/1.pdf"
              }
            ],
            "amendments": [
              {
                "id": "amd-1",
                "seen_at": "2026-01-12T06:00:00Z",
                "kind": "deadline"
              }
            ]
          }
        ],
        "x-tauraco-dataset": "tenders"
      },
      "TenderDocumentOut": {
        "properties": {
          "title": {
            "type": "string",
            "title": "Title"
          },
          "url": {
            "type": "string",
            "title": "Url"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "title",
          "url"
        ],
        "title": "TenderDocumentOut",
        "description": "Pièce d'un avis : intitulé et lien.",
        "examples": [
          {
            "title": "Dossier d'appel d'offres",
            "url": "https://marches.example.org/dao/1.pdf"
          }
        ]
      },
      "TenderList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/TenderOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "TenderList",
        "description": "Page d'avis de marchés publics.",
        "examples": [
          {
            "data": [
              {
                "id": "tnd_0001",
                "slug": "rehabilitation-route-exemple-2026",
                "title": "Réhabilitation d'une route communale",
                "summary": "Travaux de réhabilitation.",
                "buyer_name": "Commune Exemple",
                "country": "ML",
                "region": null,
                "sector": "travaux",
                "notice_type": "appel_offres",
                "procedure_type": "ouvert",
                "tender_kind": "travaux",
                "status": "open",
                "is_expired": false,
                "can_apply": true,
                "published_at": "2026-01-10T00:00:00Z",
                "deadline_at": "2026-02-10T17:00:00Z",
                "deadline_tz": "Africa/Bamako",
                "budget_amount": "150000000",
                "currency": "XOF",
                "source_name": "Journal officiel (exemple)",
                "source_url": "https://marches.example.org/avis/1",
                "url": "https://tauraco.io/marches/rehabilitation-route-exemple-2026",
                "first_seen_at": "2026-01-10T06:00:00Z",
                "last_seen_at": "2026-01-12T06:00:00Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "TenderOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant (Identifier)."
          },
          "slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Slug",
            "description": "Référence de l'avis (Notice slug)."
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title",
            "description": "Objet (Title)."
          },
          "summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary",
            "description": "Résumé (Summary)."
          },
          "buyer_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Name",
            "description": "Acheteur (Buyer)."
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Pays (Country)."
          },
          "region": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Region",
            "description": "Région (Region)."
          },
          "sector": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sector",
            "description": "Secteur (Sector)."
          },
          "notice_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notice Type",
            "description": "Type d'avis (Notice type)."
          },
          "procedure_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Procedure Type",
            "description": "Procédure (Procedure)."
          },
          "tender_kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tender Kind",
            "description": "Nature (Kind)."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Statut (Status).",
            "x-enum-values": [
              "open",
              "closed",
              "cancelled",
              "awarded",
              "unknown"
            ]
          },
          "is_expired": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Expired",
            "description": "Échu (Expired)."
          },
          "can_apply": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Can Apply",
            "description": "Candidature possible (Open to applications)."
          },
          "published_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published At",
            "description": "Publié le (Published at)."
          },
          "deadline_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deadline At",
            "description": "Date limite (Deadline)."
          },
          "deadline_tz": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deadline Tz",
            "description": "Fuseau de la date limite (Deadline time zone)."
          },
          "budget_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Valeur décimale, en chaîne.",
                "examples": [
                  "12.5"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Budget Amount",
            "description": "Budget estimé (Estimated budget)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "source_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Name",
            "description": "Source (Source)."
          },
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Url",
            "description": "Avis officiel (Official notice)."
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "Page Tauraco (Tauraco page)."
          },
          "first_seen_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Seen At",
            "description": "Repéré le (First seen at)."
          },
          "last_seen_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Seen At",
            "description": "Vu pour la dernière fois le (Last seen at)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "slug",
          "title",
          "summary",
          "buyer_name",
          "country",
          "region",
          "sector",
          "notice_type",
          "procedure_type",
          "tender_kind",
          "status",
          "is_expired",
          "can_apply",
          "published_at",
          "deadline_at",
          "deadline_tz",
          "budget_amount",
          "currency",
          "source_name",
          "source_url",
          "url",
          "first_seen_at",
          "last_seen_at"
        ],
        "title": "TenderOut",
        "description": "Un avis de marché public (donnée externe non vérifiée).",
        "examples": [
          {
            "id": "tnd_0001",
            "slug": "rehabilitation-route-exemple-2026",
            "title": "Réhabilitation d'une route communale",
            "summary": "Travaux de réhabilitation.",
            "buyer_name": "Commune Exemple",
            "country": "ML",
            "region": null,
            "sector": "travaux",
            "notice_type": "appel_offres",
            "procedure_type": "ouvert",
            "tender_kind": "travaux",
            "status": "open",
            "is_expired": false,
            "can_apply": true,
            "published_at": "2026-01-10T00:00:00Z",
            "deadline_at": "2026-02-10T17:00:00Z",
            "deadline_tz": "Africa/Bamako",
            "budget_amount": "150000000",
            "currency": "XOF",
            "source_name": "Journal officiel (exemple)",
            "source_url": "https://marches.example.org/avis/1",
            "url": "https://tauraco.io/marches/rehabilitation-route-exemple-2026",
            "first_seen_at": "2026-01-10T06:00:00Z",
            "last_seen_at": "2026-01-12T06:00:00Z"
          }
        ],
        "x-tauraco-dataset": "tenders"
      },
      "TrialBalance": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/TrialBalanceLineOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "TrialBalance",
        "description": "Page de la balance générale.",
        "examples": [
          {
            "data": [
              {
                "account_code": "411100",
                "account_name": "Clients",
                "debit_total": "118000",
                "credit_total": "0",
                "debit_balance": "118000",
                "credit_balance": "0",
                "currency": "XOF",
                "period_start": "2026-01-01",
                "period_end": "2026-01-31"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "TrialBalanceLineOut": {
        "properties": {
          "account_code": {
            "type": "string",
            "title": "Account Code",
            "description": "Compte (Account)."
          },
          "account_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Name",
            "description": "Intitulé (Account name)."
          },
          "debit_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Debit Total",
            "description": "Mouvements débit (Total debits)."
          },
          "credit_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Total",
            "description": "Mouvements crédit (Total credits)."
          },
          "debit_balance": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Debit Balance",
            "description": "Solde débiteur (Debit balance)."
          },
          "credit_balance": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$",
                "description": "Montant en unités majeures de la devise, en chaîne décimale.",
                "examples": [
                  "150000"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Balance",
            "description": "Solde créditeur (Credit balance)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Devise (Currency)."
          },
          "period_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period Start",
            "description": "Début de période (Period start)."
          },
          "period_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period End",
            "description": "Fin de période (Period end)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "account_code",
          "account_name",
          "debit_total",
          "credit_total",
          "debit_balance",
          "credit_balance",
          "currency",
          "period_start",
          "period_end"
        ],
        "title": "TrialBalanceLineOut",
        "description": "Solde d'un compte sur la période demandée (balance générale).",
        "examples": [
          {
            "account_code": "411100",
            "account_name": "Clients",
            "debit_total": "118000",
            "credit_total": "0",
            "debit_balance": "118000",
            "credit_balance": "0",
            "currency": "XOF",
            "period_start": "2026-01-01",
            "period_end": "2026-01-31"
          }
        ],
        "x-tauraco-dataset": "trial_balance"
      },
      "WebhookDeliveryList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/WebhookDeliveryOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "WebhookDeliveryList",
        "description": "Livraisons d'un endpoint, les plus récentes d'abord.",
        "examples": [
          {
            "data": [
              {
                "id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
                "event_id": "evt_3f2a9c0d6b1e4a7f8c5d2e1b0a9f8e7d",
                "event_type": "invoice.paid",
                "status": "DELIVERED",
                "attempts": 1,
                "max_attempts": 7,
                "next_retry_at": null,
                "last_status_code": 200,
                "last_error": null,
                "delivered_at": "2026-01-05T08:00:01Z",
                "replayed_from_id": null,
                "created_at": "2026-01-05T08:00:00Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "WebhookDeliveryOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant de la livraison (UUID)."
          },
          "event_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Event Id",
            "description": "Identifiant de l'événement (evt_…), identique pour un rejeu."
          },
          "event_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Event Type",
            "description": "Type d'événement."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "PENDING, DELIVERING, DELIVERED, DEAD, CANCELLED, FAILED ou EXHAUSTED."
          },
          "attempts": {
            "type": "integer",
            "title": "Attempts",
            "description": "Tentatives effectuées."
          },
          "max_attempts": {
            "type": "integer",
            "title": "Max Attempts",
            "description": "Tentatives au plus."
          },
          "next_retry_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Retry At",
            "description": "Prochaine tentative."
          },
          "last_status_code": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Status Code",
            "description": "Dernier statut HTTP reçu."
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Error",
            "description": "Dernière erreur (générique)."
          },
          "delivered_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivered At",
            "description": "Livraison réussie (UTC)."
          },
          "replayed_from_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Replayed From Id",
            "description": "Livraison rejouée, s'il y a lieu."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Création (UTC)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "event_id",
          "event_type",
          "status",
          "attempts",
          "max_attempts",
          "next_retry_at",
          "last_status_code",
          "last_error",
          "delivered_at",
          "replayed_from_id",
          "created_at"
        ],
        "title": "WebhookDeliveryOut",
        "description": "Une livraison d'événement vers un endpoint (sans la charge utile).",
        "examples": [
          {
            "id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
            "event_id": "evt_3f2a9c0d6b1e4a7f8c5d2e1b0a9f8e7d",
            "event_type": "invoice.paid",
            "status": "DELIVERED",
            "attempts": 1,
            "max_attempts": 7,
            "next_retry_at": null,
            "last_status_code": 200,
            "last_error": null,
            "delivered_at": "2026-01-05T08:00:01Z",
            "replayed_from_id": null,
            "created_at": "2026-01-05T08:00:00Z"
          }
        ]
      },
      "WebhookEndpointList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/WebhookEndpointOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "WebhookEndpointList",
        "description": "Endpoints du client, du plus récent au plus ancien (page unique).",
        "examples": [
          {
            "data": [
              {
                "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                "url": "https://integrations.exemple.test/tauraco/webhooks",
                "events": [
                  "invoice.paid",
                  "payment.recorded"
                ],
                "description": "ERP du groupe",
                "is_active": true,
                "api_version": "v2",
                "secret_hint": "…a1b2",
                "failure_count": 0,
                "failing_since": null,
                "disabled_at": null,
                "disabled_reason": null,
                "created_at": "2026-01-05T08:00:00Z"
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "WebhookEndpointOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant de l'endpoint (UUID)."
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "URL HTTPS de réception ; null dans une réponse rejouée."
          },
          "events": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Events",
            "description": "Types d'événements abonnés."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description libre."
          },
          "is_active": {
            "type": "boolean",
            "title": "Is Active",
            "description": "Vrai si l'endpoint reçoit les livraisons."
          },
          "api_version": {
            "type": "string",
            "title": "Api Version",
            "description": "Version de l'enveloppe (v2)."
          },
          "secret_hint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Secret Hint",
            "description": "Quatre derniers caractères du secret de signature."
          },
          "failure_count": {
            "type": "integer",
            "title": "Failure Count",
            "description": "Échecs consécutifs de livraison."
          },
          "failing_since": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Failing Since",
            "description": "Premier échec de la série en cours."
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disabled At",
            "description": "Désactivation (manuelle ou automatique)."
          },
          "disabled_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disabled Reason",
            "description": "manual ou delivery_failures."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Création (UTC)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "url",
          "events",
          "description",
          "is_active",
          "api_version",
          "secret_hint",
          "failure_count",
          "failing_since",
          "disabled_at",
          "disabled_reason",
          "created_at"
        ],
        "title": "WebhookEndpointOut",
        "description": "Un endpoint de webhook v2 du client (jamais son secret).",
        "examples": [
          {
            "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
            "url": "https://integrations.exemple.test/tauraco/webhooks",
            "events": [
              "invoice.paid",
              "payment.recorded"
            ],
            "description": "ERP du groupe",
            "is_active": true,
            "api_version": "v2",
            "secret_hint": "…a1b2",
            "failure_count": 0,
            "failing_since": null,
            "disabled_at": null,
            "disabled_reason": null,
            "created_at": "2026-01-05T08:00:00Z"
          }
        ]
      },
      "WebhookEndpointSecretOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifiant de l'endpoint (UUID)."
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "URL HTTPS de réception ; null dans une réponse rejouée."
          },
          "events": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Events",
            "description": "Types d'événements abonnés."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description libre."
          },
          "is_active": {
            "type": "boolean",
            "title": "Is Active",
            "description": "Vrai si l'endpoint reçoit les livraisons."
          },
          "api_version": {
            "type": "string",
            "title": "Api Version",
            "description": "Version de l'enveloppe (v2)."
          },
          "secret_hint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Secret Hint",
            "description": "Quatre derniers caractères du secret de signature."
          },
          "failure_count": {
            "type": "integer",
            "title": "Failure Count",
            "description": "Échecs consécutifs de livraison."
          },
          "failing_since": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Failing Since",
            "description": "Premier échec de la série en cours."
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disabled At",
            "description": "Désactivation (manuelle ou automatique)."
          },
          "disabled_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disabled Reason",
            "description": "manual ou delivery_failures."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "Création (UTC)."
          },
          "secret": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Secret",
            "description": "Secret de signature whsec_… : affiché une seule fois, à conserver ; null dans une réponse rejouée."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "url",
          "events",
          "description",
          "is_active",
          "api_version",
          "secret_hint",
          "failure_count",
          "failing_since",
          "disabled_at",
          "disabled_reason",
          "created_at",
          "secret"
        ],
        "title": "WebhookEndpointSecretOut",
        "description": "Endpoint et secret de signature, rendu une seule fois (création, rotation).",
        "examples": [
          {
            "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
            "url": "https://integrations.exemple.test/tauraco/webhooks",
            "events": [
              "invoice.paid",
              "payment.recorded"
            ],
            "description": "ERP du groupe",
            "is_active": true,
            "api_version": "v2",
            "secret_hint": "…a1b2",
            "failure_count": 0,
            "failing_since": null,
            "disabled_at": null,
            "disabled_reason": null,
            "created_at": "2026-01-05T08:00:00Z",
            "secret": "whsec_exemple0000000000000000000000000000"
          }
        ]
      },
      "WebhookEventTypeList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/WebhookEventTypeOut"
            },
            "type": "array",
            "title": "Data",
            "description": "Éléments de la page, dans l'ordre de la clé stable."
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor",
            "description": "Curseur de la page suivante ; null sur la dernière page."
          },
          "has_more": {
            "type": "boolean",
            "title": "Has More",
            "description": "Vrai s'il reste au moins un élément après cette page."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "title": "WebhookEventTypeList",
        "description": "Types d'événements auxquels le client peut s'abonner (page unique).",
        "examples": [
          {
            "data": [
              {
                "type": "invoice.paid",
                "label": "Facture réglée",
                "read_scope": "invoices:read",
                "amounts": true
              }
            ],
            "next_cursor": "c1.eyJkIjoiaW52b2ljZXMiLCJmIjoiNDRhMSIsImsiOltdLCJvIjoiYXNjIn0.q83vEjRWeJA",
            "has_more": true
          }
        ]
      },
      "WebhookEventTypeOut": {
        "properties": {
          "type": {
            "type": "string",
            "title": "Type",
            "description": "Type d'événement."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Libellé (Accept-Language: en pour l'anglais)."
          },
          "read_scope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Read Scope",
            "description": "Scope de lecture exigé pour s'abonner."
          },
          "amounts": {
            "type": "boolean",
            "title": "Amounts",
            "description": "Vrai si la charge utile porte des montants."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "type",
          "label",
          "read_scope",
          "amounts"
        ],
        "title": "WebhookEventTypeOut",
        "description": "Un type d'événement auquel le client peut s'abonner.",
        "examples": [
          {
            "type": "invoice.paid",
            "label": "Facture réglée",
            "read_scope": "invoices:read",
            "amounts": true
          }
        ]
      },
      "WebhookTestOut": {
        "properties": {
          "event_id": {
            "type": "string",
            "title": "Event Id",
            "description": "Identifiant de l'événement webhook.test."
          },
          "delivery_id": {
            "type": "string",
            "title": "Delivery Id",
            "description": "Livraison créée vers cet endpoint seul."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "event_id",
          "delivery_id"
        ],
        "title": "WebhookTestOut",
        "description": "Événement de test émis et sa livraison.",
        "examples": [
          {
            "event_id": "evt_0a1b2c3d4e5f60718293a4b5c6d7e8f9",
            "delivery_id": "8c9d0e1f-2a3b-4c4d-8e5f-6a7b8c9d0e1f"
          }
        ]
      },
      "ProblemDetails": {
        "description": "Corps RFC 9457 ``application/problem+json`` de toute erreur de ``/public/v1``.",
        "examples": [
          {
            "code": "insufficient_scope",
            "detail": "Le jeton ne porte pas invoices:read.",
            "instance": "/public/v1/invoices",
            "request_id": "5b0c2a1e-8f3d-4c55-9a51-0d7e6f1b2c3d",
            "required_scopes": [
              "invoices:read"
            ],
            "status": 403,
            "title": "Scope insuffisant",
            "type": "https://docs.tauraco.ai/developers/erreurs#insufficient_scope"
          }
        ],
        "properties": {
          "type": {
            "description": "URI de la documentation du code d'erreur.",
            "title": "Type",
            "type": "string"
          },
          "title": {
            "description": "Intitulé du code d'erreur.",
            "title": "Title",
            "type": "string"
          },
          "status": {
            "description": "Statut HTTP.",
            "title": "Status",
            "type": "integer"
          },
          "detail": {
            "description": "Message destiné à l'appelant ; jamais de détail interne.",
            "title": "Detail",
            "type": "string"
          },
          "instance": {
            "description": "Chemin de la requête.",
            "title": "Instance",
            "type": "string"
          },
          "code": {
            "description": "Code de la liste fermée (CONTRATS §2.3).",
            "title": "Code",
            "type": "string"
          },
          "request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Identifiant de corrélation (X-Request-Id).",
            "title": "Request Id"
          },
          "errors": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ProblemFieldError"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Erreurs par champ (422).",
            "title": "Errors"
          },
          "retry_after": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Secondes avant de réessayer (429, 503).",
            "title": "Retry After"
          },
          "required_scopes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Scopes manquants (403).",
            "title": "Required Scopes"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "code"
        ],
        "title": "ProblemDetails",
        "type": "object"
      },
      "ProblemFieldError": {
        "description": "Erreur de validation d'un champ ou d'un filtre.",
        "properties": {
          "field": {
            "description": "Nom du champ, du filtre ou du paramètre en cause.",
            "title": "Field",
            "type": "string"
          },
          "message": {
            "description": "Explication lisible.",
            "title": "Message",
            "type": "string"
          }
        },
        "required": [
          "field",
          "message"
        ],
        "title": "ProblemFieldError",
        "type": "object"
      },
      "CustomerCreate": {
        "additionalProperties": false,
        "description": "Corps de ``POST /customers`` : un nouveau client de l'entreprise.",
        "examples": [
          {
            "city": "Dakar",
            "country": "SN",
            "currency": "XOF",
            "email": "comptabilite@client-exemple.test",
            "legal_name": "Client Exemple SA",
            "name": "Client Exemple",
            "tax_id": "SN-0000000"
          }
        ],
        "properties": {
          "name": {
            "description": "Nom d'usage du client.",
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "legal_name": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Raison sociale.",
            "title": "Legal Name"
          },
          "email": {
            "anyOf": [
              {
                "maxLength": 255,
                "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "E-mail de facturation (écrit, jamais relu par l'API).",
            "title": "Email"
          },
          "phone": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Téléphone (écrit, jamais relu par l'API).",
            "title": "Phone"
          },
          "address": {
            "anyOf": [
              {
                "maxLength": 1000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Adresse postale (écrite, jamais relue par l'API).",
            "title": "Address"
          },
          "postal_code": {
            "anyOf": [
              {
                "maxLength": 16,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Code postal (jamais relu).",
            "title": "Postal Code"
          },
          "city": {
            "anyOf": [
              {
                "maxLength": 128,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Ville.",
            "title": "City"
          },
          "country": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Pays (code ISO 3166-1 alpha-2 conseillé).",
            "title": "Country"
          },
          "tax_id": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Identifiant fiscal (NIF, NINEA…).",
            "title": "Tax Id"
          },
          "currency": {
            "default": "XOF",
            "description": "Devise de facturation (ISO 4217).",
            "pattern": "^[A-Z]{3}$",
            "title": "Currency",
            "type": "string"
          },
          "siren": {
            "anyOf": [
              {
                "pattern": "^\\d{9}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "SIREN (France).",
            "title": "Siren"
          },
          "siret": {
            "anyOf": [
              {
                "pattern": "^\\d{14}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "SIRET (France).",
            "title": "Siret"
          },
          "tva_intra": {
            "anyOf": [
              {
                "maxLength": 15,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Numéro de TVA intracommunautaire.",
            "title": "Tva Intra"
          },
          "einvoicing_routing_code": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Code de routage de facturation électronique.",
            "title": "Einvoicing Routing Code"
          }
        },
        "required": [
          "name"
        ],
        "title": "CustomerCreate",
        "type": "object"
      },
      "ExportDatasetRequest": {
        "additionalProperties": false,
        "description": "Un jeu d'un export : code, colonnes (``None`` = colonnes par défaut), filtres.",
        "properties": {
          "dataset": {
            "maxLength": 64,
            "minLength": 1,
            "title": "Dataset",
            "type": "string"
          },
          "columns": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "maxItems": 200,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "title": "Columns"
          },
          "filters": {
            "additionalProperties": true,
            "title": "Filters",
            "type": "object"
          }
        },
        "required": [
          "dataset"
        ],
        "title": "ExportDatasetRequest",
        "type": "object"
      },
      "ExportRequest": {
        "additionalProperties": false,
        "description": "Demande d'export (``POST /v1/hub/exports``, API publique, MCP, planification).",
        "properties": {
          "datasets": {
            "items": {
              "$ref": "#/components/schemas/ExportDatasetRequest"
            },
            "maxItems": 10,
            "minItems": 1,
            "title": "Datasets",
            "type": "array"
          },
          "format": {
            "maxLength": 24,
            "minLength": 1,
            "title": "Format",
            "type": "string"
          },
          "format_options": {
            "additionalProperties": true,
            "title": "Format Options",
            "type": "object"
          },
          "include_pii": {
            "default": false,
            "title": "Include Pii",
            "type": "boolean"
          },
          "file_name": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "title": "File Name"
          },
          "delivery": {
            "default": "download",
            "maxLength": 64,
            "title": "Delivery",
            "type": "string"
          },
          "template_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "title": "Template Id"
          }
        },
        "required": [
          "datasets",
          "format"
        ],
        "title": "ExportRequest",
        "type": "object"
      },
      "InvoiceLineCreate": {
        "additionalProperties": false,
        "description": "Une ligne d'une facture à créer ; montants en unités majeures de la devise de la facture.",
        "examples": [
          {
            "description": "Prestation de conseil",
            "product_id": null,
            "quantity": 2,
            "tax_rate_bps": 1800,
            "unit_price": "50000"
          }
        ],
        "properties": {
          "description": {
            "description": "Libellé de la ligne.",
            "maxLength": 1000,
            "minLength": 1,
            "title": "Description",
            "type": "string"
          },
          "quantity": {
            "default": 1,
            "description": "Quantité (entier, au moins 1).",
            "maximum": 1000000,
            "minimum": 1,
            "title": "Quantity",
            "type": "integer"
          },
          "unit_price": {
            "description": "Prix unitaire hors taxes, en unités majeures de la devise.",
            "examples": [
              "150000"
            ],
            "pattern": "^\\d+(\\.\\d+)?$",
            "title": "Unit Price",
            "type": "string"
          },
          "tax_rate_bps": {
            "default": 1800,
            "description": "Taux de TVA en points de base (1800 = 18 %).",
            "maximum": 10000,
            "minimum": 0,
            "title": "Tax Rate Bps",
            "type": "integer"
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Produit du catalogue de l'entreprise (UUID), facultatif.",
            "title": "Product Id"
          }
        },
        "required": [
          "description",
          "unit_price"
        ],
        "title": "InvoiceLineCreate",
        "type": "object"
      },
      "InvoiceCreate": {
        "additionalProperties": false,
        "description": "Corps de ``POST /invoices`` : une facture client, créée en brouillon par le service de facturation.",
        "examples": [
          {
            "currency": "XOF",
            "customer_id": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
            "due_date": "2026-02-04",
            "issue_date": "2026-01-05",
            "lines": [
              {
                "description": "Prestation de conseil",
                "product_id": null,
                "quantity": 2,
                "tax_rate_bps": 1800,
                "unit_price": "50000"
              }
            ]
          }
        ],
        "properties": {
          "customer_id": {
            "description": "Client de l'entreprise (UUID, GET /customers).",
            "title": "Customer Id",
            "type": "string"
          },
          "issue_date": {
            "description": "Date d'émission (AAAA-MM-JJ).",
            "format": "date",
            "title": "Issue Date",
            "type": "string"
          },
          "due_date": {
            "description": "Date d'échéance (AAAA-MM-JJ), au plus tôt la date d'émission.",
            "format": "date",
            "title": "Due Date",
            "type": "string"
          },
          "currency": {
            "default": "XOF",
            "description": "Devise de la facture (ISO 4217).",
            "pattern": "^[A-Z]{3}$",
            "title": "Currency",
            "type": "string"
          },
          "lines": {
            "description": "Lignes de la facture (1 à 500).",
            "items": {
              "$ref": "#/components/schemas/InvoiceLineCreate"
            },
            "maxItems": 500,
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "customer_id",
          "issue_date",
          "due_date",
          "lines"
        ],
        "title": "InvoiceCreate",
        "type": "object"
      },
      "PaymentCreate": {
        "additionalProperties": false,
        "description": "Corps de ``POST /payments`` : un encaissement sur une facture client.",
        "examples": [
          {
            "amount": "118000",
            "bank_account_id": null,
            "invoice_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "method": "BANK_TRANSFER",
            "paid_on": "2026-01-20",
            "reference": "VIR-2026-0042"
          }
        ],
        "properties": {
          "invoice_id": {
            "description": "Facture client encaissée (UUID).",
            "title": "Invoice Id",
            "type": "string"
          },
          "amount": {
            "description": "Montant encaissé, en unités majeures de la devise de la facture ; au plus le reste dû.",
            "examples": [
              "150000"
            ],
            "pattern": "^\\d+(\\.\\d+)?$",
            "title": "Amount",
            "type": "string"
          },
          "method": {
            "default": "BANK_TRANSFER",
            "description": "Mode d'encaissement.",
            "enum": [
              "CASH",
              "BANK_TRANSFER",
              "MOBILE_MONEY",
              "CHECK",
              "CARD"
            ],
            "title": "Method",
            "type": "string"
          },
          "paid_on": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Date de l'encaissement (jamais future ; défaut : aujourd'hui).",
            "title": "Paid On"
          },
          "bank_account_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Compte de trésorerie de l'entreprise crédité (UUID) ; défaut : compte 521.",
            "title": "Bank Account Id"
          },
          "reference": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Référence du virement ou de la transaction (écrite, jamais relue).",
            "title": "Reference"
          }
        },
        "required": [
          "invoice_id",
          "amount"
        ],
        "title": "PaymentCreate",
        "type": "object"
      },
      "WebhookEndpointCreate": {
        "additionalProperties": false,
        "description": "Corps de ``POST /webhooks``.",
        "examples": [
          {
            "description": "ERP du groupe",
            "events": [
              "invoice.paid",
              "payment.recorded"
            ],
            "url": "https://integrations.exemple.test/tauraco/webhooks"
          }
        ],
        "properties": {
          "url": {
            "description": "URL HTTPS publique de réception.",
            "maxLength": 1024,
            "minLength": 1,
            "title": "Url",
            "type": "string"
          },
          "events": {
            "description": "Types d'événements (GET /webhooks/event-types).",
            "items": {
              "type": "string"
            },
            "maxItems": 32,
            "minItems": 1,
            "title": "Events",
            "type": "array"
          },
          "description": {
            "default": "",
            "description": "Description libre.",
            "maxLength": 255,
            "title": "Description",
            "type": "string"
          }
        },
        "required": [
          "url",
          "events"
        ],
        "title": "WebhookEndpointCreate",
        "type": "object"
      },
      "WebhookEndpointUpdate": {
        "additionalProperties": false,
        "description": "Corps de ``PATCH /webhooks/{endpoint_id}`` (champs absents inchangés).",
        "examples": [
          {
            "events": [
              "invoice.created",
              "invoice.paid"
            ]
          }
        ],
        "properties": {
          "url": {
            "anyOf": [
              {
                "maxLength": 1024,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Nouvelle URL (revalidée).",
            "title": "Url"
          },
          "events": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "maxItems": 32,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Nouveaux types.",
            "title": "Events"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Nouvelle description.",
            "title": "Description"
          }
        },
        "title": "WebhookEndpointUpdate",
        "type": "object"
      }
    },
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 : client credentials (application d'entreprise) ou authorization code avec PKCE S256 (accès délégué par un utilisateur).",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://api.tauraco.io/oauth/token",
            "scopes": {
              "company:read": "Lire le profil de l'entreprise",
              "customers:read": "Lire les clients",
              "customers:write": "Créer des clients",
              "suppliers:read": "Lire les fournisseurs",
              "invoices:read": "Lire les factures clients",
              "invoices:write": "Créer des factures clients",
              "bills:read": "Lire les factures fournisseurs",
              "accounting:read": "Lire la comptabilité",
              "payments:read": "Lire les encaissements",
              "payments:write": "Enregistrer des encaissements",
              "treasury:read": "Lire la trésorerie",
              "purchases:read": "Lire les commandes d'achat",
              "products:read": "Lire les produits",
              "inventory:read": "Lire les stocks",
              "tenders:read": "Lire les appels d'offres",
              "markets:read": "Lire les marchés",
              "financing:read": "Lire les demandes de financement",
              "documents:read": "Télécharger les pièces",
              "guarantees:read": "Lire les garanties",
              "collateral:read": "Lire les dépôts de garantie",
              "exports:read": "Lire les exports",
              "exports:write": "Demander des exports",
              "webhooks:manage": "Gérer les webhooks",
              "bank:inbox:read": "Lire la boîte de réception bancaire",
              "bank:requests:read": "Lire les dossiers de financement reçus",
              "bank:documents:read": "Télécharger les pièces des dossiers",
              "bank:info-requests:write": "Demander des compléments",
              "bank:collateral:read": "Lire les garanties des dossiers",
              "bank:repayments:read": "Lire les remboursements",
              "bank:reconciliation:write": "Rapprocher les remboursements"
            }
          },
          "authorizationCode": {
            "authorizationUrl": "https://api.tauraco.io/oauth/authorize",
            "tokenUrl": "https://api.tauraco.io/oauth/token",
            "refreshUrl": "https://api.tauraco.io/oauth/token",
            "scopes": {
              "company:read": "Lire le profil de l'entreprise",
              "customers:read": "Lire les clients",
              "customers:write": "Créer des clients",
              "suppliers:read": "Lire les fournisseurs",
              "invoices:read": "Lire les factures clients",
              "invoices:write": "Créer des factures clients",
              "bills:read": "Lire les factures fournisseurs",
              "accounting:read": "Lire la comptabilité",
              "payments:read": "Lire les encaissements",
              "payments:write": "Enregistrer des encaissements",
              "treasury:read": "Lire la trésorerie",
              "purchases:read": "Lire les commandes d'achat",
              "products:read": "Lire les produits",
              "inventory:read": "Lire les stocks",
              "tenders:read": "Lire les appels d'offres",
              "markets:read": "Lire les marchés",
              "financing:read": "Lire les demandes de financement",
              "documents:read": "Télécharger les pièces",
              "guarantees:read": "Lire les garanties",
              "collateral:read": "Lire les dépôts de garantie",
              "exports:read": "Lire les exports",
              "exports:write": "Demander des exports",
              "webhooks:manage": "Gérer les webhooks",
              "bank:inbox:read": "Lire la boîte de réception bancaire",
              "bank:requests:read": "Lire les dossiers de financement reçus",
              "bank:documents:read": "Télécharger les pièces des dossiers",
              "bank:info-requests:write": "Demander des compléments",
              "bank:collateral:read": "Lire les garanties des dossiers",
              "bank:repayments:read": "Lire les remboursements",
              "bank:reconciliation:write": "Rapprocher les remboursements"
            }
          }
        }
      },
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Jeton d'accès du hub (JWT RS256, typ at+jwt, audience tauraco-public-api)."
      }
    }
  },
  "tags": [
    {
      "name": "company",
      "description": "Entreprise et application appelante."
    },
    {
      "name": "customers",
      "description": "Clients."
    },
    {
      "name": "suppliers",
      "description": "Fournisseurs (sans coordonnées bancaires)."
    },
    {
      "name": "invoices",
      "description": "Factures clients."
    },
    {
      "name": "bills",
      "description": "Factures fournisseurs."
    },
    {
      "name": "payments",
      "description": "Encaissements clients."
    },
    {
      "name": "purchases",
      "description": "Bons de commande."
    },
    {
      "name": "products",
      "description": "Produits et prestations."
    },
    {
      "name": "treasury",
      "description": "Trésorerie."
    },
    {
      "name": "accounting",
      "description": "Comptabilité : comptes, écritures, balance."
    },
    {
      "name": "inventory",
      "description": "Stocks."
    },
    {
      "name": "tenders",
      "description": "Marchés publics relayés (données externes non vérifiées)."
    },
    {
      "name": "financing",
      "description": "Demandes de financement de l'entreprise."
    },
    {
      "name": "collateral",
      "description": "Dépôts : stocks confiés à un tiers détenteur (constatation, sans valeur d'inscription)."
    },
    {
      "name": "documents",
      "description": "Pièces rattachées à leur parent (métadonnées et contenu en flux)."
    },
    {
      "name": "exports",
      "description": "Exports de jeux de données : demande, suivi, téléchargement."
    },
    {
      "name": "webhooks",
      "description": "Endpoints de webhook de l'application, livraisons, test et rejeu."
    },
    {
      "name": "integrations",
      "description": "Catalogue d'intégration : jeux exportables, formats, connexions de livraison."
    },
    {
      "name": "bank",
      "description": "API banque (clients bank d'une institution) : dossiers transmis, pièces, compléments, facilités, échéances, rapprochements et garanties Collateral."
    }
  ],
  "security": [
    {
      "oauth2": []
    },
    {
      "bearer": []
    }
  ]
}
