flowie-exchange
v0.1.1
Published
Official JavaScript/TypeScript SDK for the Flowie Exchange API — compliant e-invoicing across 47 countries (Peppol, France PA/PPF, Italy SDI, Saudi Fatoora, India GST IRP, Malaysia MyInvois).
Maintainers
Readme
flowie-exchange
Official JavaScript/TypeScript SDK for the Flowie Exchange API — one REST API for compliant electronic invoicing across 47 countries and every major network: Peppol, France PA/PPF, Italy SDI, Saudi Fatoora, Israel ITA, India GST IRP, Malaysia MyInvois.
- Documentation: https://docs.get-flowie.com
- Developer portal: https://docs.get-flowie.com/developers/
- OpenAPI 3.1 contract: https://docs.get-flowie.com/openapi.json
Install
npm install flowie-exchangeNode 18+ (uses the built-in fetch).
Get a key with no signup
One unauthenticated call mints a working sandbox key and a seeded company, so you can send a document within a minute — no sales call, no signup form. This is also why an autonomous agent can integrate unattended.
import { FlowieExchange } from "flowie-exchange";
const flowie = await FlowieExchange.bootstrapSandbox();
console.log(flowie.bootstrap.company.peppolId);Or use a key you already have:
const flowie = new FlowieExchange({
apiKey: process.env.FLOWIE_API_KEY, // flw_live_… / flw_test_… / JWT
environment: "production", // default: "sandbox"
});Send an invoice
Note the field is number, not invoiceNumber — the API validates on
document.number.
const doc = await flowie.sendDocument({
type: "invoice", // credit-note | debit-note | purchase-order | …
from: "0208:0000000001",
to: "0208:0000000002",
document: {
number: "INV-001",
issueDate: "2026-08-06",
currency: "EUR",
lines: [{ description: "Consulting", quantity: 1, unitPrice: 1000, vatRate: 20 }],
},
});
console.log(doc.id, doc.status); // doc_… "sent"Check reachability before you promise delivery
const reach = await flowie.verifyRecipient({ recipient: "0208:0000000002", documentType: "invoice" });Track and advance the lifecycle
In several countries the transition is the receiver's statutory reporting obligation, not bookkeeping — it is forwarded to the national platform where one requires it.
await flowie.setLifecycle(doc.id, "approved");
await flowie.setLifecycle(doc.id, "paid");
const history = await flowie.getLifecycle(doc.id);
console.log(history.currentStatus); // "paid"List documents
const { documents } = await flowie.listDocuments({ companyId: "…", limit: 25 });Register a company on Peppol
await flowie.registerCompany(companyId);Errors
Every failure throws a FlowieError carrying the API's own code and, crucially,
the requestId. Any 4xx/5xx is replayable by that id through the request
inspector, which is faster than reconstructing a failure from logs.
import { FlowieError } from "flowie-exchange";
try {
await flowie.getDocument("doc_missing");
} catch (err) {
if (err instanceof FlowieError) {
console.error(err.status, err.code, err.requestId);
}
}Anything else in the contract
The named methods cover the operations that carry real traffic. request()
reaches all 112:
await flowie.request("GET", "/v1/compliance/status", { query: { country: "FR" } });For AI agents
The API is callable natively over two agent protocols, and the documentation is published in machine-readable form:
| Surface | URL |
|---|---|
| MCP (product, 40 tools) | https://back.flowie.ink/exchange/mcp |
| MCP (documentation) | https://docs.get-flowie.com/mcp |
| A2A (JSON-RPC 2.0) | https://back.flowie.ink/exchange/a2a |
| Agent Card | https://docs.get-flowie.com/.well-known/agent-card.json |
| Auth walkthrough | https://docs.get-flowie.com/auth.md |
| Page index for LLMs | https://docs.get-flowie.com/llms.txt |
To let an agent act on your account without handing it your API key, mint a single-use, scoped, expiring link at https://docs.get-flowie.com/share-access.
License
MIT © Flowie
