Consulter les factures ERP
Deux endpoints permettent de relire les factures certifiées par votre ERP via l’intégration en ligne : la liste paginée et le détail d’une facture.
Authentification : clé API (en-tête X-API-Key) délivrée après approbation d’une intégration
ERP. Portée : uniquement les factures du business_id lié à la clé. Explorateur
interactif : Référence OpenAPI
Liste des factures
URL : GET /api/v1/invoices
GET https://api.sfec.gouv.cg/api/v1/invoices?page=1&pageSize=10
X-API-Key: {votre_cle_api}
Accept: application/jsonLes factures sont triées par invoice_date décroissante.
Paramètres de requête
| Paramètre | Type | Description | Défaut |
|---|---|---|---|
page | integer | Numéro de page. Toute valeur < 1 est ramenée à 1. | 1 |
pageSize | integer | Factures par page. Toute valeur < 1 est ramenée à 10, toute valeur > 20 est ramenée à 20. | 10 |
invoice_type | string | Filtre par type : salesInvoice ou creditNote. | — |
date_start | string RFC 3339 | Borne inférieure sur invoice_date, incluse. | — |
date_end | string RFC 3339 | Borne supérieure sur invoice_date, incluse. | — |
Les dates doivent être au format RFC 3339 complet, horaire et fuseau compris : 2025-01-31T00:00:00Z.
Une date que le serveur ne sait pas analyser — 2025-01-31 par exemple — n’est pas rejetée : le filtre est purement et simplement ignoré et la réponse contient toutes les factures. Aucun code d’erreur ne le signale. Vérifiez vos bornes avant de vous fier au résultat.
Les deux bornes ne sont pas traitées symétriquement :
date_endest automatiquement reporté à la fin de la journée (23:59:59.999999999), dans le fuseau que vous avez transmis. Envoyer2025-01-31T00:00:00Zinclut donc bien toute la journée du 31.date_startest utilisé tel quel. Envoyer2025-01-31T10:00:00Zexclut silencieusement les factures de la matinée. Pour couvrir une journée entière, transmettez explicitementT00:00:00.
Exemple
curl --request GET \
--url "https://api.sfec.gouv.cg/api/v1/invoices?page=1&pageSize=20&invoice_type=salesInvoice&date_start=2026-07-01T00:00:00Z&date_end=2026-07-31T00:00:00Z" \
--header "X-API-Key: sk_sfec_live_your_key" \
--header "Accept: application/json"Enveloppe de réponse
{
"invoices": [/* voir « Structure d'une facture » ci-dessous */],
"totalPages": 12,
"page": 1,
"pageSize": 20
}| Champ | Type | Description |
|---|---|---|
invoices | array | Factures de la page courante |
totalPages | integer | Nombre total de pages pour le filtre appliqué. Vaut 1 même sans résultat. |
page | integer | Page retournée, après application des bornes |
pageSize | integer | Taille de page retenue, après application des bornes |
Pagination et factures de même date — le tri porte sur invoice_date seul, sans critère de
départage. Deux factures partageant exactement la même date d’émission, cas courant lors d’un
import ERP en masse, peuvent changer d’ordre entre deux appels : une même facture peut alors
apparaître sur deux pages consécutives, ou n’apparaître sur aucune. Pour un export exhaustif,
préférez un découpage par période via date_start / date_end plutôt qu’un parcours de toutes
les pages.
Codes de réponse
| Code | Description |
|---|---|
200 | Requête réussie |
401 | Clé API absente, invalide, ou dont le statut n’est pas active |
429 | Quota de requêtes dépassé — voir Limites de débit |
500 | Erreur interne |
Cet endpoint ne renvoie pas de 400. Les paramètres de pagination hors plage sont corrigés
silencieusement, et un filtre de date mal formé est ignoré.
Détail d’une facture
URL : GET /api/v1/invoices/{id}
GET https://api.sfec.gouv.cg/api/v1/invoices/{id}
X-API-Key: {votre_cle_api}
Accept: application/jsonParamètre de chemin
| Paramètre | Type | Description |
|---|---|---|
id | string | Identifiant unique (UUID) ou numéro de facture (invoice_number) |
Les deux formes sont acceptées indifféremment :
# Par UUID
curl --request GET \
--url "https://api.sfec.gouv.cg/api/v1/invoices/f0b6ad2d-bd0e-4c5a-9559-e2d7c4156c90" \
--header "X-API-Key: sk_sfec_live_your_key"
# Par numéro de facture
curl --request GET \
--url "https://api.sfec.gouv.cg/api/v1/invoices/AV-2026-000042" \
--header "X-API-Key: sk_sfec_live_your_key"La réponse est un objet facture unique, avec exactement les mêmes champs qu’un élément du tableau invoices de la liste.
Codes de réponse
| Code | Description |
|---|---|
200 | Facture trouvée |
400 | Identifiant de business invalide |
401 | Clé API absente, invalide, ou dont le statut n’est pas active |
404 | Facture inexistante, ou n’appartenant pas au business lié à la clé |
429 | Quota de requêtes dépassé — voir Limites de débit |
500 | Erreur interne |
Structure d’une facture
L’objet facture est plat et complet : les 63 champs sont retournés à chaque appel, sur les deux endpoints. Les champs non renseignés valent null — ils ne sont pas omis.
Exemple complet
Dans cet exemple, les montants et le QR code sont tronqués et signalés par …. La réponse
réelle les renvoie en entier — voir Montants pour la forme exacte.
{
"id": "f0b6ad2d-bd0e-4c5a-9559-e2d7c4156c90",
"invoice_number": "AV-2026-000042",
"invoice_date": "2026-07-28T14:33:35.609Z",
"invoice_type": "salesInvoice",
"invoice_subject": "Avoir - retour d'un ordinateur portable défectueux",
"invoice_due_date": null,
"invoice_status": "certified",
"reference_invoice_id": "FV-2026-000021",
"total_ht": "585000.0000…",
"total_tax18": "105300.0000…",
"total_tax5": "0.0000…",
"total_exempt": "0.0000…",
"additional_tax5": "5265.0000…",
"electronic_stamp": "0.0000…",
"overall_discount": "0.0000…",
"amount_due": "695565.0000…",
"total_debours": "0.0000…",
"total_line_discount_amount": "65000.0000…",
"total_ttc": "695565.0000…",
"tva": "105300.0000…",
"currency": "XAF",
"item_count": 1,
"notes": "Avoir émis suite au constat de panne écran sur 1 unité.",
"payment_method": "bank_transfer",
"payment_reference": null,
"payment_date": null,
"certification_date": "2026-07-28T14:33:35.609Z",
"certification_status": "certified",
"certification_signature": "a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90",
"certification_short_signature": "A1B2C3D4E5F60718293A",
"certification_qr_code": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg… (tronqué)",
"logo_img": null,
"certification_img": null,
"buyer_name": "Test Buyer Company",
"buyer_niu": "BUYER123456789",
"buyer_phone": "+242060000000",
"buyer_type": "business",
"buyer_address": "123 avenue Exemple, Brazzaville, Congo",
"is_buyer_taxable": true,
"buyer_tax_residence": null,
"buyer_tax_regime": null,
"delivery_address": null,
"transaction_location": "Brazzaville",
"seller_name": "Test Seller SARL",
"seller_address": null,
"seller_phone": "060000000",
"seller_email": "contact@exemple.cg",
"seller_niu": "SELLER123456789",
"seller_legal_form": "SARL",
"seller_share_capital": "1000000.00",
"seller_rccm": "CG-BZV-2025-B-001",
"seller_tax_regime": null,
"seller_bank_rib": null,
"seller_bank_iban": null,
"cashier_name": "Caissier Test",
"external_credit_note_number": "ERP-CN-00042",
"original_sfec_invoice_number": "CG-2026-0000000021",
"sciet": null,
"items_json": [
{
"type": "product",
"designation": "Retour - Ordinateur portable",
"classification_code": "8471.30.00",
"quantity": 1,
"unit_price": 650000,
"subtotal": 585000,
"discount_amount": 65000,
"reduction_type": "commercial",
"amount_after_discount": 585000,
"net_amount": 690300,
"tax_rate": "18",
"tax_amount": 105300,
"total_amount": 690300
}
],
"additional_taxes": null,
"created_at": "2026-07-28T14:33:35.608933Z",
"updated_at": "2026-07-28T14:33:35.608933Z",
"status": {
"status_id": 3,
"name": "Certified",
"description": "Invoice is certified"
}
}Identification
| Champ | Type | Description |
|---|---|---|
id | string (UUID) | Identifiant SFEC de la facture |
invoice_number | string | Numéro de facture transmis par l’ERP |
invoice_date | string (date-time) | Date d’émission — c’est le champ sur lequel portent le tri et les filtres de période |
invoice_type | string | salesInvoice ou creditNote |
invoice_subject | string | null | Objet libre de la facture |
invoice_due_date | string (date-time) | null | Échéance de paiement |
invoice_status | string | null | Statut de la facture |
reference_invoice_id | string | null | Référence de la facture d’origine pour un avoir. Contient un numéro de facture, pas un UUID, malgré son nom. |
Montants
Les montants sont des chaînes de caractères reprenant la représentation NUMERIC brute de la base : la partie décimale compte systématiquement 30 chiffres, quelle que soit la devise. Un total de 650 000 XAF est donc renvoyé sous la forme 650000. suivi de trente zéros — une chaîne de 37 caractères.
Ne les comparez pas comme des chaînes et n’affichez jamais la valeur brute : analysez-les comme des décimaux avant tout usage.
| Champ | Type | Description |
|---|---|---|
total_ht | string | Total hors taxe |
total_tax18 | string | null | TVA à 18 % |
total_tax5 | string | null | TVA à 5 % |
total_exempt | string | null | Total exonéré |
additional_tax5 | string | null | Taxe additionnelle 5 % |
electronic_stamp | string | null | Timbre fiscal électronique |
overall_discount | string | null | Remise globale |
total_line_discount_amount | string | null | Cumul des remises de ligne |
amount_due | string | null | Montant restant dû. Reste strictement commercial — n’inclut jamais total_debours, voir Débours ci-dessous |
total_debours | string | null | Total des débours — voir Débours ci-dessous |
total_ttc | string | Total toutes taxes comprises |
tva | string | Total TVA |
currency | string | XAF, USD ou EUR |
item_count | integer | Nombre de lignes |
Débours
Un débours est une somme avancée par le vendeur au nom et pour le compte du client, puis refacturée à l’identique. Il est hors champ de TVA et n’est pas du chiffre d’affaires. Il apparaît en lecture sous deux formes :
total_debours— le cumul, au niveau de la facture, de toutes les lignes de débours.items_json[].is_debours—truesur les lignes concernées, absent oufalsesur les lignes commerciales ordinaires (voir Lignes de facture).
amount_due n’inclut jamais total_debours. Pour afficher le montant réellement dû par le client, additionnez les deux vous-même :
net_à_payer = amount_due + total_deboursCette somme n’est stockée nulle part telle quelle sur la facture — elle est à recalculer à chaque affichage.
Paiement
| Champ | Type | Description |
|---|---|---|
payment_method | string | null | Mode de paiement — voir l’avertissement ci-dessous |
payment_reference | string | null | Référence du règlement |
payment_date | string (date-time) | null | Date du règlement |
notes | string | null | Notes libres |
payment_method a deux formats possibles. La valeur est restituée exactement telle que votre ERP l’a transmise à la certification, sans normalisation. La certification acceptant les deux notations, vous pouvez recevoir :
- l’énumération textuelle :
cash,bank_transfer,card,mobile_money,cheque,credit; - ou le code PGSFEC correspondant :
"1","2","3","4","5","6".
La correspondance est cash → 1, bank_transfer → 2, card → 3, mobile_money → 4, cheque → 5, credit → 6. Prévoyez de gérer les deux formes en lecture : c’est le format d’écriture de votre ERP qui détermine ce que vous relirez.
Certification
| Champ | Type | Description |
|---|---|---|
certification_date | string (date-time) | null | Horodatage de la certification |
certification_status | string | null | Statut de certification |
certification_signature | string | null | Signature complète (64 caractères hexadécimaux) |
certification_short_signature | string | null | Signature courte (20 caractères) |
certification_qr_code | string | null | QR code, en data URI PNG encodé en base64 |
certification_img | string | null | Visuel de certification, en data URI |
logo_img | string | null | Logo du vendeur, en data URI |
Poids de la réponse — certification_qr_code fait plusieurs kilo-octets par facture et est
toujours inclus ; logo_img et certification_img sont du même type lorsqu’ils sont renseignés.
Une page de 20 factures peut ainsi dépasser plusieurs centaines de kilo-octets. Aucun paramètre ne
permet actuellement de les exclure : dimensionnez vos délais d’attente en conséquence, et réduisez
pageSize si nécessaire.
Correspondance avec la réponse de certification
Les champs renvoyés par POST /api/v1/invoices portent d’autres noms en lecture :
| Réponse de certification | Champ en lecture |
|---|---|
signature et certification_number (valeurs identiques) | certification_signature |
short_signature et identifier (valeurs identiques) | certification_short_signature |
qr_code | certification_qr_code |
certification_date | certification_date |
invoice_number | invoice_number |
Client
Les informations du client sont à plat sur la facture. Elles reprennent ce que l’ERP a transmis à la certification.
| Champ | Type | Description |
|---|---|---|
buyer_name | string | null | Nom ou raison sociale |
buyer_niu | string | null | NIU du client |
buyer_phone | string | null | Téléphone |
buyer_type | string | null | individual, business, government ou foreign |
buyer_address | string | null | Adresse |
is_buyer_taxable | boolean | null | Client assujetti |
buyer_tax_residence | string | null | Résidence fiscale |
buyer_tax_regime | string | null | Régime d’imposition |
delivery_address | string | null | Adresse de livraison |
transaction_location | string | null | Lieu de la transaction |
Un objet imbriqué buyer figure dans le schéma de l’API mais n’est jamais renvoyé pour les
factures certifiées par API : celles-ci ne sont pas rattachées à une fiche client du répertoire
SFEC. Ne construisez pas votre intégration dessus — utilisez les champs buyer_* ci-dessus.
Vendeur
Ces champs décrivent votre propre entreprise. Ils sont identiques sur toutes les factures d’une même réponse, puisque la clé API ne donne accès qu’à un seul business_id.
| Champ | Type | Description |
|---|---|---|
seller_name | string | null | Raison sociale |
seller_niu | string | null | NIU |
seller_rccm | string | null | Numéro RCCM |
seller_legal_form | string | null | Forme juridique |
seller_share_capital | string | null | Capital social |
seller_tax_regime | string | null | Régime fiscal |
seller_address | string | null | Adresse |
seller_phone | string | null | Téléphone |
seller_email | string | null | Adresse e-mail |
seller_bank_rib | string | null | RIB |
seller_bank_iban | string | null | IBAN |
cashier_name | string | null | Caissier ayant émis la facture |
Rapprochement ERP
| Champ | Type | Description |
|---|---|---|
external_credit_note_number | string | null | Numéro d’avoir dans votre ERP |
original_sfec_invoice_number | string | null | Numéro SFEC de la facture d’origine |
sciet | string | null | Référence SCIET |
Lignes de facture
| Champ | Type | Description |
|---|---|---|
items_json | array | Lignes de la facture |
additional_taxes | array | null | Taxes additionnelles (TAR, ASDI, TAX_TOUR, TAX_MUNI, droits d’accises) |
items_json est restitué tel quel, sans schéma imposé : le contenu est celui que votre ERP a
transmis à la certification. Les clés présentes varient d’une ligne à l’autre et d’une facture à
l’autre. Traitez chaque clé comme facultative.
Clés couramment rencontrées :
| Clé | Type | Description |
|---|---|---|
type | string | product ou service |
designation | string | Libellé de l’article |
classification_code | string | Code de classification douanière ou fiscale |
quantity | number | Quantité |
unit_price | number | Prix unitaire HT |
subtotal | number | Montant HT de l’article, remise ligne déjà déduite |
discount_amount | number | Remise appliquée |
reduction_type | string | Nature de la remise, par exemple commercial |
amount_after_discount | number | Montant HT après remise (hors taxe) |
net_amount | number | Montant TTC de la ligne, remise et taxe incluses |
tax_rate | string | Taux de TVA : "0", "5" ou "18" |
tax_amount | number | Montant de TVA de la ligne |
total_amount | number | Montant TTC de la ligne |
is_debours | boolean | Marque la ligne comme débours — voir Débours ci-dessus |
Métadonnées
| Champ | Type | Description |
|---|---|---|
created_at | string (date-time) | Création de l’enregistrement SFEC |
updated_at | string (date-time) | Dernière modification |
status | object | Statut de traitement : status_id, name, description |
Trois champs portent une notion de statut — invoice_status, certification_status et l’objet status. Pour une facture certifiée par API, l’objet status vaut toujours {"status_id": 3, "name": "Certified", "description": "Invoice is certified"} : il ne distingue pas les factures entre elles et ne constitue pas un signal exploitable. Fiez-vous à certification_status.
Limites de débit
Les appels sont limités par clé API et par business. Chaque réponse porte les en-têtes :
| En-tête | Description |
|---|---|
X-RateLimit-Limit | Nombre de requêtes autorisées sur la fenêtre |
X-RateLimit-Remaining | Requêtes restantes |
X-RateLimit-Reset | Horodatage Unix de réinitialisation de la fenêtre |
Au dépassement, l’API répond 429 avec le message Rate limit exceeded. Attendez la date indiquée par X-RateLimit-Reset avant de réessayer.
Format des erreurs
Toutes les erreurs suivent la même forme :
{
"message": "API key is required"
}Le corps ne contient que la clé message. Il n’y a ni champ error ni champ details.
Messages courants :
| Code | message |
|---|---|
401 | API key is required — en-tête X-API-Key absent |
401 | Invalid API key — clé inconnue, révoquée ou inactive |
404 | invoice not found |
429 | Rate limit exceeded |
500 | Failed to list invoices / Failed to get invoice |
Étape suivante → Référence OpenAPI