Skip to content

Full cash flow report for a date range

GET
/provider/{provider_id}/business_entity/{business_entity_id}/financial_reports/cash_flow_report
curl --request GET \
--url 'https://api.flychain.us/external/v1/provider/9c1e7a42-0b3d-4e58-9f21-6a8b5c4d3e2f/business_entity/3f5d8b16-7c94-42a1-b0e6-58d9c2a71b43/financial_reports/cash_flow_report?start_date=2026-07-01&end_date=2026-07-31' \
--header 'Authorization: Bearer <token>'

Provider keys only. A partner key is refused with 403 ENDPOINT_NOT_AVAILABLE.

The whole report for one range — every cash ledger, and beneath each one the individual transactions that moved it. The identical structure our own application consumes, so nothing is held back.

This is the largest payload on this API, and the only one that grows with an entity’s transaction volume rather than with its chart of accounts. One entry per transaction in the range. If you only store the report totals, use the summary variant: it costs the same on our side and returns orders of magnitude less JSON.

Reading a total: on a ledger, total_net_cash_flow_cents. amount_cents and total_amount_cents are both 0 there — they carry the amount on a transaction only. See guides/data-semantics §7.

The start_date / end_date in the response are the effective range we reported on after clamping, not necessarily the range you asked for.

provider_id
required
string format: uuid

The provider, from GET /providers or the provider_id on a business-entity record. With a partner key it must be a provider in your partner relationship; with a provider key it is always your own provider_id, which GET /providers returns.

Example
9c1e7a42-0b3d-4e58-9f21-6a8b5c4d3e2f
business_entity_id
required
string format: uuid

The business entity, from GET /business_entities. Must belong to the provider_id in the same path.

Example
3f5d8b16-7c94-42a1-b0e6-58d9c2a71b43
start_date
required
string format: date
/^\d{4}-\d{2}-\d{2}$/

First day of the requested range, inclusive.

Must be a real calendar date, zero-padded, in YYYY-MM-DD form — 2026-7-1 and 2026-02-31 are both 400 INVALID_REQUEST. Ranges are evaluated in UTC.

Raised to the entity’s books_start_date when it falls earlier. If the whole requested range sits before the books begin, the result is 400 INVALID_REQUEST rather than a zero statement, so a range with no books behind it can never read as a period with no revenue.

Example
2026-07-01
end_date
required
string format: date
/^\d{4}-\d{2}-\d{2}$/

Last day of the requested range, inclusive. Same format rules as start_date, and must not be earlier than it.

Capped at today when it falls in the future, which is the ordinary case for a job that asks for the current month every day. The response echoes the effective range it used.

Example
2026-07-31

The full report for the effective range.

Media typeapplication/json

The range envelope carrying the full report.

object
provider_id
required
string format: uuid
business_entity_id
required
string format: uuid
start_date
required

First day of the effective range, inclusive — what we reported on after clamping, not necessarily what was requested.

string format: date
end_date
required

Last day of the effective range, inclusive. Compare both dates against what you asked for: a difference means the range was clamped to the entity’s books or to today.

string format: date
accounting_basis
required

The basis an entity’s financials are prepared on.

A property of the entity, not a request parameter. A report is produced on the basis the underlying books are kept on; there is no per-request switch. It is returned on every entity record and every report so a figure is never ambiguous, and it will not change without notice. See guides/data-semantics.

null only where the entity has no books yet — every entity with reporting_available: true carries a basis.

string | null
Allowed values: CASH ACCRUAL
currency
required

Currency of every amount in the payload. Always USD — the key exists so it never has to be assumed.

string
Allowed values: USD
is_closed
required

Whether the books are finalized through end_date (that is, end_date is on or before the entity’s books_closed_through).

false means the figures are provisional and may still be revised as transactions are reconciled. This is the flag to trust, rather than inferring from the calendar — see guides/data-semantics.

boolean
generated_at
required

When this payload was produced, ISO 8601 UTC. Reports are computed on request, so this is also the as-of time of the figures.

string format: date-time
cash_flow_report
required

The full report: every cash ledger with its transactions, plus the same five figures the summary variant returns on their own.

This is the identical structure our own application consumes. Nothing is held back and nothing is added for external callers — a pared-down copy would be a second definition of the report, and a second definition drifts.

object
ledgers
required

One entry per cash account, ordered by total_net_cash_flow_cents descending. Each carries its transactions in children.

A flat list, not a tree. Where one account rolls up into another, both appear here as their own entries — which is why total_net_cash_flow_cents must not be summed across it. The report totals below are built from each account’s total_inflow_cents / total_outflow_cents, so those are what reconcile.

Array<object>

A node in the full cash flow report: either a ledger (a cash account) or a transaction beneath one. Recursive through children, though in practice the report is two levels deep.

Written out separately from Record rather than extending it, because the two answer “where is the total” differently and conflating them is the single easiest way to read a zero here:

Ledger Transaction
Read one node total_net_cash_flow_cents amount_cents
Sum across nodes total_inflow_cents / total_outflow_cents amount_cents
total_amount_cents 0, always the same amount
ledger_id present absent
line_id / datetime absent present

The two ledger rows differ because ledgers is a flat list: where one account rolls up into another, both are entries in it, so the rolled-up figure double-counts under a sum. See the two fields below.

Null fields are omitted rather than sent as null, exactly as on Record, so treat an absent key as “not applicable to this node”.

object
ledger_id

Stable identifier for a cash account, so the same account can be tracked across periods. Present on ledger nodes, absent on transactions.

Opaque — not a UUID, unlike the provider and business-entity ids. Treat it as a string and do not parse it.

string
line_id

Identifier for a single journal-entry line as we hold it. Present on transaction nodes only, and opaque — treat it as a string and do not parse it.

Not promised to be stable across pulls. If you need to reconcile two pulls of the same period, match on amount, date and description rather than on this; that is what we do internally.

string
name
required

Display name of the account, or the transaction’s description as it reaches us from the bank or the journal entry. No Description Available where neither carries one.

string
datetime

When the transaction posted. Present on transaction nodes only. A timestamp rather than a date, and passed through from the ledger as we hold it — use the period’s start_date / end_date to know which period a transaction belongs to, not this.

string
amount_cents
required

On a transaction, the signed amount that moved: positive in, negative out. On a ledger, always 0 — read total_net_cash_flow_cents instead.

integer
total_amount_cents
required

On a transaction, the same value as amount_cents. On a ledger, always 0. This is the field to read on an income statement or balance sheet and the wrong one here; it is published because the report carries it, not because it is useful.

integer
net_cash_flow_cents

Net movement through this account alone over the range, excluding anything that rolls up into it. Present on ledger nodes, and the counterpart to total_net_cash_flow_cents below.

To reconcile against the report totals, add up total_inflow_cents and total_outflow_cents rather than this — those are the per-account figures the report totals are summed from, so they agree exactly.

integer
total_net_cash_flow_cents

Net movement through this account and every account that rolls up into it. Present on ledger nodes, and equal to net_cash_flow_cents for any account with nothing beneath it.

This is the figure to read for one account, and the one this list is ordered by. Do not sum it across ledgers — the accounts beneath a parent are entries in that same list, so a sum counts them twice. Aggregate total_inflow_cents / total_outflow_cents instead.

integer
total_inflow_cents

Cash in through this account’s own transactions over the range. Positive. Present on ledger nodes.

This and total_outflow_cents are the fields to aggregate. The report’s own total_inflow_cents / total_outflow_cents are these values added up, and its net_cash_flow_cents is their sum, so the reconciliation is exact rather than merely expected.

integer
total_outflow_cents

Cash out through this account’s own transactions over the range. Negative, or 0 where nothing left it. Present on ledger nodes, and the other half of the pair to aggregate.

integer
children
required
Array<object> recursive
key
additional properties
any
total_inflow_cents
required

Cash in over the range. Positive.

integer
total_outflow_cents
required

Cash out over the range, as a negative number (0 if none).

integer
starting_cash_balance_cents
required

Cash on hand at the start of the effective range.

integer
ending_cash_balance_cents
required

Cash on hand at the end of the effective range.

integer
net_cash_flow_cents
required

total_inflow_cents + total_outflow_cents.

integer
key
additional properties
any
Examples
ExamplejulyCashFlow

July 2026 full report, with per-transaction detail

GET .../financial_reports/cash_flow_report?start_date=2026-07-01&end_date=2026-07-31

Two cash accounts, each with the transactions that moved it. Ledgers are ordered by total_net_cash_flow_cents descending.

Read the ledger totals from total_net_cash_flow_cents. Note that amount_cents and total_amount_cents are 0 on both ledgers below and carry the real amount on every transaction — that is the shape, not an artefact of this example.

A real entity has hundreds of transactions a month rather than five. This is the variant whose size grows with transaction volume.

{
"provider_id": "9c1e7a42-0b3d-4e58-9f21-6a8b5c4d3e2f",
"business_entity_id": "3f5d8b16-7c94-42a1-b0e6-58d9c2a71b43",
"start_date": "2026-07-01",
"end_date": "2026-07-31",
"accounting_basis": "CASH",
"currency": "USD",
"is_closed": false,
"generated_at": "2026-08-20T14:02:11Z",
"cash_flow_report": {
"ledgers": [
{
"ledger_id": "rhvm6QyfxbygB5warCZv8X",
"name": "Operating Checking",
"amount_cents": 0,
"total_amount_cents": 0,
"children": [
{
"line_id": "ln_9Kd2pQ7mXr",
"name": "Patient revenue deposit",
"amount_cents": 3642500,
"total_amount_cents": 3642500,
"children": [],
"datetime": "2026-07-06T00:00:00Z"
},
{
"line_id": "ln_4Tb8nH1wLc",
"name": "Insurance remittance",
"amount_cents": 512000,
"total_amount_cents": 512000,
"children": [],
"datetime": "2026-07-21T00:00:00Z"
},
{
"line_id": "ln_7Zc3vJ5qNs",
"name": "Payroll",
"amount_cents": -1820000,
"total_amount_cents": -1820000,
"children": [],
"datetime": "2026-07-15T00:00:00Z"
},
{
"line_id": "ln_2Ry6dM0kPf",
"name": "Rent and software",
"amount_cents": -910000,
"total_amount_cents": -910000,
"children": [],
"datetime": "2026-07-01T00:00:00Z"
}
],
"net_cash_flow_cents": 1424500,
"total_net_cash_flow_cents": 1424500,
"total_inflow_cents": 4154500,
"total_outflow_cents": -2730000
},
{
"ledger_id": "qBn4LxKe7ZaW2mtRcH9dY",
"name": "Savings",
"amount_cents": 0,
"total_amount_cents": 0,
"children": [
{
"line_id": "ln_6Wq1sB4xTg",
"name": "Interest earned",
"amount_cents": 12500,
"total_amount_cents": 12500,
"children": [],
"datetime": "2026-07-31T00:00:00Z"
}
],
"net_cash_flow_cents": 12500,
"total_net_cash_flow_cents": 12500,
"total_inflow_cents": 12500,
"total_outflow_cents": 0
}
],
"total_inflow_cents": 4167000,
"total_outflow_cents": -2730000,
"starting_cash_balance_cents": 8450000,
"ending_cash_balance_cents": 9887000,
"net_cash_flow_cents": 1437000
}
}

Malformed request — a missing or unparseable date, a path id that is not a UUID, start_date after end_date, or a range that does not overlap the period this entity has books for. Also returned when the request reached us over plaintext HTTP; see INSECURE_TRANSPORT below and guides/authentication.

Media typeapplication/json

The failure shape for every error — validation, authorization, ours — so a client needs a single error path.

Match on code, not on message: the code set below is the contract and is stable, while wording may be clarified. New codes may be added within v1 (see guides/versioning), so treat an unrecognised code as “the HTTP status is authoritative”.

This includes a request that never reaches a documented operation at all — an unrouted path or a method we do not serve on that path, which is the failure you are most likely to meet while integrating. Those are answered before any operation runs, so no operation below lists them, but they arrive in this same shape, as ENDPOINT_NOT_FOUND (404) and METHOD_NOT_ALLOWED (405). Either one means check the URL rather than your credentials: the operations below are the whole surface.

object
error
required
object
code
required

Machine-readable cause.

  • INVALID_REQUEST (400) — malformed dates, a non-UUID path id, an inverted range, or a range with no reportable books behind it.
  • INSECURE_TRANSPORT (400) — the request was sent over plaintext http, so the key crossed the network in the clear. Rotate the key, then fix the URL; we refuse rather than redirect so this cannot pass unnoticed.
  • INVALID_API_KEY (401) — missing, invalid, expired or revoked key.
  • PARTNER_API_NOT_ENABLED (403) — your key is valid, but your organization is not enrolled in the API programme. Contact us; do not rotate the key.
  • PROVIDER_NOT_ACTIVE (403) — a provider key whose Flychain account is not active. Contact us; do not rotate the key.
  • PROVIDER_API_NOT_ENABLED (403) — a provider key on an account that is not enrolled in the API programme. Contact us; do not rotate the key.
  • ENDPOINT_NOT_AVAILABLE (403) — the path exists and your key is valid, but that operation is not served for your kind of key. The balance sheet and cash flow families are provider-only. Your URL is not wrong; do not rotate the key.
  • PROVIDER_NOT_IN_PARTNER_SCOPE (403) — the provider exists but is not in your relationship, including one that has left it.
  • BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE (403) — the entity exists but does not belong to the provider_id in the path.
  • PROVIDER_NOT_FOUND (404) — no provider with that id.
  • BUSINESS_ENTITY_NOT_FOUND (404) — no business entity with that id.
  • ENDPOINT_NOT_FOUND (404) — the URL itself is not one we serve, as opposed to a record we do not have. Check the path against the operations below.
  • METHOD_NOT_ALLOWED (405) — the path exists but not with that method; the Allow response header lists the ones it takes. Every operation here is a GET.
  • BOOKS_NOT_AVAILABLE (409) — the entity has no reportable books.
  • INTERNAL_ERROR (500) — ours; retry with backoff.
  • AUTH_SERVICE_UNAVAILABLE (503) — we could not verify your key; retry with backoff, and do not treat it as an authentication failure.
string
Allowed values: INVALID_REQUEST INSECURE_TRANSPORT INVALID_API_KEY PARTNER_API_NOT_ENABLED PROVIDER_NOT_ACTIVE PROVIDER_API_NOT_ENABLED ENDPOINT_NOT_AVAILABLE PROVIDER_NOT_IN_PARTNER_SCOPE BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE PROVIDER_NOT_FOUND BUSINESS_ENTITY_NOT_FOUND ENDPOINT_NOT_FOUND METHOD_NOT_ALLOWED BOOKS_NOT_AVAILABLE INTERNAL_ERROR AUTH_SERVICE_UNAVAILABLE
message
required

Human-readable detail. Do not match on it.

string
key
additional properties
any
key
additional properties
any
Examples

Unparseable date

{
"error": {
"code": "INVALID_REQUEST",
"message": "start_date must be a valid date in YYYY-MM-DD format."
}
}

Missing, invalid, expired or revoked API key. One message covers every case on purpose — a caller cannot tell a revoked key from an unknown one.

Media typeapplication/json

The failure shape for every error — validation, authorization, ours — so a client needs a single error path.

Match on code, not on message: the code set below is the contract and is stable, while wording may be clarified. New codes may be added within v1 (see guides/versioning), so treat an unrecognised code as “the HTTP status is authoritative”.

This includes a request that never reaches a documented operation at all — an unrouted path or a method we do not serve on that path, which is the failure you are most likely to meet while integrating. Those are answered before any operation runs, so no operation below lists them, but they arrive in this same shape, as ENDPOINT_NOT_FOUND (404) and METHOD_NOT_ALLOWED (405). Either one means check the URL rather than your credentials: the operations below are the whole surface.

object
error
required
object
code
required

Machine-readable cause.

  • INVALID_REQUEST (400) — malformed dates, a non-UUID path id, an inverted range, or a range with no reportable books behind it.
  • INSECURE_TRANSPORT (400) — the request was sent over plaintext http, so the key crossed the network in the clear. Rotate the key, then fix the URL; we refuse rather than redirect so this cannot pass unnoticed.
  • INVALID_API_KEY (401) — missing, invalid, expired or revoked key.
  • PARTNER_API_NOT_ENABLED (403) — your key is valid, but your organization is not enrolled in the API programme. Contact us; do not rotate the key.
  • PROVIDER_NOT_ACTIVE (403) — a provider key whose Flychain account is not active. Contact us; do not rotate the key.
  • PROVIDER_API_NOT_ENABLED (403) — a provider key on an account that is not enrolled in the API programme. Contact us; do not rotate the key.
  • ENDPOINT_NOT_AVAILABLE (403) — the path exists and your key is valid, but that operation is not served for your kind of key. The balance sheet and cash flow families are provider-only. Your URL is not wrong; do not rotate the key.
  • PROVIDER_NOT_IN_PARTNER_SCOPE (403) — the provider exists but is not in your relationship, including one that has left it.
  • BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE (403) — the entity exists but does not belong to the provider_id in the path.
  • PROVIDER_NOT_FOUND (404) — no provider with that id.
  • BUSINESS_ENTITY_NOT_FOUND (404) — no business entity with that id.
  • ENDPOINT_NOT_FOUND (404) — the URL itself is not one we serve, as opposed to a record we do not have. Check the path against the operations below.
  • METHOD_NOT_ALLOWED (405) — the path exists but not with that method; the Allow response header lists the ones it takes. Every operation here is a GET.
  • BOOKS_NOT_AVAILABLE (409) — the entity has no reportable books.
  • INTERNAL_ERROR (500) — ours; retry with backoff.
  • AUTH_SERVICE_UNAVAILABLE (503) — we could not verify your key; retry with backoff, and do not treat it as an authentication failure.
string
Allowed values: INVALID_REQUEST INSECURE_TRANSPORT INVALID_API_KEY PARTNER_API_NOT_ENABLED PROVIDER_NOT_ACTIVE PROVIDER_API_NOT_ENABLED ENDPOINT_NOT_AVAILABLE PROVIDER_NOT_IN_PARTNER_SCOPE BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE PROVIDER_NOT_FOUND BUSINESS_ENTITY_NOT_FOUND ENDPOINT_NOT_FOUND METHOD_NOT_ALLOWED BOOKS_NOT_AVAILABLE INTERNAL_ERROR AUTH_SERVICE_UNAVAILABLE
message
required

Human-readable detail. Do not match on it.

string
key
additional properties
any
key
additional properties
any
Examples
ExampleinvalidKey
{
"error": {
"code": "INVALID_API_KEY",
"message": "Missing, invalid, expired or revoked API key."
}
}

Your key is valid, but this call is not allowed. Either the operation is not served for your kind of key — the balance sheet and cash flow families are provider-only, eight operations in all — or your provider’s Flychain account is not active or not enrolled in the API programme. None of these is a credential problem; rotating the key will not help.

The partner scope refusals do not appear here: a partner key cannot reach these operations at all.

Media typeapplication/json

The failure shape for every error — validation, authorization, ours — so a client needs a single error path.

Match on code, not on message: the code set below is the contract and is stable, while wording may be clarified. New codes may be added within v1 (see guides/versioning), so treat an unrecognised code as “the HTTP status is authoritative”.

This includes a request that never reaches a documented operation at all — an unrouted path or a method we do not serve on that path, which is the failure you are most likely to meet while integrating. Those are answered before any operation runs, so no operation below lists them, but they arrive in this same shape, as ENDPOINT_NOT_FOUND (404) and METHOD_NOT_ALLOWED (405). Either one means check the URL rather than your credentials: the operations below are the whole surface.

object
error
required
object
code
required

Machine-readable cause.

  • INVALID_REQUEST (400) — malformed dates, a non-UUID path id, an inverted range, or a range with no reportable books behind it.
  • INSECURE_TRANSPORT (400) — the request was sent over plaintext http, so the key crossed the network in the clear. Rotate the key, then fix the URL; we refuse rather than redirect so this cannot pass unnoticed.
  • INVALID_API_KEY (401) — missing, invalid, expired or revoked key.
  • PARTNER_API_NOT_ENABLED (403) — your key is valid, but your organization is not enrolled in the API programme. Contact us; do not rotate the key.
  • PROVIDER_NOT_ACTIVE (403) — a provider key whose Flychain account is not active. Contact us; do not rotate the key.
  • PROVIDER_API_NOT_ENABLED (403) — a provider key on an account that is not enrolled in the API programme. Contact us; do not rotate the key.
  • ENDPOINT_NOT_AVAILABLE (403) — the path exists and your key is valid, but that operation is not served for your kind of key. The balance sheet and cash flow families are provider-only. Your URL is not wrong; do not rotate the key.
  • PROVIDER_NOT_IN_PARTNER_SCOPE (403) — the provider exists but is not in your relationship, including one that has left it.
  • BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE (403) — the entity exists but does not belong to the provider_id in the path.
  • PROVIDER_NOT_FOUND (404) — no provider with that id.
  • BUSINESS_ENTITY_NOT_FOUND (404) — no business entity with that id.
  • ENDPOINT_NOT_FOUND (404) — the URL itself is not one we serve, as opposed to a record we do not have. Check the path against the operations below.
  • METHOD_NOT_ALLOWED (405) — the path exists but not with that method; the Allow response header lists the ones it takes. Every operation here is a GET.
  • BOOKS_NOT_AVAILABLE (409) — the entity has no reportable books.
  • INTERNAL_ERROR (500) — ours; retry with backoff.
  • AUTH_SERVICE_UNAVAILABLE (503) — we could not verify your key; retry with backoff, and do not treat it as an authentication failure.
string
Allowed values: INVALID_REQUEST INSECURE_TRANSPORT INVALID_API_KEY PARTNER_API_NOT_ENABLED PROVIDER_NOT_ACTIVE PROVIDER_API_NOT_ENABLED ENDPOINT_NOT_AVAILABLE PROVIDER_NOT_IN_PARTNER_SCOPE BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE PROVIDER_NOT_FOUND BUSINESS_ENTITY_NOT_FOUND ENDPOINT_NOT_FOUND METHOD_NOT_ALLOWED BOOKS_NOT_AVAILABLE INTERNAL_ERROR AUTH_SERVICE_UNAVAILABLE
message
required

Human-readable detail. Do not match on it.

string
key
additional properties
any
key
additional properties
any
Examples

A partner key on a provider-only operation

{
"error": {
"code": "ENDPOINT_NOT_AVAILABLE",
"message": "This endpoint is available to provider API keys only. See the reference at https://docs.flychain.us for the endpoints a partner key can read."
}
}

No provider or business entity exists with that id.

Media typeapplication/json

The failure shape for every error — validation, authorization, ours — so a client needs a single error path.

Match on code, not on message: the code set below is the contract and is stable, while wording may be clarified. New codes may be added within v1 (see guides/versioning), so treat an unrecognised code as “the HTTP status is authoritative”.

This includes a request that never reaches a documented operation at all — an unrouted path or a method we do not serve on that path, which is the failure you are most likely to meet while integrating. Those are answered before any operation runs, so no operation below lists them, but they arrive in this same shape, as ENDPOINT_NOT_FOUND (404) and METHOD_NOT_ALLOWED (405). Either one means check the URL rather than your credentials: the operations below are the whole surface.

object
error
required
object
code
required

Machine-readable cause.

  • INVALID_REQUEST (400) — malformed dates, a non-UUID path id, an inverted range, or a range with no reportable books behind it.
  • INSECURE_TRANSPORT (400) — the request was sent over plaintext http, so the key crossed the network in the clear. Rotate the key, then fix the URL; we refuse rather than redirect so this cannot pass unnoticed.
  • INVALID_API_KEY (401) — missing, invalid, expired or revoked key.
  • PARTNER_API_NOT_ENABLED (403) — your key is valid, but your organization is not enrolled in the API programme. Contact us; do not rotate the key.
  • PROVIDER_NOT_ACTIVE (403) — a provider key whose Flychain account is not active. Contact us; do not rotate the key.
  • PROVIDER_API_NOT_ENABLED (403) — a provider key on an account that is not enrolled in the API programme. Contact us; do not rotate the key.
  • ENDPOINT_NOT_AVAILABLE (403) — the path exists and your key is valid, but that operation is not served for your kind of key. The balance sheet and cash flow families are provider-only. Your URL is not wrong; do not rotate the key.
  • PROVIDER_NOT_IN_PARTNER_SCOPE (403) — the provider exists but is not in your relationship, including one that has left it.
  • BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE (403) — the entity exists but does not belong to the provider_id in the path.
  • PROVIDER_NOT_FOUND (404) — no provider with that id.
  • BUSINESS_ENTITY_NOT_FOUND (404) — no business entity with that id.
  • ENDPOINT_NOT_FOUND (404) — the URL itself is not one we serve, as opposed to a record we do not have. Check the path against the operations below.
  • METHOD_NOT_ALLOWED (405) — the path exists but not with that method; the Allow response header lists the ones it takes. Every operation here is a GET.
  • BOOKS_NOT_AVAILABLE (409) — the entity has no reportable books.
  • INTERNAL_ERROR (500) — ours; retry with backoff.
  • AUTH_SERVICE_UNAVAILABLE (503) — we could not verify your key; retry with backoff, and do not treat it as an authentication failure.
string
Allowed values: INVALID_REQUEST INSECURE_TRANSPORT INVALID_API_KEY PARTNER_API_NOT_ENABLED PROVIDER_NOT_ACTIVE PROVIDER_API_NOT_ENABLED ENDPOINT_NOT_AVAILABLE PROVIDER_NOT_IN_PARTNER_SCOPE BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE PROVIDER_NOT_FOUND BUSINESS_ENTITY_NOT_FOUND ENDPOINT_NOT_FOUND METHOD_NOT_ALLOWED BOOKS_NOT_AVAILABLE INTERNAL_ERROR AUTH_SERVICE_UNAVAILABLE
message
required

Human-readable detail. Do not match on it.

string
key
additional properties
any
key
additional properties
any
Examples
{
"error": {
"code": "PROVIDER_NOT_FOUND",
"message": "No provider exists with that id."
}
}

The entity exists and is in your relationship, but has no books a report can be produced from — it is still onboarding, or it has been deactivated. It appears in GET /business_entities with reporting_available: false; skip it rather than recording a zero.

Media typeapplication/json

The failure shape for every error — validation, authorization, ours — so a client needs a single error path.

Match on code, not on message: the code set below is the contract and is stable, while wording may be clarified. New codes may be added within v1 (see guides/versioning), so treat an unrecognised code as “the HTTP status is authoritative”.

This includes a request that never reaches a documented operation at all — an unrouted path or a method we do not serve on that path, which is the failure you are most likely to meet while integrating. Those are answered before any operation runs, so no operation below lists them, but they arrive in this same shape, as ENDPOINT_NOT_FOUND (404) and METHOD_NOT_ALLOWED (405). Either one means check the URL rather than your credentials: the operations below are the whole surface.

object
error
required
object
code
required

Machine-readable cause.

  • INVALID_REQUEST (400) — malformed dates, a non-UUID path id, an inverted range, or a range with no reportable books behind it.
  • INSECURE_TRANSPORT (400) — the request was sent over plaintext http, so the key crossed the network in the clear. Rotate the key, then fix the URL; we refuse rather than redirect so this cannot pass unnoticed.
  • INVALID_API_KEY (401) — missing, invalid, expired or revoked key.
  • PARTNER_API_NOT_ENABLED (403) — your key is valid, but your organization is not enrolled in the API programme. Contact us; do not rotate the key.
  • PROVIDER_NOT_ACTIVE (403) — a provider key whose Flychain account is not active. Contact us; do not rotate the key.
  • PROVIDER_API_NOT_ENABLED (403) — a provider key on an account that is not enrolled in the API programme. Contact us; do not rotate the key.
  • ENDPOINT_NOT_AVAILABLE (403) — the path exists and your key is valid, but that operation is not served for your kind of key. The balance sheet and cash flow families are provider-only. Your URL is not wrong; do not rotate the key.
  • PROVIDER_NOT_IN_PARTNER_SCOPE (403) — the provider exists but is not in your relationship, including one that has left it.
  • BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE (403) — the entity exists but does not belong to the provider_id in the path.
  • PROVIDER_NOT_FOUND (404) — no provider with that id.
  • BUSINESS_ENTITY_NOT_FOUND (404) — no business entity with that id.
  • ENDPOINT_NOT_FOUND (404) — the URL itself is not one we serve, as opposed to a record we do not have. Check the path against the operations below.
  • METHOD_NOT_ALLOWED (405) — the path exists but not with that method; the Allow response header lists the ones it takes. Every operation here is a GET.
  • BOOKS_NOT_AVAILABLE (409) — the entity has no reportable books.
  • INTERNAL_ERROR (500) — ours; retry with backoff.
  • AUTH_SERVICE_UNAVAILABLE (503) — we could not verify your key; retry with backoff, and do not treat it as an authentication failure.
string
Allowed values: INVALID_REQUEST INSECURE_TRANSPORT INVALID_API_KEY PARTNER_API_NOT_ENABLED PROVIDER_NOT_ACTIVE PROVIDER_API_NOT_ENABLED ENDPOINT_NOT_AVAILABLE PROVIDER_NOT_IN_PARTNER_SCOPE BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE PROVIDER_NOT_FOUND BUSINESS_ENTITY_NOT_FOUND ENDPOINT_NOT_FOUND METHOD_NOT_ALLOWED BOOKS_NOT_AVAILABLE INTERNAL_ERROR AUTH_SERVICE_UNAVAILABLE
message
required

Human-readable detail. Do not match on it.

string
key
additional properties
any
key
additional properties
any
Examples
ExamplenoBooks
{
"error": {
"code": "BOOKS_NOT_AVAILABLE",
"message": "This business entity does not currently have reportable books. GET /business_entities lists it with reporting_available: false."
}
}

Our side. Safe to retry with backoff.

Media typeapplication/json

The failure shape for every error — validation, authorization, ours — so a client needs a single error path.

Match on code, not on message: the code set below is the contract and is stable, while wording may be clarified. New codes may be added within v1 (see guides/versioning), so treat an unrecognised code as “the HTTP status is authoritative”.

This includes a request that never reaches a documented operation at all — an unrouted path or a method we do not serve on that path, which is the failure you are most likely to meet while integrating. Those are answered before any operation runs, so no operation below lists them, but they arrive in this same shape, as ENDPOINT_NOT_FOUND (404) and METHOD_NOT_ALLOWED (405). Either one means check the URL rather than your credentials: the operations below are the whole surface.

object
error
required
object
code
required

Machine-readable cause.

  • INVALID_REQUEST (400) — malformed dates, a non-UUID path id, an inverted range, or a range with no reportable books behind it.
  • INSECURE_TRANSPORT (400) — the request was sent over plaintext http, so the key crossed the network in the clear. Rotate the key, then fix the URL; we refuse rather than redirect so this cannot pass unnoticed.
  • INVALID_API_KEY (401) — missing, invalid, expired or revoked key.
  • PARTNER_API_NOT_ENABLED (403) — your key is valid, but your organization is not enrolled in the API programme. Contact us; do not rotate the key.
  • PROVIDER_NOT_ACTIVE (403) — a provider key whose Flychain account is not active. Contact us; do not rotate the key.
  • PROVIDER_API_NOT_ENABLED (403) — a provider key on an account that is not enrolled in the API programme. Contact us; do not rotate the key.
  • ENDPOINT_NOT_AVAILABLE (403) — the path exists and your key is valid, but that operation is not served for your kind of key. The balance sheet and cash flow families are provider-only. Your URL is not wrong; do not rotate the key.
  • PROVIDER_NOT_IN_PARTNER_SCOPE (403) — the provider exists but is not in your relationship, including one that has left it.
  • BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE (403) — the entity exists but does not belong to the provider_id in the path.
  • PROVIDER_NOT_FOUND (404) — no provider with that id.
  • BUSINESS_ENTITY_NOT_FOUND (404) — no business entity with that id.
  • ENDPOINT_NOT_FOUND (404) — the URL itself is not one we serve, as opposed to a record we do not have. Check the path against the operations below.
  • METHOD_NOT_ALLOWED (405) — the path exists but not with that method; the Allow response header lists the ones it takes. Every operation here is a GET.
  • BOOKS_NOT_AVAILABLE (409) — the entity has no reportable books.
  • INTERNAL_ERROR (500) — ours; retry with backoff.
  • AUTH_SERVICE_UNAVAILABLE (503) — we could not verify your key; retry with backoff, and do not treat it as an authentication failure.
string
Allowed values: INVALID_REQUEST INSECURE_TRANSPORT INVALID_API_KEY PARTNER_API_NOT_ENABLED PROVIDER_NOT_ACTIVE PROVIDER_API_NOT_ENABLED ENDPOINT_NOT_AVAILABLE PROVIDER_NOT_IN_PARTNER_SCOPE BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE PROVIDER_NOT_FOUND BUSINESS_ENTITY_NOT_FOUND ENDPOINT_NOT_FOUND METHOD_NOT_ALLOWED BOOKS_NOT_AVAILABLE INTERNAL_ERROR AUTH_SERVICE_UNAVAILABLE
message
required

Human-readable detail. Do not match on it.

string
key
additional properties
any
key
additional properties
any
Examples
ExampleinternalError
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred. Retry with backoff."
}
}

We could not verify your API key right now — our identity provider was unreachable or rate-limited. This is not an authentication failure: the key may well be valid. Retry with backoff rather than treating it as a 401.

Media typeapplication/json

The failure shape for every error — validation, authorization, ours — so a client needs a single error path.

Match on code, not on message: the code set below is the contract and is stable, while wording may be clarified. New codes may be added within v1 (see guides/versioning), so treat an unrecognised code as “the HTTP status is authoritative”.

This includes a request that never reaches a documented operation at all — an unrouted path or a method we do not serve on that path, which is the failure you are most likely to meet while integrating. Those are answered before any operation runs, so no operation below lists them, but they arrive in this same shape, as ENDPOINT_NOT_FOUND (404) and METHOD_NOT_ALLOWED (405). Either one means check the URL rather than your credentials: the operations below are the whole surface.

object
error
required
object
code
required

Machine-readable cause.

  • INVALID_REQUEST (400) — malformed dates, a non-UUID path id, an inverted range, or a range with no reportable books behind it.
  • INSECURE_TRANSPORT (400) — the request was sent over plaintext http, so the key crossed the network in the clear. Rotate the key, then fix the URL; we refuse rather than redirect so this cannot pass unnoticed.
  • INVALID_API_KEY (401) — missing, invalid, expired or revoked key.
  • PARTNER_API_NOT_ENABLED (403) — your key is valid, but your organization is not enrolled in the API programme. Contact us; do not rotate the key.
  • PROVIDER_NOT_ACTIVE (403) — a provider key whose Flychain account is not active. Contact us; do not rotate the key.
  • PROVIDER_API_NOT_ENABLED (403) — a provider key on an account that is not enrolled in the API programme. Contact us; do not rotate the key.
  • ENDPOINT_NOT_AVAILABLE (403) — the path exists and your key is valid, but that operation is not served for your kind of key. The balance sheet and cash flow families are provider-only. Your URL is not wrong; do not rotate the key.
  • PROVIDER_NOT_IN_PARTNER_SCOPE (403) — the provider exists but is not in your relationship, including one that has left it.
  • BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE (403) — the entity exists but does not belong to the provider_id in the path.
  • PROVIDER_NOT_FOUND (404) — no provider with that id.
  • BUSINESS_ENTITY_NOT_FOUND (404) — no business entity with that id.
  • ENDPOINT_NOT_FOUND (404) — the URL itself is not one we serve, as opposed to a record we do not have. Check the path against the operations below.
  • METHOD_NOT_ALLOWED (405) — the path exists but not with that method; the Allow response header lists the ones it takes. Every operation here is a GET.
  • BOOKS_NOT_AVAILABLE (409) — the entity has no reportable books.
  • INTERNAL_ERROR (500) — ours; retry with backoff.
  • AUTH_SERVICE_UNAVAILABLE (503) — we could not verify your key; retry with backoff, and do not treat it as an authentication failure.
string
Allowed values: INVALID_REQUEST INSECURE_TRANSPORT INVALID_API_KEY PARTNER_API_NOT_ENABLED PROVIDER_NOT_ACTIVE PROVIDER_API_NOT_ENABLED ENDPOINT_NOT_AVAILABLE PROVIDER_NOT_IN_PARTNER_SCOPE BUSINESS_ENTITY_NOT_IN_PARTNER_SCOPE PROVIDER_NOT_FOUND BUSINESS_ENTITY_NOT_FOUND ENDPOINT_NOT_FOUND METHOD_NOT_ALLOWED BOOKS_NOT_AVAILABLE INTERNAL_ERROR AUTH_SERVICE_UNAVAILABLE
message
required

Human-readable detail. Do not match on it.

string
key
additional properties
any
key
additional properties
any
Examples
ExampleauthUnavailable
{
"error": {
"code": "AUTH_SERVICE_UNAVAILABLE",
"message": "Unable to verify the API key right now. Retry with backoff."
}
}