Envelopify API
Envelopify envoie de vraies lettres papier avec de vrais timbres depuis votre logiciel, en Belgique. Un appel par lettre : nous imprimons, mettons sous enveloppe, collons les timbres et remettons la lettre à bpost. Standard : remise à bpost dans les 3 jours ouvrables. Express : le jour ouvrable même si reçue avant 12h00 (Europe/Brussels). Flex : dans les 5 jours ouvrables. bpost distribue dans les 2 à 3 jours ouvrables après le dépôt.
https://envelopify.lovable.app/api/v1Construire avec l'IA
Donnez ce lien à votre assistant IA et laissez-le construire l'intégration. Toute la documentation est disponible en texte brut (en anglais).
Lis la documentation de l'API Envelopify sur https://envelopify.lovable.app/llms-full.txt. Construis dans mon app une intégration qui envoie automatiquement une lettre quand [événement, p. ex. une facture est créée]. Appelle l'API uniquement depuis une fonction serveur, garde la clé API comme secret et jamais dans le navigateur. Commence avec ma clé de test (test_...). Affiche les erreurs de l'API en langage clair à l'utilisateur et conserve l'id et le statut de chaque lettre.Aussi disponible : openapi.json, developers.md et llms.txt.
Démarrer en 5 minutes
- Créer une clé. Créez un compte gratuit, ouvrez Clés API et créez une clé de test. Remplacez
test_JOUW_SLEUTELdans les exemples par votre clé. - Envoyer une lettre test. L'exemple sous Envoyer une lettre utilise notre PDF d'exemple et fonctionne tel quel. Rien n'est imprimé ni facturé.
- Consulter le statut. Prenez l'
idde la réponse et appelezGET /api/v1/letters/{id}. Ajoutez/pdfpour obtenir le PDF tel que nous l'imprimons. - Configurer les notifications. Enregistrez une URL https avec
POST /api/v1/webhookspour être averti quand votre lettre est imprimée et postée. - Passer en production. Rechargez votre crédit dans le portail et cliquez sur Passer en live à côté de votre clé. Les nouvelles clés démarrent toujours en mode test. La clé elle-même ne change pas.
Créez un compte gratuit pour générer votre clé.
Authentification par clé
Envoyez votre clé avec chaque requête dans l'en-tête Authorization: Bearer <clé>. Les nouvelles clés démarrent en mode test ; vous les passez en live dans le portail (Clés API, Passer en live). Le mode dépend de la clé, pas de son préfixe. Avec une clé en mode test, les lettres ne sont jamais imprimées, envoyées ni facturées ; elles reçoivent le statut received. Une clé n'est affichée qu'une seule fois : gardez-la comme secret sur votre serveur, jamais dans du code navigateur. Une clé manquante, invalide ou révoquée renvoie 401 unauthorized.
Mettre un événement en attentePOST/api/v1/flow-events
Pour un flux de rappel actif et un contact enregistré. Crée un plan unique, pas une lettre immédiate. Le traitement quotidien partage les contrôles de prix et d’arrêt ; un crédit insuffisant conserve la file. event_key évite les doublons par flux et mode. Limites journalières et délai par contact ; les plans test sont exécutés par un administrateur, sans envoi ni frais.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
flow_id | texte | oui | Id du flux actif. |
contact_id | texte | oui | Id de votre contact. |
event_key | texte | oui | Référence unique, 1 à 120 caractères. |
order_cents | nombre | Montant pour la condition, 0 par défaut. | |
variables | objet | Champs nécessaires uniquement. |
Exemple de requête
curl -X POST https://envelopify.lovable.app/api/v1/flow-events \
-H "Authorization: Bearer test_JOUW_SLEUTEL" \
-H "Content-Type: application/json" \
-d '{
"flow_id": "b1d1a7f7-3db2-43df-a896-bc9dc10c6029",
"contact_id": "b1d1a7f7-3db2-43df-a896-bc9dc10c6029",
"event_key": "herinnering-104",
"variables": {}
}'{
"status": "queued",
"test": true
}Envoyer une lettrePOST/api/v1/letters
Crée une lettre. Indiquez exactement une source : un PDF (pdf_base64 ou pdf_url) ou un modèle (template_id ou template_code) avec variables. Le PDF suit le choix du compte : page d’adresse gratuite ou zone blanche sur la première page avec options.address_on_first_page. Petit jusqu’à 50 g, moyen jusqu’à 100 g, grand jusqu’à 350 g. Moyen et grand nécessitent un supplément confirmé et activé. La page d’adresse compte pour le poids, pas le prix de base. Renvoie 201 avec l'id, le statut, le prix et son détail (price_breakdown), le nombre de feuilles (page d'adresse comprise), la date de dépôt au plus tard pour la vitesse choisie et test. Avec une clé de test, le statut est received et post_date vaut null. Une lettre refusée renvoie 422 avec un code d'erreur et letter_id. En-tête facultatif Idempotency-Key.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
options.address_on_first_page | oui/non | PDF chargé : zone d’adresse blanche opaque fixe sur la première page, sans page supplémentaire. Le contenu couvert devient blanc. Par défaut selon le compte (initialement page séparée). | |
options.corrections | objet | Corrections PDF : region {left,top,width,height} en mm sur A4, window left/right/both, first_page, white_margins, flatten et a4_portrait. Sans cet objet, la règle du compte s’applique. L’ancienne zone d’adresse devient blanche. L’original est conservé. | |
recipient.language | texte | Facultatif : nl, fr, en ou de. Choisit la variante enregistrée, sinon le texte de base. Par défaut selon le code postal belge. | |
recipient.company | texte | Facultatif. Nom de l'entreprise. | |
recipient.name | texte | oui | Nom du destinataire. Le nom ou l'entreprise est obligatoire. |
recipient.street | texte | oui | Rue. |
recipient.number | texte | oui | Numéro. |
recipient.box | texte | Facultatif. Numéro de boîte. | |
recipient.postal_code | texte | oui | Code postal. 4 chiffres en Belgique. |
recipient.city | texte | oui | Commune. |
recipient.country | texte | Code pays (2 lettres), BE par défaut. Aussi tous les autres pays de l'UE (p. ex. NL, FR, DE), +1,50 € par lettre, délai de 5 à 10 jours ouvrables après l'envoi, pas d'express. | |
pdf_base64 | texte | PDF en base64, A4, maximum 20 Mo. | |
pdf_url | texte | Lien HTTPS public direct vers votre PDF, maximum 20 Mo. Sans redirection, identifiants, réseau privé ou port non standard. | |
template_id | texte | Id d'un modèle, au lieu d'un PDF. | |
template_code | texte | Ou le code d'un modèle, p. ex. herinnering. | |
variables | objet | Valeurs des champs de votre modèle, p. ex. { "voornaam": "An" }. | |
options.flat | oui/non | Non plié dans une grande enveloppe, traitement manuel. Disponible après activation. Supplément via /price. | |
options.registered | oui/non | Recommandé papier, BE et standard/express uniquement, après activation. Suivi : registered_tracking, registered_handed_in_at et registered_receipt_url temporaire. | |
options.color | oui/non | Couleur. Noir et blanc par défaut. Supplément par feuille via /price. | |
options.duplex | oui/non | Recto verso : deux pages par feuille. Recto par défaut. | |
options.qr_tracking | oui/non | QR code dynamique avec suivi des scans, +0,05 € par lettre. | |
options.speed | texte | Vitesse : `standard` (envoyée dans les 3 jours ouvrables), `express` (le jour ouvrable même si reçue avant 12h00, +0,15 € par lettre, minimum 15,00 € par jour) ou `flex` (dans les 5 jours ouvrables, -0,05 € par lettre). `standard` par défaut. | |
options.qr_target_url | texte | Obligatoire avec qr_tracking. Lien https vers lequel le QR code redirige. Modifiable ensuite dans le portail. | |
enclosure_batch_id | texte | Id des imprimés reçus dans le portail. Un exemplaire par lettre après activation et contrôle. Annulation avant production restitue le stock. | |
reference | texte | Facultatif. Votre propre référence, p. ex. numéro de facture. | |
post_on | texte | Jour de dépôt facultatif (YYYY-MM-DD), un jour ouvrable jusqu’à 90 jours calendrier à l’avance. Pas une date de livraison. Crédit réservé par débit à la création, remboursé en cas d’annulation avant production. |
Exemple de requête
curl -X POST https://envelopify.lovable.app/api/v1/letters \
-H "Authorization: Bearer test_JOUW_SLEUTEL" \
-H "Idempotency-Key: factuur-2026-104" \
-H "Content-Type: application/json" \
-d '{
"recipient": {
"name": "An Peeters",
"street": "Meir",
"number": "12",
"postal_code": "2000",
"city": "Antwerpen"
},
"pdf_url": "https://envelopify.lovable.app/voorbeeld.pdf",
"options": {
"color": false
},
"reference": "factuur-2026-104"
}'{
"id": "b1d1a7f7-3db2-43df-a896-bc9dc10c6029",
"status": "scheduled",
"price_cents": 129,
"price_breakdown": {
"unit_price_cents": 129,
"tier": 1,
"tier_fixed": false,
"volume_30d": 120,
"letters_to_next_tier": 379,
"pages": 1,
"sheets": 1,
"address_sheet": true,
"total_sheets": 2,
"color": false,
"duplex": false,
"speed": "standard",
"destination": "BE",
"options": [],
"total_cents": 129,
"on_request": false,
"currency": "EUR",
"vat_included": false
},
"sheet_count": 2,
"post_date": "2026-11-13",
"free_trial": false,
"test": false
}Consulter une lettreGET/api/v1/letters/{id}
Renvoie tous les champs de la lettre, les horodatages, le détail du prix, le nombre de scans QR (scan_count) et, une fois postée, un lien temporaire vers la photo du lot (batch_photo_url, valable 1 heure).
Exemple de requête
curl -X GET https://envelopify.lovable.app/api/v1/letters/b1d1a7f7-3db2-43df-a896-bc9dc10c6029 \
-H "Authorization: Bearer test_JOUW_SLEUTEL"{
"id": "b1d1a7f7-3db2-43df-a896-bc9dc10c6029",
"tracking_code": "B1D1A7F7",
"reference": "factuur-2026-104",
"status": "posted",
"test": false,
"reject_reason": null,
"return_reason": null,
"recipient": {
"company": null,
"name": "An Peeters",
"street": "Meir",
"number": "12",
"box": null,
"postal_code": "2000",
"city": "Antwerpen",
"country": "BE"
},
"source": "pdf",
"color": false,
"duplex": false,
"qr_tracking": false,
"sheet_count": 2,
"price_cents": 129,
"price_breakdown": {
"unit_price_cents": 129,
"tier": 1,
"tier_fixed": false,
"volume_30d": 120,
"letters_to_next_tier": 379,
"pages": 1,
"sheets": 1,
"address_sheet": true,
"total_sheets": 2,
"color": false,
"duplex": false,
"speed": "standard",
"destination": "BE",
"options": [],
"total_cents": 129,
"on_request": false,
"currency": "EUR",
"vat_included": false
},
"speed": "standard",
"post_deadline": "2026-11-13",
"created_at": "2026-11-12T10:02:11Z",
"scheduled_at": "2026-11-12T10:02:11Z",
"printed_at": "2026-11-13T09:40:00Z",
"posted_at": "2026-11-13T16:02:11Z",
"returned_at": null,
"post_date": "2026-11-13",
"scan_count": 0,
"batch_photo_url": null
}Télécharger le PDFGET/api/v1/letters/{id}/pdf
Renvoie le PDF définitif tel que nous l'imprimons (application/pdf), page d'adresse comprise. Uniquement pour vos propres lettres. Une lettre refusée n'a pas de PDF et renvoie 404.
Exemple de requête
curl -X GET https://envelopify.lovable.app/api/v1/letters/b1d1a7f7-3db2-43df-a896-bc9dc10c6029/pdf \
-H "Authorization: Bearer test_JOUW_SLEUTEL"Liste des lettresGET/api/v1/letters
Renvoie vos lettres les plus récentes, de la plus récente à la plus ancienne, dans data. S'il y en a plus, vous recevez un next_cursor à renvoyer comme cursor.
| Filtre | Type | Description | |
|---|---|---|---|
status | texte | Filtrer par statut, p. ex. posted. | |
reference | texte | Filtrer par référence. | |
from | texte | À partir de la date, p. ex. 2026-11-01. | |
to | texte | Jusqu'à la date incluse. | |
limit | nombre | 25 par défaut, maximum 100. | |
cursor | texte | Valeur de next_cursor. |
Exemple de requête
curl -X GET https://envelopify.lovable.app/api/v1/letters?status=posted&limit=50 \
-H "Authorization: Bearer test_JOUW_SLEUTEL"{
"data": [
{
"id": "b1d1a7f7-3db2-43df-a896-bc9dc10c6029",
"status": "posted",
"reference": "factuur-2026-104"
}
],
"next_cursor": "MjAyNi0xMS0xMlQxMDo..."
}Annuler une lettreDELETE/api/v1/letters/{id}
Annule une lettre tant que le lot du jour est encore ouvert. Le montant est recrédité sur votre compte Envelopify, pas versé et la lettre revient avec le statut rejected. Si le lot est déjà clôturé, vous recevez 409 cutoff_passed.
Exemple de requête
curl -X DELETE https://envelopify.lovable.app/api/v1/letters/b1d1a7f7-3db2-43df-a896-bc9dc10c6029 \
-H "Authorization: Bearer test_JOUW_SLEUTEL"Calculer un prixPOST/api/v1/price
Calcule le prix d'une lettre avec votre palier actuel, sans rien créer ni facturer. Mêmes options qu'une lettre, mais avec le nombre de pages imprimées au lieu d'un PDF. Avec address_sheet (true par défaut), la page d'adresse gratuite compte dans le maximum de feuilles, comme pour un PDF chargé ; mettez false pour une lettre à partir d'un modèle. Une tranche indisponible renvoie 422 weight_class_unavailable. Utilisez options.address_on_first_page sans page d’adresse supplémentaire.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
options.address_on_first_page | oui/non | PDF chargé : zone d’adresse blanche opaque fixe sur la première page, sans page supplémentaire. Le contenu couvert devient blanc. Par défaut selon le compte (initialement page séparée). | |
options.flat | oui/non | Non plié dans une grande enveloppe, traitement manuel. Disponible après activation. Supplément via /price. | |
options.registered | oui/non | Recommandé papier, BE et standard/express uniquement, après activation. Suivi : registered_tracking, registered_handed_in_at et registered_receipt_url temporaire. | |
enclosure_batch_id | texte | Id des imprimés reçus dans le portail. Un exemplaire par lettre après activation et contrôle. Annulation avant production restitue le stock. | |
pages | nombre | oui | Nombre de pages imprimées (sans la page d'adresse). |
address_sheet | oui/non | Compter la page d'adresse gratuite dans le maximum de feuilles. true par défaut. | |
options.country | texte | Pays de destination, BE par défaut. Un autre pays de l'UE ajoute le supplément UE. | |
options.color | oui/non | Couleur, supplément par feuille via /price. | |
options.duplex | oui/non | Recto verso. | |
options.qr_tracking | oui/non | QR code avec suivi des scans. | |
options.speed | texte | standard, express ou flex. |
Exemple de requête
curl -X POST https://envelopify.lovable.app/api/v1/price \
-H "Authorization: Bearer test_JOUW_SLEUTEL" \
-H "Content-Type: application/json" \
-d '{
"pages": 3,
"address_sheet": true,
"options": {
"color": false,
"duplex": false,
"qr_tracking": false,
"speed": "standard"
}
}'{
"price_breakdown": {
"unit_price_cents": 129,
"tier": 1,
"tier_fixed": false,
"volume_30d": 120,
"letters_to_next_tier": 379,
"pages": 3,
"sheets": 3,
"address_sheet": true,
"total_sheets": 4,
"color": false,
"duplex": false,
"speed": "standard",
"destination": "BE",
"options": [
{
"code": "extra_sheets",
"label": "Extra vellen (2)",
"amount_cents": 20
}
],
"total_cents": 149,
"on_request": false,
"currency": "EUR",
"vat_included": false
}
}Liste des modèlesGET/api/v1/templates
Renvoie vos modèles dans data.
Exemple de requête
curl -X GET https://envelopify.lovable.app/api/v1/templates \
-H "Authorization: Bearer test_JOUW_SLEUTEL"{
"data": [
{
"id": "6c1f...",
"name": "Herinnering",
"code": "herinnering",
"body": "Beste {{voornaam}}, ...",
"created_at": "2026-11-12T10:00:00Z"
}
]
}Créer un modèlePOST/api/v1/templates
Crée un modèle. Les champs se placent entre doubles accolades, p. ex. {{voornaam}}. Un code existant renvoie 409 conflict.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
name | texte | oui | Nom. |
code | texte | oui | Code unique : lettres, chiffres, - et _. |
body | texte | oui | Texte avec champs. |
Exemple de requête
curl -X POST https://envelopify.lovable.app/api/v1/templates \
-H "Authorization: Bearer test_JOUW_SLEUTEL" \
-H "Content-Type: application/json" \
-d '{
"name": "Herinnering",
"code": "herinnering",
"body": "Beste {{voornaam}},\n\nWe ontvingen nog geen betaling van {{bedrag}}."
}'Crédit et tarifsGET/api/v1/balance
Renvoie votre crédit, les lettres d'essai gratuites restantes (free_letters_remaining), votre palier actuel, le nombre de vraies lettres des 30 derniers jours, les lettres restantes avant la remise suivante et la grille tarifaire en cents, HTVA : prix par lettre par palier, suppléments des options, vitesses et règles express.
Exemple de requête
curl -X GET https://envelopify.lovable.app/api/v1/balance \
-H "Authorization: Bearer test_JOUW_SLEUTEL"{
"credit_cents": 4950,
"free_letters_remaining": 3,
"company_verified": true,
"tier": 1,
"tier_fixed": false,
"volume_30d": 120,
"letters_to_next_tier": 380,
"unit_price_cents": 129,
"tiers": [
{
"tier": 1,
"from": 0,
"unit_price_cents": 129
},
{
"tier": 2,
"from": 500,
"unit_price_cents": 109
},
{
"tier": 3,
"from": 5000,
"unit_price_cents": 99
}
],
"options": {
"extra_sheet_cents": 10,
"qr_tracking_cents": 5
},
"speeds": [
{
"speed": "standard",
"name": "Standaard",
"amount_cents": 0,
"working_days": 3
},
{
"speed": "express",
"name": "Express",
"amount_cents": 15,
"working_days": 0
},
{
"speed": "flex",
"name": "Flex",
"amount_cents": -5,
"working_days": 5
}
],
"express": {
"minimum_cents": 1500,
"max_letters_per_day": 1000,
"before_hour": 12
},
"heavy_letter": {
"from_grams": 50,
"amount_cents": 60
},
"eu": {
"surcharge_cents": 150,
"countries": [
"AT",
"DE",
"FR",
"NL",
"..."
],
"delivery": "5 tot 10 werkdagen na verzending",
"express": false
},
"daily_letter_max": 1000,
"max_sheets": 8,
"currency": "EUR",
"vat_included": false
}Votre compte et vérification de l'entrepriseGET/api/v1/account
Renvoie les données de votre propre compte. company_verified vaut true si votre numéro de TVA a été vérifié via le contrôle européen de la TVA (VIES) ou manuellement par nous. verification_status vaut verified, none (non vérifiée), pending (vérification plus tard) ou invalid. Pour une entreprise vérifiée, official_name et official_address proviennent du registre officiel. GET /balance contient aussi company_verified. Le statut ne se modifie pas via l'API : uniquement après un vrai contrôle dans le portail.
Exemple de requête
curl -X GET https://envelopify.lovable.app/api/v1/account \
-H "Authorization: Bearer test_JOUW_SLEUTEL"{
"customer_id": "4f6c2a1e-...",
"company": "Jouw Bedrijf",
"email": "post@jouwbedrijf.be",
"company_verified": true,
"verification_status": "verified",
"vat_number": "BE0123456749",
"official_name": "Jouw Bedrijf BV",
"official_address": "Kerkstraat 1\n2000 Antwerpen",
"checked_at": "2026-11-12T10:00:00Z",
"free_letters_remaining": 3
}Liste des webhooksGET/api/v1/webhooks
Liste vos URL et notification_groups. null signifie tous les événements existants ; une liste limite les notifications aux groupes choisis.
Exemple de requête
curl -X GET https://envelopify.lovable.app/api/v1/webhooks \
-H "Authorization: Bearer test_JOUW_SLEUTEL"{
"data": [
{
"id": "a3c2...",
"url": "https://jouwsite.be/hooks/envelopify",
"active": true,
"created_at": "2026-11-12T10:00:00Z"
}
]
}Créer un webhookPOST/api/v1/webhooks
Enregistre une URL https. La réponse contient une seule fois le secret ; utilisez-le pour vérifier les signatures.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
url | texte | oui | Lien https qui reçoit notre POST. |
notification_groups | liste | Facultatif : problems (review/rejected), sent (posted/registered_handed_in), undeliverable (returned), delivered (bientôt, aucun événement). Omettre conserve tous les événements ; [] ne reçoit rien. Modifiable par URL dans le portail. |
Exemple de requête
curl -X POST https://envelopify.lovable.app/api/v1/webhooks \
-H "Authorization: Bearer test_JOUW_SLEUTEL" \
-H "Content-Type: application/json" \
-d '{
"url": "https://jouwsite.be/hooks/envelopify"
}'{
"id": "a3c2...",
"url": "https://jouwsite.be/hooks/envelopify",
"active": true,
"created_at": "2026-11-12T10:00:00Z",
"secret": "whsec_..."
}Supprimer un webhookDELETE/api/v1/webhooks/{id}
Supprime un webhook.
Exemple de requête
curl -X DELETE https://envelopify.lovable.app/api/v1/webhooks/a3c2... \
-H "Authorization: Bearer test_JOUW_SLEUTEL"{
"id": "a3c2...",
"deleted": true
}Notifications de statut
À chaque événement, nous envoyons un POST { event, letter_id, status, occurred_at, letter } à toutes vos URL de webhook actives. Chaque requête porte l'en-tête x-envelopify-signature : le HMAC-SHA256 hexadécimal du corps brut avec votre secret. Vérifiez-le avant de faire confiance au contenu et répondez avec un statut 2xx. Les envois échoués (pas de 2xx ou pas de réponse dans les 8 secondes) sont relancés jusqu'à 3 fois (lors de votre événement suivant et à chaque tournée de production), soit 4 tentatives au total. Les lettres test restent received et n'envoient pas de webhooks.
| Événement | Quand |
|---|---|
letter.scheduled | Planifiée pour un jour de dépôt, crédit débité |
letter.review | Adresse à contrôler : nous la vérifions avant l'impression |
letter.checked | Adresse approuvée après contrôle, planifiée |
letter.rejected | Refusée après contrôle ou annulée avant production, crédit remboursé |
letter.printed | Imprimée et affranchie |
letter.posted | Remise à bpost |
letter.returned | Revenue comme non distribuable |
letter.registered_handed_in | Dépôt recommandé avec suivi et preuve |
letter.scanned | QR code scanné |
{
"event": "letter.posted",
"letter_id": "b1d1a7f7-3db2-43df-a896-bc9dc10c6029",
"status": "posted",
"occurred_at": "2026-11-13T16:02:12Z",
"letter": {
"id": "b1d1a7f7-3db2-43df-a896-bc9dc10c6029",
"tracking_code": "B1D1A7F7",
"reference": "factuur-2026-104",
"status": "posted",
"posted_at": "2026-11-13T16:02:11Z"
},
"created_at": "2026-11-13T16:02:12Z"
}Vérifier la signature :
// Node 18+ with Express: verify a webhook signature
import crypto from "node:crypto";
import express from "express";
const SECRET = "whsec_JOUW_GEHEIM"; // returned once when you create the webhook
const app = express();
app.post("/hooks/envelopify", express.raw({ type: "application/json" }), (req, res) => {
const expected = crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");
const given = req.get("x-envelopify-signature") ?? "";
const ok = given.length === expected.length && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
if (!ok) return res.status(401).end();
const { event, letter } = JSON.parse(req.body.toString("utf8"));
console.log(event, letter.id, letter.status);
res.status(200).end();
});
app.listen(3000);Éviter les doublons
Envoyez un en-tête Idempotency-Key, p. ex. votre numéro de facture. Si vous renvoyez la même clé dans les 24 heures, vous recevez la lettre existante (statut 200) au lieu d'une nouvelle, et rien n'est facturé en plus. Après 24 heures, la clé compte comme nouvelle.
Statuts
| Statut | Signification |
|---|---|
received | Reçue. Les lettres test restent dans ce statut. |
scheduled | Planifiée pour un jour de dépôt, crédit débité. |
review | À contrôler : le code postal n'existe pas ou ne correspond pas à la commune. Nous approuvons ou refusons l'adresse (crédit remboursé). Voir address_warning. |
printed | Imprimée et affranchie. |
posted | Remise à bpost. |
returned | Revenue comme non distribuable. |
rejected | Refusée ou annulée. La raison figure dans reject_reason. |
Codes d'erreur
Les erreurs ont toujours la forme { error: { code, message } }. Le code (error.code) est toujours le même, quelle que soit la langue : utilisez-le dans votre logique. Le message (error.message) est en néerlandais et peut être affiché tel quel à votre utilisateur.
| Code | HTTP | Signification |
|---|---|---|
sender_not_verified | 422 | Tout envoi réel, même gratuit, exige un e-mail confirmé et une entreprise vérifiée. Le mode test reste disponible. |
weight_class_unavailable | 422 | Tranche non activée ou poids supérieur à 350 grammes. |
service_unavailable | 422 | Le service choisi ou le stock reçu n’est pas disponible. |
invalid_post_date | 422 | Le jour de dépôt n’est pas un jour ouvrable valable dans les 90 jours. |
address_incomplete | 422 | Un champ d'adresse manque ou le code postal est incorrect. |
insufficient_balance | 422 | Votre crédit ne suffit pas. |
pdf_invalid | 422 | Le PDF ne peut pas être ouvert, n'est pas un PDF ou dépasse 20 Mo. |
too_many_sheets | 422 | Plus de 8 feuilles, page d'adresse comprise. |
express_limit | 422 | Plus de 1000 lettres express sur une journée. |
country_not_supported | 422 | Pays hors de la Belgique et de l'UE. |
express_not_available | 422 | L'express n'est pas disponible vers les autres pays de l'UE. |
daily_limit | 422 | Maximum journalier de lettres atteint (1000 par défaut, ajustable sur demande). |
template_invalid | 422 | Modèle introuvable ou champs manquants. |
invalid_request | 400 | Requête invalide, p. ex. source manquante ou lien QR incorrect. |
unauthorized | 401 | Clé manquante, invalide ou révoquée. |
not_found | 404 | La lettre, le webhook ou le point d'accès n'existe pas. Aussi sans clé. |
cutoff_passed | 409 | Trop tard pour annuler, la lettre est en production. |
not_cancellable | 409 | Annulation impossible, p. ex. lettre déjà refusée ou annulée. |
conflict | 409 | Un modèle avec ce code existe déjà. |
rate_limited | 429 | Plus de 60 requêtes par minute. Voyez l'en-tête Retry-After. |
server_error | 500 | Un problème est survenu de notre côté. |
{
"error": {
"code": "address_incomplete",
"message": "Een Belgische postcode bestaat uit 4 cijfers"
}
}Limites
Maximum 60 requêtes par minute par clé ; au-delà, vous recevez 429 rate_limited avec un en-tête Retry-After. PDF jusqu'à 20 Mo, lettres jusqu’à 350 g, moyen et grand après activation, maximum 1000 lettres express par jour et par défaut maximum 1000 lettres par jour par compte. error.code est indépendant de la langue et stable ; message est en néerlandais. CORS est ouvert, mais n'utilisez jamais votre clé dans du code navigateur.
Tarifs
Un seul prix par lettre, HTVA, tout compris : 1 feuille (recto ou recto verso, noir et blanc), enveloppe, vrais timbres et dépôt. Selon vos vraies lettres des 30 derniers jours glissants, nouvelle lettre incluse, sans remise à zéro mensuelle : 1,29 € sous 500, 1,09 € à partir de 500, 0,99 € à partir de 5000. Couleur : +0,08 € par feuille. Recto verso sans supplément. Feuille supplémentaire : +0,10 € par feuille après la première (en recto verso, deux pages par feuille). QR code avec suivi des scans : +0,05 €. La page d'adresse est gratuite et ne compte pas dans le prix. Une lettre standard compte jusqu'à 8 feuilles au total, page d'adresse comprise ; les lettres plus grandes sont possibles sur demande. Vitesses (options.speed) : standard (remise à bpost dans les 3 jours ouvrables), express (+0,15 €, le jour ouvrable même si reçue avant 12h00 Europe/Brussels, sinon le jour ouvrable suivant) et flex (-0,05 €, dans les 5 jours ouvrables). bpost distribue dans les 2 à 3 jours ouvrables après le dépôt. Minimum express via l'API : si vos lettres express d'une journée totalisent moins de 15,00 € à 12h00, la différence est débitée comme ligne "Aanvulling minimum express" ; votre crédit doit la couvrir lors de la création de la lettre. Maximum 1000 lettres express par jour (422 express_limit). Exemples, palier 1 : 1 feuille 1,29 € ; 1 feuille couleur 1,37 € ; 3 feuilles 1,49 € ; 4 pages recto verso (2 feuilles) 1,39 € ; avec QR 1,34 € ; express 1,44 € ; flex 1,24 €. Chaque réponse avec un prix contient price_breakdown avec unit_price_cents, tier, volume_30d, letters_to_next_tier, sheets, total_sheets, speed, options (liste de code, label, amount_cents) et total_cents. Les prix peuvent changer ; lisez-les via GET /balance ou POST /price. Lettres d'essai gratuites : chaque nouveau compte reçoit 3 vraies lettres gratuites, aussi via l'API avec votre clé en mode live. Conditions : vitesse standard, 3 feuilles de contenu maximum, adresse e-mail confirmée et 3 lettres d'essai maximum par adresse de destinataire. Une lettre qui ne remplit pas les conditions est payée avec votre crédit comme d'habitude. Une lettre d'essai a free_trial: true et price_cents: 0 ; l'annuler avant la production la rend. GET /balance affiche free_letters_remaining. Lettre lourde : au-delà de 50 g, nous ajoutons +0,60 € par lettre (option heavy_letter). Autres pays de l'UE : +1,50 € par lettre (option eu), délai de 5 à 10 jours ouvrables après l'envoi, pas d'express. Contrôle d'adresse : pour une adresse belge, nous vérifions que le code postal existe et correspond à la commune. En cas de doute, la lettre reçoit le statut review avec address_warning et nous l'approuvons ou la refusons (crédit remboursé).
Tous les tarifs et le calculateur se trouvent sur la page des tarifs.