Quickstart
From a fresh key to listing invoices and downloading a PDF.
This walks from a fresh API key to a working integration. Every example is copy-pasteable; replace the key and ids with your own.
1. Get a key
In the Fynex dashboard, open Integration in the left-hand menu and issue a secret key from the API keys card.
sk_test_…— authenticates while your account is in demo mode.sk_live_…— authenticates once your account is live.
An account is in exactly one of those modes, so exactly one of the two key environments works at any time.
Keys are stored only as hashes, so a key is shown once, at creation. If you lose it, regenerate — there is no recovery. Keep keys server-side: they carry full read and write access to your billing data.
2. Set your base URL
Every endpoint sits under the path /billing-api/v1. The host depends on the
environment you were onboarded to, so the examples below use a variable:
export FYNEX_API_BASE="https://api.fynex.ai/billing-api/v1"
export FYNEX_API_KEY="sk_test_4f6f..."
| Environment | Host |
|---|---|
| Production | https://api.fynex.ai — a sk_live_ key is accepted only by the environment that issued it. The OpenAPI document's servers block lists the origin of the deployment you are reading from first, so a generated client needs no manual host configuration. |
You are reading these docs on the same host the API runs on, so
/billing-api/v1/openapi.json and /billing-api/v1/docs are always
reachable relative to wherever this page is served.
3. Make your first call
GET /contracts is the safest first request — it needs no ids and tells you
whether your key, environment, and network path all work:
curl -s $FYNEX_API_BASE/contracts \
-H "Authorization: Bearer $FYNEX_API_KEY"
{
"contracts": [
{
"contractId": 42,
"contractNumber": "UK2607AA",
"version": 1,
"sellerCustomerId": 7,
"currency": "EUR",
"status": "active",
"startDate": "2026-01-01",
"customerName": "Ada Lovelace",
"customerCompanyName": "Harbour Group BV"
}
]
}
contractId is the key to every per-contract endpoint that follows.
If instead you get:
401— the header is missing or the key is wrong. The format isAuthorization: Bearer sk_live_…; a bare key withoutBearerfails.403— the key is valid but the seller account is not active. Check the account status in the dashboard.- an empty
contractsarray — the key works, but this account has no contracts yet.
4. List invoices
curl -s "$FYNEX_API_BASE/invoices?limit=5" \
-H "Authorization: Bearer $FYNEX_API_KEY"
{
"invoices": [
{
"id": 4180,
"contractId": 42,
"sellerCustomerId": 7,
"origin": "usage",
"invoiceNumber": "UK2607AA-2608AAB",
"jurisdiction": "UK",
"invoiceType": "standard",
"status": "sent",
"currency": "EUR",
"issueDate": "2026-08-01T00:00:00Z",
"dueDate": "2026-08-15T00:00:00Z",
"subtotalMinor": 10000,
"taxTotalMinor": 2000,
"grandTotalMinor": 12000,
"creditAppliedMinor": 0,
"collectibleMinor": 12000,
"creditSettledMinor": 0,
"reverseCharge": false,
"paymentLinkId": 991
}
],
"hasMore": true,
"nextCursor": 4180,
"nextBeforeId": 4180
}
Two things to internalize right now, because they cause most integration bugs:
- Amounts are integers in minor units.
12000in EUR is €120.00. Never parse them as floats. grandTotalMinoris the document total,collectibleMinoris what collection asks the customer for. They differ when stored credit funded part of the invoice. Neither drops to zero once the invoice is paid — to decide "does this customer still owe us money", readstatus.creditSettledMinoris not a payment total. It counts only stored credit drawn down, so a card-paid invoice reports0there.
5. Get one invoice with its lines
curl -s $FYNEX_API_BASE/invoices/4180 \
-H "Authorization: Bearer $FYNEX_API_KEY"
{
"invoice": { "id": 4180, "invoiceNumber": "UK2607AA-2608AAB", "...": "..." },
"lines": [
{
"position": 1,
"description": "API calls over allowance",
"quantity": "250",
"unitPriceMinor": 40,
"discountMinor": 0,
"netAmountMinor": 10000,
"taxCategory": "standard",
"taxRate": "20",
"taxAmountMinor": 2000,
"sourceRef": "usage:api_calls:2026-07"
}
]
}
quantity and taxRate are decimal strings — they carry fractional
precision that a JSON number would round. Feed them to a decimal type, not a
float.
6. Download the PDF
curl -s $FYNEX_API_BASE/invoices/4180/pdf \
-H "Authorization: Bearer $FYNEX_API_KEY" \
-o invoice-UK2607AA-2608AAB.pdf
The response is application/pdf bytes with a Content-Disposition
filename. It renders from the document's frozen payload, so a PDF fetched
today and one fetched next year are identical.
Next
- Workflows shows the end-to-end recipes: collecting on an invoice, reconciling a month, watching usage against limits.
- Pagination & Amounts covers the paging loop you will need past 20 rows.
- Errors covers the status contract, rate limits, and retry policy.