A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Sage API is how an app or AI agent works with a Sage Business Cloud Accounting business: listing contacts, raising a sales invoice, recording a payment against a bill, or posting a journal to the ledger. Access is granted through an OAuth access token tied to one Sage user, and that user's role in each area, like Sales, Purchases, Bank, or Contacts, sets what a call can read or change. Sage does not push events, so an integration detects changes by asking for records updated since a given time.
How an app or AI agent connects to Sage determines what it can reach. There is one route, a REST API authenticated with an OAuth access token, and the data an agent can touch is bounded by the Sage user who authorized the app and the role that user holds in each area of the business.
The REST API accepts and returns JSON (the request body must be application/json), keys each record by an opaque id, and pages lists with page and items_per_page. The base URL is https://api.accounting.sage.com/v3.1, shared across the supported regions, with the OAuth token and revoke endpoints under https://oauth.accounting.sage.com and the authorization server at https://www.sageone.com/oauth2/auth/central. The X-Business header selects which of the user's businesses a call acts on.
Sage uses the OAuth 2.0 authorization-code flow, which supports PKCE. The user is sent to the Sage authorization server, authenticates, and authorizes the app, which returns a single-use code (valid 60 seconds) exchanged at https://oauth.accounting.sage.com/token for an access token and a refresh token. The requested scope is either readonly or full_access. The access token is sent as a Bearer token on every call; it lasts 5 minutes, and the refresh token rotates on use and expires after 31 days of inactivity.
The Sage Accounting API is split into areas an agent can act on, like contacts, sales invoices, purchase invoices, payments, bank accounts, and the ledger. Each area maps to a Sage access role, and a write in one area records real financial data in the business.
Methods for working with contacts, the customers and suppliers a business deals with.
Methods for working with sales invoices and sales credit notes.
Methods for working with purchase invoices and purchase credit notes.
Methods for working with contact payments and receipts.
Methods for working with bank accounts.
Methods for working with ledger accounts, the chart of accounts.
Methods for working with products and services.
Methods for reading tax rates.
Methods for working with manual journals posted to the ledger.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
ContactsMethods for working with contacts, the customers and suppliers a business deals with.5 | ||||||
| GET | /v3.1/contacts | List all contacts (paginated), with filters like updated_or_created_since, contact_type_id, and search. | read | — | Current | |
No per-method OAuth scope; needs a Read Only or higher role in Contacts, Sales, or Purchases. Acts oncontact Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3.1/contacts/{key} | Retrieve a single contact by its id. | read | — | Current | |
Read-only; needs a Read Only or higher role in Contacts, Sales, or Purchases. Acts oncontact Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/contacts | Create a contact (a customer or supplier), optionally with address data created in the background. | write | — | Current | |
Needs a Restricted Access or Full Access role in Contacts; a Read Only role returns 403 MultiUserAccessDenied. Acts oncontact Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v3.1/contacts/{key} | Update an existing contact. | write | — | Current | |
Needs a Restricted Access or Full Access role in Contacts. Acts oncontact Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v3.1/contacts/{key} | Delete a contact. | write | — | Current | |
Deleting needs a Full Access role in Contacts; Restricted Access cannot delete. Acts oncontact Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Sales TransactionsMethods for working with sales invoices and sales credit notes.6 | ||||||
| GET | /v3.1/sales_invoices | List all sales invoices (paginated), with filters like contact_id, status_id, from_date, and updated_or_created_since. | read | — | Current | |
Needs a Read Only or higher role in Sales. Acts onsales_invoice Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3.1/sales_invoices/{key} | Retrieve a single sales invoice by its id. | read | — | Current | |
Read-only; needs a Read Only or higher role in Sales. Acts onsales_invoice Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/sales_invoices | Create a sales invoice (an outgoing invoice). | write | — | Current | |
Needs a Restricted Access or Full Access role in Sales. Acts onsales_invoice Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v3.1/sales_invoices/{key} | Update a sales invoice. | write | — | Current | |
Needs a Restricted Access or Full Access role in Sales. Voiding (DELETE) needs Full Access. Acts onsales_invoice Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3.1/sales_credit_notes | List all sales credit notes (paginated). | read | — | Current | |
Needs a Read Only or higher role in Sales. Acts onsales_credit_note Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/sales_credit_notes | Create a sales credit note (an outgoing credit). | write | — | Current | |
Needs a Restricted Access or Full Access role in Sales. Acts onsales_credit_note Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Purchase TransactionsMethods for working with purchase invoices and purchase credit notes.4 | ||||||
| GET | /v3.1/purchase_invoices | List all purchase invoices (paginated), with filters like contact_id, status_id, and updated_or_created_since. | read | — | Current | |
Needs a Read Only or higher role in Purchases. Acts onpurchase_invoice Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/purchase_invoices | Create a purchase invoice (an incoming bill). | write | — | Current | |
Needs a Restricted Access or Full Access role in Purchases. Acts onpurchase_invoice Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /v3.1/purchase_invoices/{key} | Update a purchase invoice. | write | — | Current | |
Needs a Restricted Access or Full Access role in Purchases. Acts onpurchase_invoice Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v3.1/purchase_credit_notes | List all purchase credit notes (paginated). | read | — | Current | |
Needs a Read Only or higher role in Purchases. Acts onpurchase_credit_note Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Payments & ReceiptsMethods for working with contact payments and receipts.2 | ||||||
| GET | /v3.1/contact_payments | List all contact payments and receipts (paginated); the transaction_type_id distinguishes a payment from a receipt. | read | — | Current | |
Needs a Read Only or higher role in Bank. Acts oncontact_payment Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/contact_payments | Record a payment or receipt against a contact and an artefact such as an invoice. | write | — | Current | |
Needs a Restricted Access or Full Access role in Bank. Acts oncontact_payment Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
BankingMethods for working with bank accounts.2 | ||||||
| GET | /v3.1/bank_accounts | List all bank accounts (paginated). | read | — | Current | |
Needs a Read Only or higher role in Bank. Acts onbank_account Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/bank_accounts | Create a bank account. | write | — | Current | |
Needs a Restricted Access or Full Access role in Bank. Acts onbank_account Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Chart of AccountsMethods for working with ledger accounts, the chart of accounts.2 | ||||||
| GET | /v3.1/ledger_accounts | List ledger accounts, the chart of accounts, with filters like visible_in to find accounts usable in a given area. | read | — | Current | |
Read-only; a Read Only or higher role in any one of several areas (Sales, Purchases, Bank, Contacts, Journals, Products & Services, Settings) is enough. Acts onledger_account Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/ledger_accounts | Create a ledger account in the chart of accounts. | write | — | Current | |
Editing the chart of accounts needs a Full Access role in Settings. Acts onledger_account Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Products & ServicesMethods for working with products and services.2 | ||||||
| GET | /v3.1/products | List all products and services (paginated), with filters like search and active. | read | — | Current | |
Needs a Read Only or higher role in Products & Services, Sales, or Purchases. Acts onproduct Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/products | Create a product or service. | write | — | Current | |
Needs a Restricted Access or Full Access role in Products & Services. Acts onproduct Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TaxesMethods for reading tax rates.1 | ||||||
| GET | /v3.1/tax_rates | List the tax rates configured for the business, with filters like usage and date. | read | — | Current | |
Read-only; a Read Only or higher role in Sales, Purchases, Bank, or Settings is enough. Creating a tax rate is US only. Acts ontax_rate Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Transactions (Journals)Methods for working with manual journals posted to the ledger.2 | ||||||
| GET | /v3.1/journals | List all manual journals (paginated). | read | — | Current | |
Needs a Read Only or Full Access role in Journals. Acts onjournal Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v3.1/journals | Post a manual journal to the ledger, with balancing journal lines. | write | — | Current | |
Posting a journal needs a Full Access role in Journals. Acts onjournal Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| Event | What it signals | Triggered by |
|---|
Sage limits how fast an app can call, by a per-day request quota and a cap on how many requests run at once, both measured per app and shared across the user's businesses.
Sage sets a request quota of 1,296,000 requests per app per day and allows at most 150 concurrent requests at any time, both measured against the app and, where a user has more than one business, shared across those businesses. Going over either returns HTTP 429, and Sage warns a client may then have to wait up to 24 hours before a successful request. Sage recommends queueing requests and retrying with wait-and-repeat backoff. There is no documented per-method cost or point weighting.
List endpoints page with page (the page number, default 1) and items_per_page (default 20, minimum 1, maximum 200). A list response wraps the records in $items and includes $total, $page, $itemsPerPage, $next, and $back, where $next and $back are ready-made paths to the adjacent pages or null. To sync efficiently, a request can pass updated_or_created_since to return only records changed since a timestamp, and deleted_since to find deleted records.
A single list page returns at most 200 records, the maximum value of items_per_page. Access and refresh tokens can each be up to 2048 bytes, which Sage advises reserving in storage. The API gateway times a backend request out at 45 seconds, returning a 504.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | AccessTokenExpiredError / Authorization | The request was not authorized: the access token expired, was revoked, was malformed or missing, the user or business was not found, the subscription is invalid, or a read-only client attempted a write. | If the token expired, refresh it and retry. For other causes, prompt the user to authorize again and discard stored refresh tokens. |
| 403 | MultiUserAccessDenied | The authorizing user's role in the relevant business area does not permit this request, for example a Read Only user attempting a POST or PUT, or a No Access user attempting a GET. | Grant the user the required role in that area (Sales, Purchases, Bank, Contacts, Products & Services, or Settings), or have an authorized user perform the action. |
| 404 | PathNotFound | The requested endpoint or record does not exist. | Check the path and the record id, and confirm the resource exists in this business. |
| 405 | MethodNotAllowed | The HTTP verb used is not valid for this endpoint. | Use a verb the endpoint supports, listed in the API reference for that path. |
| 415 | Unsupported Media Type | The request body was not application/json. The Accounting API only accepts JSON bodies. | Set the Content-Type to application/json and send a JSON body. |
| 422 | Unprocessable Entity | The data passed is invalid and the request cannot be completed, for example a missing required field or a failed validation. | Read the $message in each returned error object, correct the data, and resend. |
| 429 | Too Many Requests | The app exceeded the daily request quota (1,296,000) or the concurrency cap (150). Sage warns it may then require waiting up to 24 hours before a successful request. | Queue requests and retry with wait-and-repeat backoff; smooth the request rate to stay under the limits. |
| 500 | Internal Server Error | An unexpected error on Sage's side. A 503 Service Unavailable or 504 Gateway Timeout (45-second backend timeout) can also occur. | Retry later with backoff, using idempotent handling, and contact Sage support if it persists. |
Sage carries its API version in the request path. v3.1 is the current version for Sage Business Cloud Accounting, with the older v1 and v2 still supported for some regions and on a migration path to v3.1.
v3.1 is the current version of the Sage Business Cloud Accounting API, carried in the request path as /v3.1. It is the version Sage develops and recommends building against. Access and refresh tokens were enlarged in v3.1 (up to 2048 bytes), and the authorization flow filters to v3.1-supported countries with the filter=apiv3.1 parameter.
v1 and v2 remain supported for some regions, such as US-only on v2, but Sage advises migrating to v3.1. They are the prior generations of the Sage Business Cloud Accounting API.
v1 is the earliest generation of the API. Legacy SageOne Accounts and Cashbook products used v1 and v2, both now deprecated for new signups, with customers directed to migrate to Accounting or Start on v3.1.
Build against v3.1; v1 and v2 are legacy and being migrated forward.
Sage Accounting migration guide ↗Bollard AI sits between a team's AI agents and Sage. Grant each agent exactly the access it needs, read or write, area by area, and every call is checked and logged.