Votre propre système lit les demandes de financement qu’Advanta vous adresse, envoie vos décisions, fixe ce que vous exigez avant de financer, gère vos limites, envoie votre relevé bancaire pour rapprochement, invite vos propres clients et fournisseurs et reçoit des webhooks signés quand quelque chose se passe. Chaque écriture a le même effet que la même action dans le portail financeur. Et il emporte toutes vos données, quand vous le voulez : votre droit de sortie.
Authorization: Bearer adv_fk_… à chaque appel : adv_fk_ suivi de 64 caractères hexadécimaux.
Format
JSON en entrée et en sortie. Un relevé bancaire peut aussi être envoyé tel quel, en fichier XML ou CSV.
Commencez par GET /v1/me : il indique à quel financeur appartient la clé, son environnement et ses portées. Listez ensuite les demandes qui vous sont adressées.
curl
export ADVANTA_KEY="adv_fk_…" # your key, shown once when it was issued
export BASE="https://bzsengbmlzzhztjfvcag.supabase.co/functions/v1/funder-api"
# 1. Who am I: funder, environment, scopes
curl -s "$BASE/v1/me" \
-H "Authorization: Bearer $ADVANTA_KEY"
# 2. The requests routed to me that are still open
curl -s "$BASE/v1/requests?status=open&limit=20" \
-H "Authorization: Bearer $ADVANTA_KEY"
JavaScript
// Node.js 18 or later, as an ES module (fetch and top-level await are built in)
const BASE = 'https://bzsengbmlzzhztjfvcag.supabase.co/functions/v1/funder-api';
const headers = { Authorization: `Bearer ${process.env.ADVANTA_KEY}` };
async function call(path) {
const res = await fetch(BASE + path, { headers });
const body = await res.json();
if (!res.ok) throw new Error(`${res.status} ${body.error.code}: ${body.error.message}`);
return body;
}
const me = await call('/v1/me');
console.log(me.environment, me.funder.name, me.key.scopes);
const { count, requests } = await call('/v1/requests?status=open&limit=20');
console.log(`${count} open request(s)`);
for (const r of requests) {
console.log(r.request_ref, r.status, r.total_amount, r.my_offer?.status ?? 'no offer yet');
}
Il n’y a qu’une URL de base. C’est la clé qui décide de l’environnement, et GET /v1/me le renvoie dans environment.
environment
Le financeur
Ce que voit la clé
live
Classé par Advanta comme réel ou pilote.
Uniquement des clients réels.
sandbox
Un financeur de démonstration.
Uniquement des entreprises fictives, sur le plan de démonstration.
unclassified
Pas encore classé par Advanta.
Aucune demande.
Une demande de l’autre plan n’est jamais visible, quelle que soit la clé.
Clés sandbox
Advanta émet une clé sandbox pour un prospect nommé (key.prospect dans GET /v1/me). Comme toute clé, elle n’est affichée qu’une fois et seul son SHA-256 est conservé.
Elle expire 1 à 90 jours après son émission (key.expires_at) ; ensuite, chaque appel répond 401 key_expired. Advanta peut aussi la révoquer à tout moment.
Elle ne voit que des entreprises fictives, sur le plan de démonstration. Ces données sont partagées avec d’autres démonstrations et reconstruites quand le scénario est réinitialisé : attendez-vous à ce qu’elles changent.
Elle lit les demandes, les paramètres, les limites, l’historique de paiement et vos clients (prescripteurs, liens, invitations et rapport), et gère ses propres endpoints de webhook et liens d’entrée en relation : elle ne voit que ceux qu’elle a créés. Un fournisseur invité avec une clé sandbox est enregistré comme entreprise de test sur le plan de démonstration.
Elle ne peut prendre de décisions (proposer, refuser, financer, régler), ajouter des prescripteurs et émettre des liens que si Advanta l’a activé sur la clé, ce qui ajoute la portée decisions:write. Les prescripteurs et les liens du financeur de démonstration sont partagés par toutes les démonstrations.
Vous pouvez avoir une clé sandbox dès aujourd’hui : votre propre système face à nos données de démonstration, avant tout contrat. Écrivez à diogo@advanta.pt. La clé réelle est émise le jour où vous voulez vous connecter.
Authentification et portées
Chaque appel porte Authorization: Bearer adv_fk_<64 hex>. Les clés sont émises par les opérations d’Advanta et appartiennent à un financeur. Une clé n’est affichée qu’une fois, seul son SHA-256 est conservé, et elle peut expirer.
Chaque clé porte des portées. Un appel pour lequel la clé n’a pas la portée répond 403 forbidden.
Portée
Ce qu’elle permet
requests:read
Lire les demandes (GET /v1/requests, GET /v1/requests/{id} et ses documents). Elle lit aussi vos paramètres et les documents que vous exigez, les registres de limites, l’historique de paiement, vos clients (prescripteurs, liens, invitations et rapport), vos liens d’entrée en relation, vos endpoints de webhook et leurs journaux de livraison. Elle lit aussi les conditions de votre programme (GET /v1/programme), les réclamations de recours (GET /v1/recourse), vos données bancaires (GET /v1/bank-data), ainsi que les notifications d’une demande et le flux de trésorerie que son cédant partage avec vous.
limits:read
Lire les registres de limites (GET /v1/credit-limits, GET /v1/seller-limits) et l’historique de paiement.
limits:write
Fixer, réviser ou refuser des limites (PUT /v1/credit-limits, PUT /v1/seller-limits).
decisions:write
Proposer, refuser, financer et régler (POST /v1/requests/{id}/decision), et relever ce que les débiteurs d’une demande doivent signer (POST /v1/requests/{id}/consent-level). Elle permet aussi toutes les écritures sur les paramètres, les limites, les relevés, les clients, les liens d’entrée en relation et les endpoints de webhook, ainsi que la lecture des endpoints de webhook, des clients et des liens d’entrée en relation. Elle permet aussi d’exporter toutes vos données. Elle permet aussi d’annoncer une demande confidentielle (POST /v1/requests/{id}/announce), de clore une réclamation de recours (POST /v1/recourse/{id}/close) et de modifier les conditions de votre programme.
settings:write
Modifier ce que vos débiteurs doivent signer avant que vous financiez (PUT /v1/settings) et les documents que vous exigez des cédants (PUT /v1/required-documents). Aussi les conditions de votre programme (PUT /v1/programme).
statements:write
Envoyer un relevé bancaire (POST /v1/statements).
clients:write
Gérer vos clients : ajouter et désactiver des prescripteurs (POST /v1/prescribers, POST /v1/prescribers/{id}/disable), émettre, remplacer et désactiver des liens (POST /v1/client-links, POST /v1/client-links/{id}/disable), et les lire, ainsi que les invitations et le rapport.
webhooks:write
Gérer les endpoints de webhook : créer, arrêter, changer le secret, envoyer un test, et lire la liste et les journaux de livraison.
onboarding:write
Créer des liens d’entrée en relation pour vos fournisseurs (POST /v1/onboarding-links) et les lire.
exports:write
Exporter toutes vos données (POST /v1/exports, GET /v1/exports, GET /v1/exports/{id} et ses documents). Clés de production uniquement.
Endpoints
Les chemins sont relatifs à l’URL de base. Tout appel peut répondre 401 (unauthorized ou key_expired), un appel qui exige une portée peut répondre 403 forbidden (la clé n’a pas la portée, ou le financeur n’est pas actif), et 500 signifie de réessayer plus tard. Ils ne sont pas répétés ci-dessous ; la section Erreurs liste tous les codes.
Votre clé
À quel financeur appartient une clé, son environnement et ses portées. Commencez ici.
GET/v1/health
Indique si l’API fonctionne. Publique : sans clé, sans données, sans accès à la base de données.
Portée
Aucune : publique, sans clé
Renvoie
200{ status, api_version, time }
Erreurs
Aucune
Advanta interroge cette route toutes les 5 minutes ; les résultats sont publiés sur la page d’état publique.
curl
curl -s "$BASE/v1/health"
GET/v1/me
Qui appelle : la clé, son financeur, son environnement et ses portées.
Portée
Toute clé valide
Renvoie
200{ api_version, environment, funder, key }
Erreurs
405method_not_allowed
key.prefix correspond aux 12 premiers caractères de la clé. key.expires_at vaut null pour une clé qui n’expire pas ; key.prospect indique à qui une clé sandbox a été émise.
Lisez les demandes qu’Advanta vous a adressées, puis proposez, refusez, financez ou enregistrez un encaissement ; et exigez davantage des débiteurs d’une demande quand il le faut.
GET/v1/requests
Les demandes qui vous sont adressées (vous pouvez agir dessus) et celles sur lesquelles vous avez déjà agi (en lecture seule, même après une réaffectation), de la plus récente à la plus ancienne, chacune avec votre propre offre dans my_offer si vous en avez fait une.
Nom
Où
Description
status
query
open (par défaut : pending, submitted, under_review, terms_sent, accepted, approved), all, ou un seul statut.
limit
query
De 1 à 200, 50 par défaut.
Portée
requests:read
Renvoie
200{ funder, count, requests[] }
Erreurs
Seulement les codes communs (401, 403, 500).
Une demande comporte id, request_ref, type (factoring ou confirming), status, total_amount, advance_amount, le cédant dans company_name et company_nif, invoice_count, assigned_bank_id, consent_level_required (ce que chaque débiteur doit signer avant qu’elle puisse être financée, fixé à son adressage), ses dates et, par débiteur, debtor_consent. La spécification liste tous les champs.
const BASE = 'https://bzsengbmlzzhztjfvcag.supabase.co/functions/v1/funder-api';
const headers = { Authorization: `Bearer ${process.env.ADVANTA_KEY}` };
const res = await fetch(`${BASE}/v1/requests?status=open&limit=200`, { headers });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { funder, requests } = await res.json();
// Routed to you (you can act on them) and not priced by you yet
const toPrice = requests.filter((r) => r.assigned_bank_id === funder.bank_id && !r.my_offer);
for (const r of toPrice) console.log(r.request_ref, r.type, r.total_amount, r.company_name);
Le dossier d’analyse d’une demande : la demande, ses créances, le dernier Advanta Score du cédant, votre propre offre et risk, les signaux de fraude et les contestations de la demande, tels que votre portail les montre.
score va de 300 à 850, avec une note de A à E et ses dimensions. Il est calculé à la volée quand le cédant n’en a pas encore, et vaut null si ce calcul échoue. Chaque créance a invoice_no, invoice_amount, invoice_date, invoice_due_date et le débiteur dans customer_name. debtor_consent donne, par débiteur, le statut de la notification, le niveau exigé et le niveau signé (level_achieved), meets_requirement, le canal, le texte de déclaration signé et le signataire.
risk.signals liste les signaux de fraude encore ouverts ou confirmés, chacun avec un code stable (par exemple amount_above_history) et une severity. Un signal hard (par exemple un montant modifié pendant que la facture est dans une demande, un avoir sur cette facture ou une contestation ouverte) bloque l’adressage et le financement jusqu’à ce que l’équipe des opérations d’Advanta l’examine ; les autres ne font que signaler. risk.disputes liste toutes les contestations enregistrées contre la demande.
Proposer des conditions, refuser, financer ou enregistrer un règlement. La demande doit vous être adressée ; sinon, 409 not_routed_to_you.
Nom
Où
Description
id obligatoire
path
L’id de la demande.
Le corps prend l’une de quatre formes, selon decision :
decision
Champs
Effet
offer
rate (pourcentage, supérieur à 0 et jusqu’à 100) et advance_pct (même plage), tous deux obligatoires ; days, notes, valid_days (de 1 à 90).
Envoie vos conditions et fait passer une demande pending, submitted ou under-review à terms_sent. L’offre expire après valid_days, sinon au terme de la validité configurée (7 jours par défaut). Refusée avec 409 credit_limit quand une de vos limites ne peut pas l’absorber, avec 409 debtor_not_eligible_for_funder quand vous n’acceptez que les acheteurs de votre liste et qu’un débiteur n’y figure pas, et avec 409 documents_missing_for_funder quand un document que vous exigez du cédant manque, n’est pas vérifié ou a expiré.
decline
reason ou notes, au moins l’un des deux ; notes est le message que lit le cédant. internal_note facultatif : réservé à votre équipe, jamais montré au cédant.
Clôt la demande. reason est l’un de payer_credit, invoice_ineligible, documentation, concentration, amount_out_of_range, sector_excluded, no_funder_capacity, withdrawn_by_client ou other ; le texte libre est conservé en note avec le motif other.
fund
value_date (AAAA-MM-JJ, la date de valeur de votre virement au cédant, au plus 7 jours à l’avance) et reference (la référence du virement, de 3 à 140 caractères) ; amount facultatif, vérifié par rapport à l’avance acceptée.
Seulement une fois que le cédant a accepté vos conditions (statut approved). En affacturage, la notification de chaque débiteur doit d’abord être confirmée (sinon 409 funding_gate_failed), et les documents que vous exigez du cédant doivent être valides à la date du financement (sinon 409 documents_missing_for_funder).
settle
amount (obligatoire) ; received_at (maintenant par défaut, au plus un jour dans le futur) ; reference (jusqu’à 140 caractères) ; note (jusqu’à 1 000) ; final.
Enregistre un encaissement sur une demande financée. Les paiements partiels s’additionnent ; la demande passe à settled quand le total atteint le montant de la demande ou que final vaut true.
Portée
decisions:write
Renvoie
201{ decision, request_id, offer_id, expires_at, status }(offer)
Relever ce que les débiteurs d’une demande doivent signer. Uniquement à la hausse, uniquement sur une demande d’affacturage qui vous est adressée et en cours, et uniquement avant qu’un de ses débiteurs ait répondu.
Nom
Où
Description
id obligatoire
path
L’id de la demande.
level obligatoire
body
receipt, acknowledgment ou acceptance, du plus bas au plus haut.
reason obligatoire
body
Pourquoi, au moins 8 caractères.
Portée
decisions:write
Renvoie
200{ request_id, consent_level_required, changed, from }
curl -s -X POST "$BASE/v1/requests/4c1e0d2a-8f3b-4f6e-9a55-3c2b1d0e9f87/consent-level" \
-H "Authorization: Bearer $ADVANTA_KEY" \
-H "Content-Type: application/json" \
-d '{"level":"acceptance","reason":"Credit committee asked for acceptance on this buyer"}'
Documents et règles
Ce qui doit être en place avant de financer : les documents que vous exigez des cédants, par pays du cédant, et ce que chaque débiteur doit signer. Chaque demande garde les versions qui ont satisfait vos exigences.
GET/v1/requests/{id}/documents
Le dossier documentaire d’une demande. Quand la demande vous a été adressée, puis quand elle a été financée, Advanta a enregistré quelle version de chaque document que vous exigez vous a donné satisfaction : nom du fichier, SHA-256, dates d’émission et de validité, et quand et comment Advanta l’a vérifié. Cet enregistrement ne change jamais, même quand le cédant dépose des versions plus récentes ; chaque entrée indique aussi où en est le document aujourd’hui, et current liste les documents actuels du cédant.
Chaque entrée avec un fichier porte une download_url valable deux minutes (url_expires_in), et chaque URL émise est journalisée. Comparez le SHA-256 de ce que vous téléchargez avec celui enregistré.
Les documents que vous exigez des cédants, par pays du cédant, et le catalogue dans lequel ils sont choisis : le code de chaque document, son nom en sept langues, l’émetteur, la validité habituelle et la sensibilité. La validité habituelle ne sert qu’à pré-remplir : c’est la date imprimée sur le document qui compte, celle que le cédant saisit et qu’Advanta vérifie.
Portée
requests:read
Renvoie
200{ funder, required, catalogue[] }
Erreurs
Seulement les codes communs (401, 403, 500).
Une demande ne vous est adressée, votre offre n’est enregistrée et la demande n’est financée que tant que chaque document de votre liste pour le pays du cédant est vérifié par Advanta et valide à cette date ; sinon, 409 documents_missing_for_funder.
Remplacer votre liste pour un pays de cédants ; une liste vide l’efface. Les codes viennent du catalogue, et le changement est conservé dans la chaîne de preuves d’Advanta avec note. Les demandes déjà chez vous y restent ; votre prochaine offre ou votre prochain financement sur l’une d’elles attend que le cédant satisfasse la nouvelle liste (open_requests_not_meeting les compte).
Ce que vos débiteurs doivent signer avant que vous financiez : le niveau que chaque débiteur doit signer avant qu’une demande d’affacturage qui vous est adressée puisse être financée (receipt, puis acknowledgment, puis acceptance), si seuls comptent les textes de déclaration approuvés par un avocat, vos demandes ouvertes par niveau, et les niveaux pour lesquels chaque droit applicable a un texte de déclaration, et dans quelles langues.
Modifier ce que vos débiteurs doivent signer. Le changement s’applique aux demandes qui vous sont adressées à partir de ce moment ; une demande déjà adressée garde le niveau avec lequel elle l’a été. reason est conservé dans la chaîne de preuves d’Advanta.
Nom
Où
Description
debtor_consent_level
body
receipt, acknowledgment ou acceptance.
require_counsel_approved_texts
body
true pour ne compter que les textes de déclaration approuvés par un avocat.
Choisissez, par défaut et par entreprise, si chaque débiteur reçoit la notification avant que vous financiez (annoncé) ou si la notification est préparée et gardée prête à l’envoi (confidentiel), avec ou sans recours, et si vous demandez les données bancaires du cédant. Ensuite, annoncez une demande confidentielle, lisez ses notifications et le flux de trésorerie que le cédant partage avec vous, et suivez vos réclamations de recours.
GET/v1/programme
Les conditions de votre programme : vos conditions par défaut, celles que vous avez fixées pour certaines entreprises, les entreprises pour lesquelles vous pouvez en fixer (celles qui ont une demande qui vous est adressée, et vos propres clients) et vos demandes d’affacturage comptées selon les conditions qu’elles portent. Une demande prend les conditions en vigueur quand elle vous est adressée et les garde.
disclosure : announced (par défaut) : chaque débiteur reçoit la notification et confirme la cession avant que vous financiez. confidential : quand la demande vous est adressée, la notification à chaque débiteur est préparée, avec son empreinte (SHA-256), et conservée prête à l’envoi, et le financement n’attend pas le débiteur. Avant le financement, tous les contrôles bloquants des factures doivent être passés, les factures doivent venir de la comptabilité du cédant lui-même (ERP, facture électronique ou SAF-T), chaque débiteur doit avoir une notification préparée et à jour qui vous nomme et une adresse où l’envoyer, et la vérification du cédant doit être approuvée. Les notifications sont envoyées quand vous annoncez la demande, et automatiquement, sur une demande financée, quand un déclencheur que vous avez activé se produit : announce_overdue_days, announce_on_dispute, announce_on_kyc_lapse.
recourse : with (avec recours) ou without (sans recours). recourse_days : jours après l’échéance d’une facture avant qu’une demande financée pas encore réglée n’ouvre une réclamation (null : aucune). bank_data : off, requested (le cédant est invité à connecter pour vous son compte bancaire professionnel, en lecture seule et avec son consentement) ou required (le financement attend aussi que le compte sur lequel vous payez soit confirmé comme celui du cédant lui-même).
Modifier vos conditions par défaut (sans seller_id) ou celles d’une entreprise. Seules les clés envoyées changent ; {"reset": true} avec un seller_id ramène cette entreprise à vos conditions par défaut. Le changement s’applique aux demandes qui vous sont adressées à partir de ce moment ; les demandes déjà adressées gardent leurs conditions. reason est conservé dans la chaîne de preuves d’Advanta.
Nom
Où
Description
seller_id
body
L’id d’une entreprise, tiré de sellers dans GET /v1/programme. Absent ou null : vos conditions par défaut.
terms obligatoire
body
Les conditions à modifier : disclosure, recourse, recourse_days, announce_overdue_days, announce_on_dispute, announce_on_kyc_lapse, bank_data ; ou reset.
Annoncer une demande confidentielle qui vous est adressée : elle devient annoncée et les notifications préparées pour elle sont envoyées à ses débiteurs, qui les confirment ensuite comme dans un programme annoncé. Possible tant que la demande est en attente, à l’étude, avec des conditions envoyées, approuvée ou financée. Un événement request.announced suit ; une fois une notification envoyée, la demande reste annoncée.
Nom
Où
Description
id obligatoire
path
L’id de la demande.
reason obligatoire
body
Pourquoi, au moins 8 caractères. Conservé dans la chaîne de preuves d’Advanta.
curl -s -X POST "$BASE/v1/requests/4c1e0d2a-8f3b-4f6e-9a55-3c2b1d0e9f87/announce" \
-H "Authorization: Bearer $ADVANTA_KEY" \
-H "Content-Type: application/json" \
-d '{"reason":"Invoice 2026-118 is 20 days overdue"}'
GET/v1/requests/{id}/notices
Les notifications de cession de la demande, une par débiteur, chacune avec son document préparé quand il existe : l’objet et le HTML exacts que reçoit le débiteur, sa langue, le droit applicable et son SHA-256. Pour une demande qui vous est adressée, ou une sur laquelle vous avez déjà agi.
Nom
Où
Description
id obligatoire
path
L’id de la demande.
Portée
requests:read
Renvoie
200{ request_id, count, notices[] }
Erreurs
404not_found
Le HTML porte un marqueur, ACK_LINK entre doubles accolades, à l’endroit du lien de confirmation du débiteur ; le lien contient un secret et n’est jamais montré. current indique si le document correspond encore aux factures et au montant de la notification.
Ce que le cédant partage avec vous de son compte bancaire professionnel, en lecture seule et avec son consentement, par un prestataire agréé d’information sur les comptes : la connexion, ses comptes (les quatre derniers caractères de chaque IBAN) et leurs soldes, douze mois de mouvements par mois, et la vérification de son compte de versement. cash_flow vaut null tant que le cédant n’a pas connecté de compte pour vous.
bank_data_problems dit ce que le financement attend encore quand vos conditions exigent des données bancaires. payment_alerts sont les paiements que le cédant a reçus d’un débiteur de cette demande après que vous l’avez financée en conditions confidentielles. Le consentement d’un cédant est donné à un financeur : vous ne voyez que ce qu’il partage avec vous.
Vos demandes d’affacturage financées par type de recours (with, without, et not_recorded pour celles adressées avant le 28 septembre 2026), les réclamations comptées par type et statut, et les réclamations elles-mêmes, les ouvertes d’abord. Une réclamation s’ouvre une fois par demande, quand une demande financée n’est pas réglée recourse_days après l’échéance d’une facture : recourse, contre le cédant, pour le montant avancé plus vos frais, moins ce que vous avez déjà encaissé ; debtor_default, sans recours, pour votre propre recouvrement et votre assurance.
Nom
Où
Description
status
query
open, settled, withdrawn ou written_off. Absent : toutes les réclamations.
Le cédant rembourse une réclamation de recours sur pay_to_iban en indiquant pay_reference. Quand les paiements que vous enregistrez à partir de là (une ligne de relevé que vous confirmez, ou la décisionsettle) couvrent claim_amount, la réclamation est réglée et la demande se clôt comme réglée par recours : les factures reviennent au cédant, toujours impayées par le débiteur.
Clore une de vos réclamations ouvertes : une réclamation de recours devient withdrawn (vous y renoncez, ou vous avez convenu autre chose avec le cédant), un défaut du débiteur devient written_off (transmis à votre recouvrement ou à votre assureur). reason est conservé dans la chaîne de preuves d’Advanta.
curl -s -X POST "$BASE/v1/recourse/$CLAIM_ID/close" \
-H "Authorization: Bearer $ADVANTA_KEY" \
-H "Content-Type: application/json" \
-d '{"status":"withdrawn","reason":"Payment plan agreed with the seller on 2 October"}'
GET/v1/bank-data
Votre propre compte d’encaissement, connecté par votre administrateur dans le portail et lu de la même façon : ses mouvements passent par le même rapprochement que POST /v1/statements, pour que les encaissements correspondent à vos demandes financées sans envoyer de fichier. Aussi : combien de cédants partagent leur compte avec vous, les alertes de paiement sur vos demandes (les 180 derniers jours) et les frais du prestataire enregistrés à votre charge, par mois.
Votre exposition par débiteur et par cédant, appliquée par la plateforme elle-même, avec des limites fixées une à une ou jusqu’à 2 000 d’un coup ; la façon dont un acheteur paie ses fournisseurs ; et ce qu’Advanta sait de chaque débiteur d’une demande.
GET/v1/credit-limits
Votre registre par débiteur : votre limite et ce qui est en cours, engagé, proposé et encore disponible, en euros.
Portée
limits:read ou requests:read
Renvoie
200{ funder, currency, count, debtors[] }
Erreurs
Seulement les codes communs (401, 403, 500).
Chaque débiteur comporte debtor_key, debtor_name, debtor_country, limit_status, limit_amount, outstanding, committed, offered, available, overdue_count, oldest_overdue, frozen, decided_at et note.
Fixer ou réviser votre limite sur un débiteur, ou refuser le débiteur. La base de données refuse toute offre ultérieure que cette limite ne peut pas absorber.
Nom
Où
Description
debtor_tax_id obligatoire
body
Le numéro de TVA ou d’identification fiscale du débiteur.
debtor_country
body
ISO 3166 alpha-2.
debtor_name
body
Le nom du débiteur.
amount
body
En euros, 0 ou plus. Obligatoire pour une limite active.
Charger jusqu’à 2 000 limites sur des débiteurs en un seul appel : votre propre registre, ou les limites de votre assureur-crédit. Chaque ligne est vérifiée exactement comme PUT /v1/credit-limits en vérifie une et reçoit sa propre réponse : une ligne en échec n’arrête pas les autres, et un débiteur présent deux fois dans le même appel est refusé la seconde fois.
Nom
Où
Description
rows obligatoire
body
De 1 à 2 000 lignes, chacune avec debtor_tax_id et, comme dans PUT /v1/credit-limits, debtor_country, debtor_name, amount, status et note. amount est un nombre ou des chiffres avec un point décimal ; il est obligatoire pour une limite active. Une simple liste de lignes, sans l’objet autour, est aussi acceptée (avec source import).
source
body
import (vos propres limites, par défaut) ou insurer (les limites de votre assureur-crédit).
source_ref
body
Le fichier ou le lot d’où viennent les limites, 200 caractères au plus.
Chaque limite écrite enregistre sa source et sa référence, sur la limite et dans son historique. La réponse compte received, written et refused, et répond à chaque ligne avec row (à partir de 1), debtor_tax_id et ok : une ligne écrite ajoute debtor_key, status et amount ; une ligne refusée donne son error (invalid_amount, debtor_tax_id_required, duplicate_debtor, invalid_status, amount_required, invalid_country, row_invalid ou invalid_limit) et peut ajouter un detail.
Comment un acheteur paie ses fournisseurs, uniquement en agrégé, à partir de la comptabilité des fournisseurs connectés à Advanta. L’historique est publié quand au moins trois fournisseurs observent l’acheteur ; sinon, status dit pourquoi et tous les chiffres valent null. Vous ne pouvez le lire que pour un acheteur présent sur une demande de votre périmètre ou sur votre liste de débiteurs ; une clé sandbox lit l’historique du plan de démonstration.
Nom
Où
Description
tax_id obligatoire
query
Le numéro de TVA ou d’identification fiscale de l’acheteur.
country
query
ISO 3166 alpha-2.
Portée
limits:read ou requests:read
Renvoie
200{ funder, payer_record }
Erreurs
404not_found(l’acheteur n’est sur aucune demande de votre périmètre ni sur votre liste de débiteurs)
422tax_id_required
Les chiffres comprennent observers, invoice_count, avg_days_to_pay, median_days_to_pay, on_time_pct, le retard de paiement (avg_settle_delay_days, median_settle_delay_days, p75_settle_delay_days, worst_settle_delay_days), des comptes de factures ouvertes et échues, window_from et refreshed_at. payer_record vaut null quand il n’y a pas d’historique.
Ce qu’Advanta sait de chaque débiteur d’une demande d’affacturage qui vous est adressée, ou d’une sur laquelle vous avez déjà agi : son level sur Advanta depuis level_since (notice : il ne connaît Advanta que par la notification ; account : il a activé son compte de payeur ; books : il a connecté son logiciel comptable ; buyer : il gère un programme acheteur, et buyer_programme vaut true), l’historique du cédant lui-même avec lui, son délai moyen de paiement officiel quand c’est un organisme public, et votre limite sur lui.
Nom
Où
Description
id obligatoire
path
L’id de la demande.
Portée
requests:read
Renvoie
200{ funder, request_id, count, debtors[] }
Erreurs
404not_found
score est le score propre du débiteur (note, de 0 à 100, quand et avec quelle version du modèle). Il n’est donné que si le débiteur partage ses données avec les financeurs qui financent des factures qu’il doit, est au niveau books ou buyer, et que la demande vous est adressée (pas une sur laquelle vous avez seulement agi) ; sinon il vaut null. pair_history est l’historique du cédant avec ce débiteur sur 36 mois, selon les règles de l’historique de paiement : uniquement des factures réelles, et un retard mesuré seulement par rapport aux échéances indiquées sur le document ou dans l’ERP. public_payment_period est le dernier délai moyen de paiement officiel d’un organisme public (DGAL pour les communes portugaises, Hacienda pour les collectivités locales espagnoles). credit_limit est votre limite sur le débiteur, son origine (source, source_ref) et ce qui est utilisé (exposure : en cours plus engagé plus proposé, en euros).
Envoyez le relevé de votre compte d’encaissement et chaque crédit est rapproché de vos demandes financées ; vous confirmez chaque rapprochement dans le portail. Pour enregistrer vous-même un paiement, envoyez la décisionsettle.
POST/v1/statements
Envoyer le relevé de votre compte d’encaissement pour rapprochement : un fichier CAMT.053 (XML) ou CSV, au plus 4 Mio et 5 000 opérations. Chaque crédit est rapproché de vos propres demandes financées, d’abord sur la référence indiquée par le débiteur. Rien n’est réglé tant que vous n’avez pas confirmé un rapprochement dans le portail. Le même fichier envoyé deux fois est refusé, d’après son SHA-256.
Nom
Où
Description
file_name
query
Le nom du fichier (facultatif).
kind
query
camt053 ou csv ; détecté s’il est omis.
le fichier obligatoire
body
Le fichier tel quel, envoyé en application/xml ou text/csv ; ou du JSON { file_name, kind, content_base64 }.
Amenez vos propres clients : un lien ouvert à vous, un lien par prescripteur, et les invitations et le rapport qui montrent qui est arrivé par chacun. Les entreprises que vous amenez ne sont adressées qu’à vous.
GET/v1/client-links
Votre propre lien ouvert (prescriber_id null) et le lien actuel de chaque prescripteur, avec son state (active, disabled ou expired) et son url tant qu’il fonctionne.
Nom
Où
Description
lang
query
La langue de la page qu’ouvre chaque lien : pt, es, en, fr, de, it ou nl, ajoutée à son url.
Portée
requests:read, clients:write ou decisions:write
Renvoie
200{ funder, count, client_links[] }
Erreurs
422lang_invalid
Une entreprise qui ouvre un lien donne son nom, son numéro fiscal, son pays et son e-mail, et reçoit votre invitation par e-mail. Quand elle l’accepte, elle devient votre cliente : ses demandes ne sont adressées qu’à vous, et son origine (le lien, le prescripteur, la date) est enregistrée. Ouvrir un lien ne crée jamais de compte à lui seul.
Chaque lien porte aussi arrivals (les entreprises dont la première arrivée chez vous est passée par lui) et claims_last_day (les inscriptions par ce lien sur les dernières 24 heures ; un lien en accepte au plus 20 par heure et 100 par jour).
Émettre votre propre lien ouvert, ou celui d’un prescripteur avec prescriber_id. Il y a un lien actif par titulaire : tant qu’un lien fonctionne, envoyez replace: true pour le remplacer (l’ancien cesse aussitôt de fonctionner) ; sinon 409 link_exists. Seul le SHA-256 du jeton du lien est conservé, et l’émission est enregistrée dans la chaîne de preuves d’Advanta.
Nom
Où
Description
prescriber_id
body
Un de vos prescripteurs actifs ; omettez-le, ou envoyez null, pour votre propre lien.
expires_at
body
Facultatif : entre une heure et trois ans à partir de maintenant.
replace
body
true pour remplacer un lien qui fonctionne encore. Par défaut false.
reason
body
Le motif, jusqu’à 200 caractères. Conservé sur le lien remplacé et dans la chaîne de preuves.
lang
body
La langue de la page qu’ouvre le lien, ajoutée à son url.
Un lien émis avec une clé sandbox ne crée que des invitations de test, et la clé a besoin de decisions:write : les liens du financeur de démonstration sont partagés par toutes les démonstrations.
curl
curl -s -X POST "$BASE/v1/client-links" \
-H "Authorization: Bearer $ADVANTA_KEY" \
-H "Content-Type: application/json" \
-d '{"replace":true,"reason":"The old link was forwarded too widely","lang":"es"}'
Désactiver un lien. Il cesse aussitôt de fonctionner ; les entreprises déjà arrivées par lui gardent leur origine. Désactiver un lien déjà désactivé ne change rien (changed vaut false). Pour en donner un nouveau, appelez POST /v1/client-links.
Vos prescripteurs, les personnes et cabinets qui vous apportent des clients (experts-comptables, conseillers, courtiers), les actifs d’abord, chacun avec son lien actuel et le nombre d’entreprises arrivées par ce lien. Ce sont les vôtres, pas des partenaires d’Advanta. La même liste que la page Clients de votre portail.
Nom
Où
Description
lang
query
La langue de la page qu’ouvre chaque lien : pt, es, en, fr, de, it ou nl, ajoutée à son url.
Portée
requests:read, clients:write ou decisions:write
Renvoie
200{ funder, count, prescribers[] }
Erreurs
422lang_invalid
Une clé sandbox lit les prescripteurs du financeur de démonstration, que toutes les démonstrations partagent.
Ajouter un prescripteur. Son propre lien ouvert est émis avec lui, dans prescriber.link.url. Son nom et son e-mail restent hors de la chaîne de preuves d’Advanta : seuls leurs hachages y figurent.
Nom
Où
Description
name obligatoire
body
De 2 à 120 caractères, unique parmi vos prescripteurs actifs.
email
body
Facultatif. Un financeur sandbox n’enregistre que des adresses réservées (se terminant par .example, .invalid, .test ou .demo).
notes
body
Facultatif, jusqu’à 1 000 caractères.
lang
body
La langue de la page qu’ouvre son lien, ajoutée à son url.
Désactiver un prescripteur. Son lien cesse aussitôt de fonctionner ; les entreprises qu’il a apportées lui restent attribuées. Désactiver un prescripteur déjà désactivé ne change rien (changed vaut false). Enregistré dans la chaîne de preuves d’Advanta.
Ce que chaque prescripteur vous a apporté : un groupe par prescripteur, puis votre propre lien (own_link), vos invitations par nom (named) et vos liens d’entrée en relation (api). Par groupe et par entreprise : quand elle est arrivée, quand son compte a été ouvert (joined), quand la vérification de l’entreprise a été approuvée (onboarded), les demandes qui vous ont été adressées, le montant demandé et le montant financé. Les mêmes chiffres que votre portail.
Une entreprise compte une fois, pour qui vous l’a apportée en premier. Le montant financé est l’avance (à défaut, le total) des demandes financées ou réglées, en euros ; totals additionne tous les groupes. Seulement vos données et seulement les entreprises de votre plan de données : une clé sandbox ne voit pas ce que d’autres clés sandbox ont fait par l’API.
Toutes vos invitations, les plus récentes d’abord : par un lien, par nom dans le portail ou avec un lien d’entrée en relation. Chacune indique comment l’entreprise est arrivée (via : link, named ou api), le prescripteur qui l’a apportée le cas échéant, son state (pending, accepted, revoked ou expired), l’entreprise, le contact et les dates.
Nom
Où
Description
limit
query
De 1 à 500, 200 par défaut.
Portée
requests:read, clients:write ou decisions:write
Renvoie
200{ funder, count, invitations[] }
Erreurs
405method_not_allowed
Seulement votre propre plan de données. Une clé sandbox ne voit pas les invitations faites par d’autres clés sandbox.
Chaque matin, les factures de vos propres clients devenues éligibles selon vos règles pendant la nuit, et ce qui a changé dans celles qui vous ont été montrées. Le webhookopportunities.daily signale quand il y a quelque chose à lire.
GET/v1/opportunities
Le résumé d’un jour, pour vos propres clients (les entreprises dont vous êtes le financeur d’origine) qui vous permettent de voir leurs factures. Chaque matin vers 6 h 30, heure de Madrid, après la préqualification de la nuit, Advanta liste les factures devenues éligibles selon vos règles depuis le résumé précédent (kind new) et ce qui a changé dans celles qui vous ont déjà été montrées : paid, disputed (le client a enregistré que son débiteur la conteste) ou no_longer_eligible.
Nom
Où
Description
date
query
Le jour du résumé, YYYY-MM-DD (heure de Madrid). Absent : le plus récent. Un jour sans résumé répond date null et aucune ligne.
Portée
requests:read
Renvoie
200{ funder, date, digest, lines[] }
Erreurs
404not_found
405method_not_allowed
422invalid_date
Une ligne porte la facture, le débiteur avec son numéro fiscal, le montant encore dû, l’échéance, et le client avec son secteur (section NACE), sa note et sa taille ; d’abord les nouvelles lignes, puis les changements. no_longer_eligible a un reason : requested (le client a demandé à la financer), cancelled, removed (elle n’est plus dans les livres du client), left_programme, not_shared (le client a cessé de partager) ou rules (elle ne respecte plus vos règles).
digest donne les totaux : combien de clients partagent et combien pas encore, ce qui est éligible aujourd’hui, ce qui est nouveau et ce qui a changé. stale vaut true quand le traitement de la nuit ne s’est pas terminé : rien n’a été comparé ce matin-là. Un résumé est une liste calculée par la base de données, pas une offre : une demande est vérifiée à nouveau quand elle est faite, et vous décidez comme toujours. Le webhook opportunities.daily signale qu’un résumé avec du contenu est prêt.
Enregistrez les endpoints qui reçoivent les webhooks, changez leurs secrets, envoyez un test et lisez le journal de livraison.
GET/v1/webhooks
Vos endpoints actifs, sans leurs secrets, et les types d’événements auxquels vous pouvez vous abonner. Une clé sandbox ne voit que les endpoints qu’elle a créés.
Enregistrer un endpoint. La réponse contient son secret de signature, qui ne sera plus affiché.
Nom
Où
Description
url obligatoire
body
https sur un nom d’hôte public, port 443, sans nom d’utilisateur ni mot de passe ; 2 048 caractères au plus. Les adresses privées, de bouclage et link-local sont refusées, et les redirections ne sont jamais suivies.
events
body
Une liste de types d’événements, ou ["*"] pour tous (par défaut).
Un nouveau secret de signature, affiché une seule fois. L’ancien secret continue de signer, en second v1 dans l’en-tête, pendant keep_previous_hours, pour que vous puissiez basculer sans perdre d’événements.
curl -s -X POST "$BASE/v1/webhooks/$WEBHOOK_ID/test" \
-H "Authorization: Bearer $ADVANTA_KEY"
GET/v1/webhooks/{id}/deliveries
Le journal de livraison d’un endpoint, du plus récent au plus ancien : statut (pending, delivered, failed ou cancelled), tentatives, code de réponse, dernière erreur, prochaine tentative, et le SHA-256 du corps exact envoyé.
Depuis votre propre produit, remettez à un fournisseur un lien Advanta d’entrée en relation à usage unique ; le fournisseur vous revient avec un statut signé quand il a terminé.
POST/v1/onboarding-links
Un lien d’entrée en relation à usage unique pour l’un de vos fournisseurs, qui vous est attribué. Advanta n’envoie aucun e-mail : c’est vous qui remettez url à votre fournisseur. Quand le fournisseur a soumis la vérification de son entreprise, vous recevez onboarding.completed, et le fournisseur est renvoyé vers votre return_url avec un statut signé.
Nom
Où
Description
company_vat obligatoire
body
Le numéro de TVA ou fiscal du fournisseur, avec ou sans le préfixe du pays.
country obligatoire
body
ISO 3166 alpha-2.
contact_email obligatoire
body
L’e-mail du contact chez le fournisseur.
return_url obligatoire
body
https, jusqu’à 2 048 caractères, sur une origine de votre liste d’origines de retour. Cette liste est tenue dans les paramètres du portail ou par Advanta, jamais par cette API.
company_name
body
De 2 à 200 caractères. Peut être omis pour un numéro de TVA de l’UE que VIES sait nommer.
contact_name
body
Jusqu’à 120 caractères.
metadata
body
Vos propres clés et valeurs : au plus 20 clés, valeurs texte, nombre, true, false ou null, 2 Ko de JSON. Renvoyées sur le lien et dans onboarding.completed.
locale
body
La langue de l’entrée en relation : pt, es, en, fr, de, it ou nl.
La réponse contient return_secret (ors_ suivi de 64 caractères hexadécimaux), affiché une seule fois : conservez-le tout de suite. Seul le SHA-256 du jeton du lien est conservé. Un lien créé avec une clé sandbox enregistre le fournisseur comme entreprise de test sur le plan de démonstration.
Quand le fournisseur revient, return_url porte advanta_onboarding (l’id du lien), advanta_status (completed), advanta_ts (secondes Unix) et advanta_sig : le HMAC-SHA256 hexadécimal de <advanta_onboarding>.<advanta_status>.<advanta_ts>, avec votre return_secret pour clé. Vérifiez-le avant que votre page se fie au statut, et refusez un retour à plus de 600 secondes de votre horloge ; le dernier exemple ci-dessous fait les deux.
curl
curl -s -X POST "$BASE/v1/onboarding-links" \
-H "Authorization: Bearer $ADVANTA_KEY" \
-H "Content-Type: application/json" \
-d '{"company_vat":"PT500000000","country":"PT","contact_email":"ana@fornecedor.example","contact_name":"Ana Sousa","company_name":"Fornecedor Exemplo, Lda.","return_url":"https://portal.example.com/onboarding/done","metadata":{"supplier_ref":"S-42"},"locale":"pt"}'
import crypto from 'node:crypto';
// On the page behind your return_url.// url: the full address the supplier came back to// returnSecret: the "ors_…" string POST /v1/onboarding-links returned, stored when you made the link
export function verifyAdvantaReturn(url, returnSecret, nowSeconds = Math.floor(Date.now() / 1000)) {
const q = new URL(url).searchParams;
const id = q.get('advanta_onboarding') ?? '';
const status = q.get('advanta_status') ?? '';
const ts = q.get('advanta_ts') ?? '';
const sig = q.get('advanta_sig') ?? '';
if (!id || !status || !/^[0-9]{1,12}$/.test(ts) || !/^[0-9a-f]{64}$/.test(sig)) return null;
if (Math.abs(nowSeconds - Number(ts)) > 600) return null; // too old: ask your back end instead
const expected = crypto.createHmac('sha256', returnSecret).update(`${id}.${status}.${ts}`).digest();
if (!crypto.timingSafeEqual(Buffer.from(sig, 'hex'), expected)) return null;
return { onboardingLinkId: id, status }; // status is "completed"
}
GET/v1/onboarding-links
Vos liens d’entrée en relation, les plus récents d’abord, chacun avec son status : pending, account_created, completed, expired ou revoked. Une clé sandbox voit les liens qu’elle a créés.
Nom
Où
Description
limit
query
De 1 à 200, 50 par défaut.
Portée
onboarding:write, decisions:write ou requests:read
Emportez tout ce que vous pouvez voir sur Advanta, quand vous le voulez, sans le demander : votre droit de sortie (DORA art. 28, par. 8, et art. 30, par. 3, point f). Un ZIP avec un CSV et un fichier JSON Lines par entité, schema.json, manifest.json avec le SHA-256 de chaque fichier, un README dans votre langue et verify.py.
POST/v1/exports
Lance un export de tout ce que votre financeur peut voir : demandes et leur historique, offres, factures avec leur vérification, vendeurs (données de l’entreprise, le résumé KYC que vous pouvez voir, la vérification du représentant), débiteurs, notifications avec les réponses des débiteurs et les données des certificats, les entrées de la chaîne de preuve sur vos opérations avec les hachages et les racines quotidiennes pour les vérifier, règlements et relevés, refus des contrôles, vos règles et limites, votre équipe, endpoints de webhook (jamais un secret), clés d’API (jamais une clé), votre piste d’audit et vos documents. Il est généré en arrière-plan, en général en moins d’une minute ; export.ready vous prévient.
Nom
Où
Description
lang
body
La langue du README : pt, es, en, fr, de, it ou nl (en par défaut).
Portée
exports:write ou decisions:write
Renvoie
202{ funder, export }
Erreurs
403export_live_key_required
409export_in_progress
422body_invalid, lang_invalid
429export_rate_limited
Une clé de production uniquement : une clé sandbox répond 403 export_live_key_required (le financeur de démonstration est partagé). Un export à la fois, au plus 10 en 24 heures. Le même export est sur la page Export du portail, dans les réglages.
Un export. Pendant sa génération : statusqueued ou running, avec progress. Une fois ready, et pendant 24 heures : files, chaque volume avec un lien valable une heure au plus (jamais au-delà de ces 24 heures). Redemandez-le pour de nouveaux liens ; chaque appel qui renvoie des liens est enregistré. Après 24 heures les fichiers sont supprimés et l’enregistrement reste.
Nom
Où
Description
id obligatoire
path
L’id de l’export, de POST /v1/exports ou GET /v1/exports.
Portée
exports:write ou decisions:write
Renvoie
200{ funder, export, files[] }
Erreurs
403export_live_key_required
404not_found
405method_not_allowed
manifest_sha256 est le SHA-256 de manifest.json écrit sans ce champ, clés triées, sans espaces. Advanta a enregistré la même valeur dans la chaîne de preuve (entrée export.ready) ; verify.py la recalcule et vérifie chaque fichier et les entrées de preuve.
# Every volume into one folder, then the checker the export carries
curl -s "$BASE/v1/exports/$EXPORT_ID" -H "Authorization: Bearer $ADVANTA_KEY" \
| jq -r '.files[].url' | while read -r u; do curl -s -o "v$((++n)).zip" "$u"; done
for z in v*.zip; do unzip -q -o "$z" -d export; done
python3 export/advanta-export-*/verify.py # files, manifest digest and evidence chain
GET/v1/exports/{id}/documents
Quand les documents étaient trop volumineux pour être inclus (documents_modelinks) : chaque document de l’export avec un lien valable 15 minutes, une page à la fois. La liste est calculée au moment de la demande : un document que vous ne pouvez plus lire n’y figure pas.
Enregistrez un endpoint HTTPS et Advanta lui envoie un POST signé quand quelque chose vous concerne : sur une demande qui vous est adressée ou sur son cédant, ou sur un lien d’entrée en relation que vous avez créé. Chaque endpoint s’abonne aux types d’événements dont il a besoin. Chaque envoi est signé et, en cas d’échec, relancé pendant 24 heures.
Événements
Événement
Quand
data
request.routed
Les opérations d’Advanta vous ont adressé une demande. Vous pouvez maintenant la lire et décider.
Un document daté (par exemple une attestation fiscale ou sociale) d’un cédant ayant une demande ouverte ou financée qui vous est adressée expire dans 30 jours, dans 7 jours ou aujourd’hui. Vérifié chaque jour ; threshold_days vaut 30, 7 ou 0.
Un débiteur a contesté des factures d’une demande qui vous est adressée, après l’approbation ou le financement. reason vaut goods_not_received, defective, amount_incorrect, already_paid, not_our_invoice ou other ; channel vaut cession_page, letter ou email.
Les opérations d’Advanta ont clos une contestation ; status vaut resolved_for_debtor, resolved_for_seller ou withdrawn.
Les champs de dispute.opened, avec son status, plus resolved_at et resolution_note.
onboarding.completed
Un fournisseur que vous avez invité avec un lien d’entrée en relation a soumis la vérification de son entreprise. status vaut completed ; metadata est la vôtre, telle que vous l’avez envoyée. Pour un lien créé avec une clé sandbox, seuls les endpoints de cette clé le reçoivent.
Une entreprise que vous avez invitée (par son nom, par votre lien ouvert, par le lien d'un prescripteur ou par l'API) a accepté l'invitation et n'est plus qu'à vous : ses demandes n'arrivent qu'à vous. origin indique comment elle est arrivée (named, open_link, prescriber ou api), avec le prescripteur s'il y en a un.
Un export que vous avez demandé (portail ou API) est prêt : téléchargez-le avec GET /v1/exports/{id} dans les 24 heures. Il porte son manifest_sha256, jamais un lien.
Une demande confidentielle qui vous est adressée a été annoncée : par vous, par les opérations d’Advanta ou par un déclencheur que vous avez activé (trigger vaut manual, overdue, dispute ou kyc_lapsed). Ses notifications préparées sont en cours d’envoi ; notices liste chacune avec le SHA-256 de son document.
Une de vos demandes financées n’est pas réglée recourse_days après l’échéance d’une facture : une réclamation de recours contre le cédant (kind recourse) ou un défaut du débiteur (kind debtor_default).
Une réclamation a été réglée : par les paiements que vous avez enregistrés depuis son ouverture (via statement ou manual ; la demande se clôt comme réglée par recours), ou parce que la demande a été réglée de la façon habituelle (via request_settled, sans paid).
Sur un compte que le cédant partage avec vous, un paiement est arrivé d’un débiteur d’une demande que vous avez financée en conditions confidentielles : sa référence porte le numéro d’une facture financée (match_rule invoice_reference), ou le payeur et le montant correspondent (payer_and_amount).
Le résumé du matin contient quelque chose : des factures de vos propres clients devenues éligibles depuis le résumé précédent, ou un changement dans celles qui vous ont été montrées. Un sommaire seulement, des comptes et des totaux, jamais une facture, un débiteur ou un client : lisez les lignes avec GET /v1/opportunities?date= (lines). Au plus un par jour ; aucun un jour sans rien de nouveau ni de changé.
Un bulletin officiel (le BORME pour les sociétés espagnoles, Citius pour les portugaises) a publié un acte qui bloque pour tout nouveau financement un débiteur d’une demande que vous avez financée : insolvabilité déclarée ou en cours, liquidation, procédure close pour insuffisance d’actif, dissolution, extinction, ou feuille du registre fermée par l’administration fiscale ou après une insolvabilité. Tant qu’il tient, aucune nouvelle offre et aucun nouveau financement ne vont aux factures de ce débiteur. Un événement par demande et par passage à bloqué. C’est ce que le bulletin a publié, à examiner par vous, non une conclusion juridique ; seules les sociétés d’Espagne et du Portugal sont surveillées.
Un client a demandé le financement des factures d’une pré-offre que vous lui avez envoyée depuis vos opportunités du matin : sa demande, faite avec tous les contrôles habituels, porte la pré-offre et vous parvient comme toujours (request.routed), et votre règle de crédit prépare votre offre à partir de votre grille. terms est ce que votre grille a donné à l’envoi, à titre indicatif : le prix est le vôtre, Advanta n’en indique aucun. Une fois par pré-offre.
L’événement de test demandé avec POST /v1/webhooks/{id}/test.
La livraison
Chaque livraison est un POST avec un corps JSON, envoyé octet pour octet tel qu’il est stocké (son SHA-256 figure dans le journal de livraison), avec trois en-têtes propres :
L’id de l’événement, identique à Advanta-Event-Id.
object
Toujours event.
type
L’un des types d’événements ci-dessus.
api_version
La révision de l’API dans laquelle l’événement est écrit.
created
La création de l’événement, en secondes Unix.
environment
live, sandbox ou unclassified, comme dans GET /v1/me.
data
Les champs de l’événement, listés ci-dessus.
Livraison et nouvelles tentatives
Répondez par n’importe quel 2xx dans les 10 secondes et l’événement est livré. Toute autre réponse, une absence de réponse en 10 secondes ou une redirection est un échec ; les redirections ne sont jamais suivies.
Une livraison échouée est retentée après 1, 2, 4, 8 … minutes, en doublant, au plus à 6 heures d’intervalle, avec une dernière tentative 24 heures après l’événement. Elle est ensuite marquée failed et reste dans le journal de livraison.
La livraison est « au moins une fois ». Conservez les valeurs de Advanta-Event-Id déjà traitées et ignorez une répétition.
GET /v1/webhooks/{id}/deliveries montre le statut, les tentatives, le code de réponse, la dernière erreur et la prochaine tentative de chaque livraison. POST /v1/webhooks/{id}/test envoie un événement webhook.test quand vous voulez vérifier votre endpoint.
Endpoints et secrets
L’URL d’un endpoint est en https sur un nom d’hôte public, sur le port 443, sans nom d’utilisateur ni mot de passe. Les adresses privées, de bouclage et link-local sont refusées.
Au plus 10 endpoints actifs. Chacun s’abonne à une liste de types d’événements, ou à ["*"] pour tous (par défaut).
Le secret de signature (whsec_ suivi de 64 caractères hexadécimaux) n’est renvoyé qu’une fois : à la création de l’endpoint, puis à chaque changement de secret. Gardez-le comme un mot de passe.
Pour le changer, appelez POST /v1/webhooks/{id}/rotate-secret. L’ancien secret continue de signer, en second v1 dans l’en-tête, pendant keep_previous_hours (de 0 à 72, 24 par défaut). Déployez le nouveau secret dans ce délai et aucun événement n’est perdu.
Vérifier les signatures
Chaque livraison porte Advanta-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256>. Vérifiez-la avant de vous fier au corps :
Lisez le corps brut de la requête, exactement tel qu’il a été reçu, avant toute analyse JSON.
Calculez le HMAC-SHA256 de <t>.<raw body>, avec le secret de l’endpoint comme clé (la chaîne whsec_… complète, en UTF-8), et encodez-le en hexadécimal.
Acceptez la livraison si l’un des v1 de l’en-tête correspond, comparé en temps constant (après un changement de secret, il y en a deux), et si t est à moins de 300 secondes de votre horloge. Sinon, rejetez-la.
Une livraison rejetée ne répond pas 2xx : Advanta la retente comme tout autre échec.
Node.js
import crypto from 'node:crypto';
import express from 'express';
const TOLERANCE_SECONDS = 300;
// header: the Advanta-Signature value// rawBody: the request body as a Buffer, exactly as received (before any JSON parsing)// secret: your endpoint secret, the whole "whsec_…" string
export function verifyAdvantaSignature(header, rawBody, secret, nowSeconds = Math.floor(Date.now() / 1000)) {
let t = null;
const signatures = [];
for (const part of String(header ?? '').split(',')) {
const i = part.indexOf('=');
if (i <= 0) continue;
const key = part.slice(0, i).trim();
const value = part.slice(i + 1).trim();
if (key === 't' && /^[0-9]{1,12}$/.test(value)) t = Number(value);
else if (key === 'v1' && /^[0-9a-f]{64}$/.test(value)) signatures.push(value);
}
if (t === null || signatures.length === 0) return false;
if (Math.abs(nowSeconds - t) > TOLERANCE_SECONDS) return false; // replay window
const expected = crypto.createHmac('sha256', secret).update(`${t}.`).update(rawBody).digest();
// After a rotation the header carries two v1 values: accept either.
return signatures.some((sig) => crypto.timingSafeEqual(Buffer.from(sig, 'hex'), expected));
}
// Express: keep the body raw on this route.
const app = express();
app.post('/advanta', express.raw({ type: '*/*' }), (req, res) => {
if (!verifyAdvantaSignature(req.get('Advanta-Signature'), req.body, process.env.ADVANTA_WEBHOOK_SECRET)) {
return res.status(400).end();
}
const event = JSON.parse(req.body.toString('utf8'));
// Delivery is at least once: skip an event.id you already processed, then queue the work.
res.status(200).end();
});
Python
import hashlib
import hmac
import json
import os
import re
import time
from flask import Flask, request
TOLERANCE_SECONDS = 300
def verify_advanta_signature(header, raw_body, secret, now=None):
"""header: the Advanta-Signature value; raw_body: the request body as bytes, exactly
as received; secret: your endpoint secret, the whole "whsec_..." string."""
t = None
signatures = []
for part in (header or "").split(","):
key, sep, value = part.partition("=")
key, value = key.strip(), value.strip()
if not sep:
continue
if key == "t" and re.fullmatch(r"[0-9]{1,12}", value):
t = int(value)
elif key == "v1" and re.fullmatch(r"[0-9a-f]{64}", value):
signatures.append(value)
if t is None or not signatures:
return False
now = int(time.time()) if now is None else now
if abs(now - t) > TOLERANCE_SECONDS: # replay window
return False
expected = hmac.new(secret.encode("utf-8"), f"{t}.".encode("ascii") + raw_body, hashlib.sha256).hexdigest()
# After a rotation the header carries two v1 values: accept either.
return any(hmac.compare_digest(sig, expected) for sig in signatures)
# Flask
app = Flask(__name__)
@app.post("/advanta")
def advanta_webhook():
raw = request.get_data() # the raw bytes; do not read request.json before verifying
if not verify_advanta_signature(request.headers.get("Advanta-Signature"), raw, os.environ["ADVANTA_WEBHOOK_SECRET"]):
return "", 400
event = json.loads(raw)
# Delivery is at least once: skip an event["id"] you already processed, then queue the work.
return "", 200
Erreurs
Chaque erreur est du JSON, avec un code stable et un message destiné aux personnes. Décidez d’après le code, jamais d’après le message.
JSON
{
"error": {
"code": "not_routed_to_you",
"message": "This request is not assigned to your institution. Advanta operations routes requests."
}
}
Codes de statut
Statut
Codes
Signification
400
reason_required
Un refus sans reason ni notes.
401
unauthorized, key_expired
unauthorized : la clé est absente, mal formée, inconnue, révoquée ou inactive. key_expired : la clé a expiré.
forbidden : la clé n’a pas la portée, ou le financeur n’est pas actif. not_your_request : un règlement par un financeur qui n’est pas celui de la demande. export_live_key_required : une clé sandbox n’exporte pas. not_routed_to_you : annoncer une demande qui ne vous est pas adressée. not_your_claim : clore une réclamation de recours qui ne porte pas sur une de vos demandes.
404
not_found
Aucune ressource visible pour cette clé, ou une route inconnue.
405
method_not_allowed
La méthode n’est pas prise en charge sur ce chemin.
Une écriture que la demande ne permet pas : elle ne vous est pas adressée, le statut ne convient pas, elle dépasse une de vos limites, une notification d’affacturage pas encore confirmée, un débiteur hors de votre liste, un document exigé du cédant manquant ou périmé, ou un niveau de consentement qui baisserait, arrive après la réponse d’un débiteur, ou vise une demande qui n’est pas de l’affacturage ou n’est pas en cours. Aussi un relevé déjà importé, plus de 10 endpoints actifs, un nom de prescripteur que vous utilisez déjà, un lien qui fonctionne encore (envoyez replace: true), et un lien d’entrée en relation pour une entreprise ou un contact qui a déjà un compte ou une invitation en attente, ou dans un pays dont Advanta n’accepte pas encore de cédants. Un export est encore en cours de génération (export_in_progress, export_not_ready) ou a échoué (export_failed).
410
export_expired
export_expired : les fichiers de l’export pouvaient être téléchargés pendant 24 heures ; lancez un nouvel export.
413
file_too_large, too_many_lines, too_many_rows
Le relevé dépasse 4 Mio ou compte plus de 5 000 opérations, ou un import de limites compte plus de 2 000 lignes (too_many_rows).
Un champ ou un paramètre manque ou n’est pas valide ; le code dit lequel. (Un refus sans motif donne 400 reason_required ; un changement de paramètres ou de niveau sans motif donne 422 reason_required.) Aussi un changement de conditions pour une entreprise hors de votre programme (seller_not_in_programme), une demande déjà annoncée ou close (already_announced, request_closed), et une réclamation de recours qui n’est plus ouverte ou close de la mauvaise façon (claim_closed, close_invalid). Sont aussi refusés un import de limites sans lignes (rows_required), avec une source autre que import ou insurer (invalid_source) ou avec une source_ref qui n’est pas du texte ou dépasse 200 caractères (source_ref_invalid, source_ref_too_long), et une date des opportunités qui n’est pas un jour du calendrier (invalid_date).
429
rate_limited, export_rate_limited
rate_limited : plus d’appels que la limite de la clé (120 par minute et 3 000 par heure, sauf si Advanta en a fixé une autre pour la clé), ou des appels répétés avec une clé inconnue depuis une même adresse ; renvoyez-le après Retry-After secondes. export_rate_limited : au plus 10 exports en 24 heures.
Quand vous n’acceptez que les acheteurs de votre liste, une offre sur une demande avec un débiteur hors liste répond 409 avec les débiteurs qui la bloquent, chacun avec un reason :
Votre limite sur le débiteur est au statut refusé.
suspended
Votre limite sur le débiteur est suspendue.
no_tax_id
Une facture n’a pas le numéro fiscal de l’acheteur.
invoice_missing
Une ligne de la demande n’a pas de facture.
no_invoices
La demande n’a aucune facture.
documents_missing_for_funder
Quand un document que vous exigez du cédant manque, n’est pas vérifié ou n’est plus valide, une offre ou un financement répond 409 avec les documents qui le bloquent, chacun avec un reason :
Le code n’est pas dans le catalogue du pays du cédant.
Versions et limites
Le chemin porte la version majeure, /v1. Au sein de la v1, des champs et des types d’événements peuvent être ajoutés : ignorez ce que vous ne connaissez pas.
api_version, dans GET /v1/me et dans chaque événement de webhook, indique la révision que vous lisez : aujourd’hui, 2026-09-23.
Chaque clé peut faire 120 appels par minute et 3 000 par heure, comptés sur tous les serveurs d’Advanta (les opérations d’Advanta peuvent fixer une autre limite pour une clé). Un appel au-delà de la limite reçoit 429 rate_limited, avec un en-tête Retry-After en secondes et retry_after_seconds, limit et window_seconds dans l’erreur : rien de ce qu’il demandait n’a été fait, renvoyez-le donc après ce délai. Des appels répétés avec une clé inconnue ou mal formée depuis une même adresse reçoivent aussi 429. GET /v1/health n’est pas limité, et les exports gardent leur propre limite (export_rate_limited).
Tout ce qui figure sur cette page est décrit dans openapi.yaml (OpenAPI 3.1). Des questions, ou une clé : diogo@advanta.pt.