Flowie
Changelog

What's new

Every change to the Flowie Exchange API, newest first. Additive changes land continuously under /v1/; deprecations are announced six months in advance and flagged with a Sunset response header.

How to read this
New additive — always safe to adopt.
Changed behavior refined — read carefully.
Deprec sunset date announced.
Break only ever in a new major (/v2/…).
Fix bug fix.

v3.1.11 — Directory-line search returns real entries

2026-06-12
Fix
POST /afnor/directory-service/v1/directory-line/search was a stub that always returned totalNumberOfResults: 0. It now forwards the filter set to the PPF annuaire (ppf-annuaire's /api/search/ligne-annuaire) and maps each entry to an AFNOR directory line (addressingIdentifier, routingIdentifier, administrativeStatus, …), so a SIRET that has annuaire lines now returns them.

v3.1.10 — Original/Converted XML for JSON-created docs

2026-06-12
Fix
Retrieving a document's Original/Converted XML (AFNOR GET /afnor/flow-service/v1/flows/{id}?docType=Original and GET /v1/documents/{id}/xml) returned 404 "XML not available… created from JSON without a stored XML file" for documents created from structured JSON. When no XML is physically stored, the UBL 2.4 is now rendered on the fly from the document's JSON (via the same converter the "Convert to UBL" flow uses), so the original/converted content is returned. A genuinely empty document still 404s.

v3.1.9 — Flow search results match the query

2026-06-12
Fix
POST /afnor/flow-service/v1/flows/search could return flows whose flowType/flowDirection didn't match the request (e.g. a CustomerInvoice/Out query surfacing SupplierInvoice/In rows), and lifecycle (…LC) searches returned plain invoices. Results are now hard-filtered to the requested flowType/flowDirection sets, so the response always matches the query (lifecycle searches return an empty set when no lifecycle flows exist rather than mislabeled invoices).

v3.1.8 — API-key creation hardening

2026-06-12

Closes privilege-escalation gaps in POST /v1/api-keys. Keys remain bound to the caller's organization and tier (no organizationId in the request).

Changed
Scopes are clamped to the caller. A new key can no longer be granted scopes the caller doesn't hold — requesting an unheld scope (or *) now returns 403. Omitting scopes inherits the caller's scopes instead of silently defaulting to *.
Changed
rateLimit.requestsPerMinute is clamped to the tier ceiling, so a key can't grant itself a higher request rate than its tier allows.
Fix
name must be non-empty and expiresAt, if given, must be in the future (a past value now returns 400 instead of minting a dead key). Keys with no expiresAt remain permanent.

v3.1.7 — Company PATCH fix

2026-06-12
Fix
PATCH /v1/companies/{id} returned 500 when only capabilities or compliance were patched — the response was built from a detached DB row after the session closed. It is now built inside the session.

v3.1.6 — AFNOR SIREN search pagination

2026-06-11
Fix
SIREN search pagination. POST /afnor/directory-service/v1/siren/search only fetched limit rows then sliced, so pages past the first (ignore > 0) came back empty and totalNumberOfResults reflected only the fetched window. Pages now resolve correctly with an accurate total.
Fix
Bounded ignore. ignore was unbounded; a very large value forced an oversized upstream fetch. It is now capped (max 10000) and the upstream fetch is bounded regardless.

v3.1.5 — Deterministic directory ordering

2026-06-11
Fix
Directory search results are now ordered deterministically. The local-registration fallback used a bare LIMIT with no ORDER BY, so identical GET /v1/directory/search calls could return rows in a different order. All AFNOR directory-service lookups are read-only and idempotent.

v3.1.4 — Directory by SIREN, list direction, recoverable number lookup

2026-06-10
Fix
Directory search by SIREN/SIRET in q. A bare 9-digit SIREN (or 14-digit SIRET) typed into GET /v1/directory/search?q=… now routes to the SIREN/SIRET lookup instead of the name search, which never matched a number. The AFNOR endpoints also stop deriving the wrong SIREN from the VAT number.
Fix
Per-row direction in document listings. GET /v1/documents now stamps each row incoming/outgoing (previously always null). An invalid direction now returns 400 instead of silently returning both.
Fix
Recoverable lookup by invoice number. When a number matches more than one document, GET /v1/documents/{number} now returns the candidate ids in the 409 body instead of a dead-end error.

v3.1.3 — Lifecycle history shows real statuses

2026-06-10
Fix
GET /v1/documents/{id}/lifecycle returned currentStatus and every history[].status as "unknown" (and setBy null) for all real documents. The history now reads the upstream audit-log's real fields (action, actionBy), and currentStatus/allowedTransitions resolve from the document's authoritative per-party lifecycle status rather than the most recent audit action.

Docs — Unified navigation

2026-06-04

Documentation-site improvements only — no API surface change. The top navigation is now generated from a single source of truth, so every page (including the per-country compliance pages) carries the same complete, consistent set of links.

Docs
Top navigation is now consistent across every page. Pages that were missing the API Keys or Playground links (e.g. MCP, agent onboarding) now carry the full set, and the per-country compliance pages use the same generated nav.
Docs
Active-link highlighting now works on the French and Italian pages even with JavaScript disabled (their nav hrefs point at the English asset, so the old runtime filename match never fired).
Docs
Browser-storage keys used by the docs site (theme, cached tokens, saved playground vars) are now sourced from a single window.FLW registry loaded on every page, removing drift between the individual scripts.

v3.1.2 — Agent handoff link

2026-05-08

Hand a single URL to your LLM and it does the integration. The user pre-approves a scope set bound to their org; the agent redeems the embedded token for an API key in one POST. No PKCE round-trip, no consent UI — the issued key acts on the user's real organization, not a fresh sandbox.

New
POST /v1/oauth/handoff (authenticated) — mints a single-use, scope-and-org-bound handoff token and returns a ready-to-paste URL. Default 10-min TTL (60s–60min configurable). Default scopes: send, receive, documents.read, companies.read, stats. Caller cannot pre-approve scopes their own token doesn't hold.
New
POST /v1/oauth/handoff/exchange (no auth) — single-use redemption. Returns an flw_test_… (or flw_live_… for paid tiers) key bound to the original user's organization, company, and tier.
New
Home-page widget under "Building with an AI agent?" — copy the anonymous link, or paste an existing API key to generate a personalized handoff URL in-browser. The pasted key never leaves the page.
Docs
Agent onboarding documents three paths now: handoff (fastest), sandbox bootstrap (no auth), OAuth consent (PKCE). LLM discovery surface (llms.txt) updated.

v3.1.1 — Belgium HERMES retired

2026-05-04

Belgium's regulator-side reporting hub HERMES was decommissioned by FPS Finance on 2025-12-31 (consultation-only access expired 2026-03-31). Flowie's HermesAdapter and the BE branch of the compliance dispatcher have been removed. Belgian invoices are now pure Peppol — the delivery itself is the compliance event.

Changed
No compliance.reported events fire for Belgian invoices. If your webhook router branches on data.platform == "HERMES", drop the branch — see migration guide for the full diff.
Changed
BE-CIUS validation now surfaces synchronously: POST /v1/documents/send returns 422 with the BE-CIUS schematron rule code in error.details[].code + the failing XPath. Replaces the old deferred compliance.reported.failed + HER-* path. Same checks, faster feedback.
Deprec
HERMES_REPORT_URL / HERMES_REPORT_TOKEN environment variables are no longer read. simulateCompliance: "reject_HER_001" sandbox value is also retired. Historical compliance_reports rows with platform=HERMES are retained for audit; new ones won't be created.
Docs
Belgium compliance page (compliance/be.html) rewritten with sourced timeline (2024-02-06 → 2028-01-01), 4-corner Peppol diagram, end-to-end send example, lifecycle table comparing FR/IT/BE, BR-BE-* error catalog, sandbox tests, and HERMES → Peppol migration table.

v3.1.0 — AI agents & multi-org

2026-05-03

First-class Model Context Protocol surface for AI agents, plus organization switching for JWT users in multiple orgs.

New
MCP servers. /exchange/mcp (curated, 34 tools across Documents / Directory / Companies / Lifecycle / Compliance / Partners) and /exchange/mcp/full (every documented operation, 94 tools). Same Bearer token as REST, same quotas, same sandbox. Full guide →
New
POST /v1/documents/send accepts type: "event" — pure audit-trail records, persisted as documents but never routed over Peppol. Useful for ERP-side notifications you want to keep alongside real invoices.
New
Organization switching for multi-org JWT users: switch the active organization without re-login. Existing flw_* API keys are unaffected (single-tenant by design).
Changed
MCP transport upgraded from legacy SSE to streamable-HTTP (MCP spec 2025-06-18). Reconfigure existing clients as "transport": "streamable-http".

v3.0.0 — Unified surface

2026-04-13

First stable cut of the Exchange API. The legacy /api/… endpoints continue to work but are deprecated.

New
Resource-oriented surface under /v1/: companies, documents, partners, webhooks, events, compliance, platform, api-keys, stats.
New
Lifecycle state machine with auto-reporting to PPF (FR), SDI (IT), HERMES (BE).
New
Idempotency-Key is accepted on every POST with a 24h TTL.
New
Cursor-based pagination everywhere (limit, cursor, hasMore).
New
Platform keys with X-Flowie-Company for tenant-scoped calls.
New
AFNOR XP Z12-013 adapter under /afnor/flow-service and /afnor/directory-service.
New
cXML PunchOut callback at /document/callback.
Deprec
All /api/… endpoints. Sunset date: 2027-04-01. Mapping table in the migration guide.

v2.9.0

2026-03-28
New
POST /v1/documents/search accepts compound AND/OR/NOT filter trees.
New
Webhook deliveries now include X-Flowie-Attempt header.
Changed
Directory verify latency dropped from p95 420ms → 90ms via SMP cache.

v2.8.0

2026-03-10
New
AI tag recommendation: POST /v1/categorization/objects/tags/auto.
New
Structured document view at GET /v1/documents/{id}/structured — all scalars flattened, ready for warehouses.
Fix
VAT normalization now strips all whitespace (was only stripping leading/trailing).

v2.7.0

2026-02-14
New
Company identifier resolution: vat: and peppol: prefixes accepted in any {company_id} / {partner_id} path param.
New
Batch lifecycle update: POST /v1/documents/lifecycle/batch, up to 500 per call.
Changed
HERMES (BE) reporting enabled by default for newly created BE companies. Existing companies untouched.

v2.6.0

2026-01-22
New
Circuit-breaker visibility at GET /health/readiness. Per-upstream state.
New
Webhook secret rotation: PATCH /v1/webhooks/{id} with {"rotateSecret": true}. Old secret stays valid for 60 minutes.
Fix
Idempotency cache correctly distinguishes requests differing only in a query param.

v2.5.0

2025-12-05
New
PPF (FR) adapter graduated from beta. Registered PDP status confirmed by DGFiP.
New
ISO 20022 / SEPA export at POST /v1/payments/export/iso20022.

v2.4.0

2025-10-18
New
Events API (/v1/events) — durable twin of every webhook, replayable.
New
Rate-limit headers (X-RateLimit-*) added to every response.
Changed
Free tier rate limit raised from 30 to 60 req/min.