> ## Documentation Index
> Fetch the complete documentation index at: https://docs.consile.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API reference: Billy

> The 17 read-only tools in the Billy connector: shared pagination, the amount/taxMode conventions, opaque ids and the organization-scoped access token, plus arguments and return shapes per tool.

All Billy tools are **read-only** and are called via `tools/call` over
`POST /billy/mcp`. The connector is connected with an **access token** (Billy's
permanent, organization-scoped token, no OAuth). See [Forbind Billy](/connect/forbind-billy).

<Info>
  Endpoint: `https://mcp.consile.ai/billy/mcp`. Billy is its own named connector
  with only its own tools. The transport namespaces each tool as `billy__<tool>`
  (e.g. `billy__get_invoice`); your AI assistant invokes these for you, so the
  names below are the bare tool names.
</Info>

<Note>
  This connector is **read-only by construction**: the client exposes only a
  generic JSON `GET` (`getJson`) and has no write verb (no post/put/delete) at all.
  Every one of the 17 tools is `readOnly`. Your AI can read your figures but can
  never change, create or delete anything in Billy.
</Note>

## Shared conventions

### No organizationId

Billy's access token is **organization-scoped**: one token maps to exactly one
Billy company, so **no tool takes an `organizationId`**. The token itself scopes
every request. `get_organization` is the health-check that tells you which company
the connected token belongs to. A customer with several Billy companies connects
one instance (one token) per company (`multiInstance`).

### Pagination

List tools return a compact `{ items, pagination }` envelope. Billy returns a real
filtered `total` (unlike some other connectors), so `pageCount` and `hasMore` are
reliable.

```json theme={null}
// list_* response
{
  "items": [ ... ],
  "pagination": { "page": 1, "pageSize": 50, "pageCount": 9, "total": 412, "hasMore": true }
}
```

<ParamField path="page" type="integer" default="1">1-based page number.</ParamField>

<ParamField path="pageSize" type="integer" default="50">
  Rows per page. Default is `50` on every list tool **except** `list_currencies`
  (default `200`). Billy hard max is `1000`.
</ParamField>

### Amounts, ids and dates

<Warning>
  Billy amounts are **floats in major units**: `1200` means `1200.00 DKK`. Never
  divide by 100. On invoices, bills and lines the `taxMode` field (`incl`/`excl`)
  governs whether the amount already includes VAT. Interpret VAT via `list_tax_rates`.
</Warning>

<ParamField path="Billy ids" type="string">
  All Billy ids (`invoiceId`, `billId`, `contactId`, `accountId`, `daybookId`,
  `transactionId`, …) are **opaque strings**, never integers.
</ParamField>

<ParamField path="date filters" type="string (YYYY-MM-DD)">
  Date-only, no time or zone. `minEntryDate`/`maxEntryDate` are inclusive bounds on
  the invoice and bill lists.
</ParamField>

### Embedded children

`get_invoice` embeds its lines + customer contact and returns a `downloadUrl` (the
invoice PDF link). `get_bill` embeds its lines + supplier contact. `list_transactions`,
`get_transaction` embed the balanced postings. These get-one tools are already
self-contained, so no follow-up call is needed.

### Error contract

A `429` is retried once after \~2 seconds; all other `4xx` are never retried. Every
upstream call is bounded at **15 seconds**.

| Status        | What it means                                                                                                                                                      |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `401`         | Token rejected (revoked inside Billy) → `BillyAuthError`, "reconnect required"                                                                                     |
| `403`         | Token valid but lacks permission for the resource → `BillyPermissionError`; reconnecting the **same** token will not help, the token needs broader access in Billy |
| `429`         | Rate limited: waits \~2s and retries **once**, then `BillyRateLimitError` ("wait a moment and try again")                                                          |
| other non-2xx | `BillyApiError` with the parsed status + Billy's error detail                                                                                                      |

See [Errors & limits](/developers/errors-and-limits).

***

## Organization & reference

| Tool                     | Description                                                                                                                                                  | Key arguments                      | Returns                      |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------- | ---------------------------- |
| `get_organization`       | The Billy company this token is connected to: name, base currency, CVR/registration number and address. The "which company am I connected to?" health-check. | (none)                             | `{ count, organizations[] }` |
| `list_products`          | The product/service catalogue: name, account, prices, VAT.                                                                                                   | `q?`, `page`, `pageSize`           | `{ items, pagination }`      |
| `list_tax_rates`         | The organization's VAT/tax rates (momssatser); interpret `tax`/`taxRateId` on invoices, bills and lines.                                                     | `page`, `pageSize`                 | `{ items, pagination }`      |
| `list_sales_tax_returns` | VAT return periods (momsangivelser) with period bounds and status.                                                                                           | `page`, `pageSize`                 | `{ items, pagination }`      |
| `list_currencies`        | Currencies Billy knows (id = ISO code, e.g. DKK); reference for `currencyId`/`exchangeRate`.                                                                 | `page`, `pageSize` (default `200`) | `{ items, pagination }`      |

***

## Sales: invoices (accounts receivable)

| Tool            | Description                                                                       | Key arguments                                                                                                      | Returns                 |
| --------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------- |
| `list_invoices` | Sales invoices, **sorted newest first** (by entry date).                          | `state?` (`draft`/`approved`), `isPaid?`, `contactId?`, `minEntryDate?`, `maxEntryDate?`, `q?`, `page`, `pageSize` | `{ items, pagination }` |
| `get_invoice`   | Full invoice by id with lines + customer embedded, plus `downloadUrl` (PDF link). | `invoiceId`                                                                                                        | invoice object          |

<Note>
  Invoice `state` is `draft` or `approved`; `approved` is a finalised invoice (a
  one-way door in Billy).
</Note>

***

## Purchases: bills (accounts payable)

| Tool         | Description                                                           | Key arguments                                                                                                                          | Returns                 |
| ------------ | --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| `list_bills` | Supplier bills (kreditorer), **sorted newest first** (by entry date). | `state?` (`draft`/`approved`/`voided`), `isPaid?`, `contactId?` (supplier), `minEntryDate?`, `maxEntryDate?`, `q?`, `page`, `pageSize` | `{ items, pagination }` |
| `get_bill`   | Full bill by id with lines + supplier embedded.                       | `billId`                                                                                                                               | bill object             |

***

## Contacts

Billy keeps **one** contact register for both customers and suppliers. The
`isCustomer`/`isSupplier` flags split them; `registrationNo` carries the CVR.

| Tool            | Description                                                                                        | Key arguments                                          | Returns                 |
| --------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ----------------------- |
| `list_contacts` | Search/list the merged customer + supplier register.                                               | `isCustomer?`, `isSupplier?`, `q?`, `page`, `pageSize` | `{ items, pagination }` |
| `get_contact`   | Full single contact: customer/supplier flags, CVR (`registrationNo`), EAN, address, payment terms. | `contactId`                                            | contact object          |

***

## Finance / general ledger

| Tool                        | Description                                                                                                                                                             | Key arguments                                                            | Returns                 |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | ----------------------- |
| `list_accounts`             | The chart of accounts (kontoplan): account number, name, group, VAT rate, bank-account flags.                                                                           | `q?`, `page`, `pageSize`                                                 | `{ items, pagination }` |
| `list_postings`             | Double-entry ledger postings (raw kontokort). Scope to one account via `accountId`. Each posting has amount, side (debit/credit) and a link to its transaction/voucher. | `accountId?`, `page`, `pageSize`                                         | `{ items, pagination }` |
| `list_transactions`         | Voucher-level transactions (bilag) with their balanced postings embedded.                                                                                               | `page`, `pageSize`                                                       | `{ items, pagination }` |
| `get_transaction`           | One voucher/transaction (bilag) by id with its balanced postings embedded.                                                                                              | `transactionId`                                                          | transaction object      |
| `list_daybook_transactions` | Draft journal entries in the daybooks (kladdeposter) awaiting posting.                                                                                                  | `daybookId?`, `state?` (`draft`/`approved`/`voided`), `page`, `pageSize` | `{ items, pagination }` |
| `list_bank_payments`        | Bank payments used to settle invoices/bills: the reconciliation view of money in and out.                                                                               | `page`, `pageSize`                                                       | `{ items, pagination }` |

***

## Code examples

<CodeGroup>
  ```json Request: list_invoices (outstanding, newest first) theme={null}
  {
    "name": "billy__list_invoices",
    "arguments": { "isPaid": false, "pageSize": 100 }
  }
  ```

  ```json Request: get_invoice (lines + customer + PDF link) theme={null}
  {
    "name": "billy__get_invoice",
    "arguments": { "invoiceId": "AbCd1234..." }
  }
  ```

  ```json Request: list_postings (one account) theme={null}
  {
    "name": "billy__list_postings",
    "arguments": { "accountId": "XyZ9876...", "pageSize": 200 }
  }
  ```
</CodeGroup>

<Note>
  This connector vaults the customer's Billy access token with **no upstream
  validation at connect time**, so an invalid or revoked token surfaces here as a
  "reconnect required" error (`401`) on the first call rather than at connect. A
  `403` means the token lacks permission and reconnecting the same token will not
  help. See [Errors & limits](/developers/errors-and-limits).
</Note>
