Everything an AI agent can do with the Wave API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints15
API versionGraphQL (unversioned)
Last updated23 June 2026
Orientation

How the Wave API works.

The Wave API is how an app or AI agent works with a Wave business: creating an invoice, recording a customer, posting an accounting transaction, or reading the chart of accounts. Access is granted through an OAuth bearer token whose scopes follow a resource and operation pattern, like invoice:write, so a token can read or write only the resources it was granted. A query reads and a mutation writes, and Wave can push a signed event to a registered endpoint when something changes, like an invoice being created.

15Endpoints
6Capability groups
9Read
6Write
12Permissions
Authentication
Wave authenticates every call with an OAuth 2.0 bearer token. An application uses the authorization-code flow to act on behalf of other Wave users, with short-lived access tokens (around two hours) refreshed using a refresh token from the offline_access scope. A full access token, generated in the developer portal, grants unrestricted access to the owner's own account and is meant for development and single-account automation, not for connecting to other users.
Permissions
Scopes follow a resource:operation pattern, like business:read, customer:write, invoice:write, product:read, account:read, sales_tax:read, and transaction:write. Read and write are granted independently, so write does not imply read. A token reaches only the resources its scopes name; a missing scope returns a 403, and for webhooks a missing scope means the matching events are simply not delivered.
Data model
Wave is a single GraphQL endpoint rather than many REST paths. Every operation is a POST: a query reads, a mutation writes, and the request names exactly the fields it wants back. The core objects are businesses, customers, invoices, products, the chart of accounts, sales taxes, and money transactions, with a business id scoping most operations. A mutation reports validation problems in an inputErrors array inside an HTTP 200 response.
Subscriptions
Wave requires an active Wave Pro subscription on a business for third-party OAuth access and for webhook delivery (a change that took effect on 26 May 2025). A webhook subscription posts a signed event to an HTTPS endpoint, verified with an HMAC-SHA256 x-wave-signature header, so an integration learns about activity like an invoice being created or a payment received without polling.
Connect & authenticate

Connection & authentication methods.

How an app or AI agent connects to Wave determines what it can reach. There is one route for making calls and a separate route for receiving events, and each is governed by the token behind it and the permissions that token carries.

Ways to connect

GraphQL API

Wave exposes a single GraphQL endpoint at https://gql.waveapps.com/graphql/public. Every operation is a POST to that one URL: a query reads data, a mutation writes it, and the request body names exactly the fields it wants back. A call authenticates with an OAuth bearer token, and the scopes on that token decide which resources it can read or write. Lists are returned as cursor-paginated connections.

Best forConnecting an app or AI agent to Wave.
Governed byThe bearer token and the scopes it carries.
Docs ↗

Webhooks

Wave POSTs a signed event to an HTTPS endpoint when something happens in a business, like an invoice being created or a payment being received. The receiver verifies the x-wave-signature header, an HMAC-SHA256 of the payload computed with the subscription's signing secret, to confirm the request came from Wave. Webhook delivery requires an active Wave Pro subscription on the business and the matching scope on the OAuth grant.

Best forReceiving Wave events at an app or AI agent.
Governed byThe signing secret on the webhook subscription.
Docs ↗
Authentication

OAuth 2.0

Wave uses the OAuth 2.0 authorization-code flow. An application redirects a Wave user to grant access, then exchanges the returned code for an access token sent as a bearer token on every request. Access tokens are short-lived (around two hours), and requesting the offline_access scope returns a refresh token for long-term access. This is the method for any application published to other Wave users.

TokenOAuth bearer access token (plus a refresh token with offline_access)
Best forApplications that connect on behalf of other Wave users.
Docs ↗

Full access token

A full access token is generated in the Wave developer portal and grants unrestricted access to the account that created it. It is intended for development and for automating a single owner's own account, not for connecting to other users. Because it carries every permission, a leaked full access token reaches everything in that account.

TokenBearer full access token
Best forDevelopment and single-account automation by the account owner.
Docs ↗
Endpoint reference

Every Wave API operation.

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.

MethodEndpointWhat it doesAccessPermissionVersion

Businesses

Operations for the authenticated user and the businesses they can reach.3

Read-only. Returns the identity behind the token, not other collaborators.

Acts onuser
Permission (capability)user:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only. The usual entry point for mapping a token to the businesses it controls.

Acts onbusiness
Permission (capability)business:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only. A business id scopes most other queries and mutations.

Acts onbusiness
Permission (capability)business:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Customers

Operations for working with a business's customers.3

Read-only. Returns customer contact and billing details.

Acts oncustomer
Permission (capability)customer:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A core write. The mutation returns the new customer, a didSucceed flag, and any inputErrors.

Acts oncustomer
Permission (capability)customer:write
VersionAvailable since the API’s base version
Webhook eventcustomer.created
Rate limitStandard limits apply

A write. Only the supplied fields are changed.

Acts oncustomer
Permission (capability)customer:write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Invoices

Operations for working with invoices.3

Read-only. Returns invoice status, line items, and amounts.

Acts oninvoice
Permission (capability)invoice:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A core write. Returns the new invoice, a didSucceed flag, and any inputErrors.

Acts oninvoice
Permission (capability)invoice:write
VersionAvailable since the API’s base version
Webhook eventinvoice.created
Rate limitStandard limits apply

A destructive write. Removes the invoice record.

Acts oninvoice
Permission (capability)invoice:write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Products & services

Operations for the products and services a business sells.2

Read-only. Returns product names, prices, and linked income accounts.

Acts onproduct
Permission (capability)product:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A core write. The product can then be referenced on invoice line items.

Acts onproduct
Permission (capability)product:write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Accounts

Operations for the chart of accounts that bookkeeping posts to.2

Read-only. Accounts are referenced when posting a transaction to the books.

Acts onaccount
Permission (capability)account:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only. Sales taxes are applied to invoice line items.

Acts onsales_tax
Permission (capability)sales_tax:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Transactions

Operations for accounting transactions in the ledger.2

Read-only. Returns posted ledger entries and the accounts they affect.

Acts onmoney_transaction
Permission (capability)transaction:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A core bookkeeping write. Posts a double-entry transaction across accounts; returns a didSucceed flag and any inputErrors.

Acts onmoney_transaction
Permission (capability)transaction:write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply
No endpoints match those filters.
Webhooks

Webhook events.

Wave can notify an app when something happens in a business, like an invoice being created or a payment being received. It sends a signed event to a registered endpoint, so an integration learns about activity without polling.

EventWhat it signalsTriggered by
invoice.createdAn invoice was created in a business. The payload identifies the business and the invoice so an integration can fetch its details.mutation invoiceCreate
customer.createdA customer was created in a business.mutation customerCreate
merchant.payment_receivedA business received a payment from a customer, for example against an outstanding invoice.In-app only
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

Wave is a single GraphQL endpoint, so the size of a request is shaped by the query an agent sends rather than by fixed page sizes, and lists are walked with cursors.

Request rate

Wave does not publish official per-method rate-limit values, response headers, or Retry-After signaling in its developer documentation. Commonly cited figures from integration guides are around 60 requests per minute per access token and a few thousand per day per application, but these are not officially documented, so an integration should treat them as approximate, back off on an HTTP 429, and avoid bursts.

Pagination

Lists are returned as GraphQL connections and walked with a cursor. A query asks for a page with a pageSize argument and a page number or an after cursor, and the response carries pageInfo so a caller knows whether more pages remain. Because the response shape is set by the query, an agent fetches only the fields it needs.

Request size

There is no fixed page size across the API. The amount returned is shaped by the query an agent writes (the fields and the requested page), so request size is controlled by the caller rather than by a global maximum.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
200inputErrorsA mutation ran but its input failed validation. Wave returns the failure inside the response, as an inputErrors array of code, message, and path entries, alongside a didSucceed flag, rather than as a transport error.Check didSucceed and read inputErrors to find which field failed and why, then correct the input and resend.
200errorsA GraphQL-level problem, like an unknown field or a malformed query. Wave returns a top-level errors array with a message and location, and HTTP 200, because the request reached the GraphQL layer.Read the message and location, fix the query, and resend.
401unauthenticatedNo valid token was provided, or the access token has expired (tokens last around two hours).Refresh the access token using the refresh token, or run the OAuth flow again, then retry.
403forbiddenThe token is valid but lacks the scope the operation needs, or the business does not have the subscription a feature requires.Request the matching scope in the OAuth grant, or confirm the business has the required Wave Pro subscription, then retry.
429rate_limitedToo many requests arrived too quickly for the token or the application.Back off and retry with exponential backoff, and smooth the request rate.
Versioning & freshness

Version history.

Wave's GraphQL API carries no dated version string in the request. It evolves continuously, with changes communicated through the developer documentation and field-level deprecation notices in the schema.

Version history

What changed, and when

Latest versionGraphQL (unversioned)
GraphQL (unversioned)Current version
Current GraphQL API

Wave's GraphQL API carries no dated version string in the request. The schema evolves continuously, and changes are communicated through the developer documentation and field-level deprecation notices in the schema rather than by minting a new version.

What changed
  • Single GraphQL endpoint for queries and mutations across businesses, customers, invoices, products, accounts, sales taxes, and money transactions.
  • OAuth 2.0 with resource:operation scopes and full access tokens for development.
  • Webhook subscriptions with HMAC-SHA256 signature verification.
2025-05-26Requires migration
Wave Pro required for third-party access

From this date, a business connected through a third-party OAuth integration must maintain an active Wave Pro subscription, and webhook delivery requires it as well.

What changed
  • Third-party OAuth integrations require the connected business to be on Wave Pro.
  • Webhook delivery is limited to businesses with an active Wave Pro subscription.

Track schema deprecation notices and the developer documentation for changes.

Wave developer documentation ↗
Questions

Wave API, answered.

Is the Wave API REST or GraphQL?+
It is GraphQL. There is a single endpoint, and every call is a POST to it. A query reads data and a mutation writes it, and the request body lists exactly the fields the caller wants back, so a response carries no more than what was asked for. This differs from a REST API where each resource has its own URL and verb.
What is the difference between an OAuth token and a full access token?+
An OAuth token comes from the authorization-code flow and represents another Wave user who granted an application scoped access; it is the method for any application published to other users. A full access token is generated in the developer portal and grants unrestricted access to the account that created it, intended for development and for automating the owner's own account, not for connecting to others.
How do scopes work in Wave?+
Scopes follow a resource:operation pattern, such as business:read or invoice:write. Each operation is granted on its own, so write does not imply read, and a token reaches only the resources its scopes name. A request that needs a scope the token lacks returns a 403, and for webhooks, events tied to a scope the user did not grant are simply not delivered.
How are errors reported in a GraphQL API like Wave's?+
Two ways. A problem with the query itself, like an unknown field, comes back in a top-level errors array with an HTTP 200, because the request reached the GraphQL layer. A mutation whose input fails validation reports it inside the response as an inputErrors array of code, message, and path, alongside a didSucceed flag, so a caller checks didSucceed rather than relying on the HTTP status alone.
Does Wave require a paid plan to use the API?+
For third-party access, yes. As of 26 May 2025, a business connected through a third-party OAuth integration must keep an active Wave Pro subscription, and webhook delivery requires it too. A developer automating their own account with a full access token is a separate case from connecting to other users' businesses.
How does an integration receive Wave events without polling?+
Through webhooks. An application registers an HTTPS endpoint and subscribes to events, and Wave POSTs a signed event when something happens in a business, like an invoice being created or a payment received. The receiver verifies the x-wave-signature header, an HMAC-SHA256 of the payload, to confirm the request came from Wave before acting on it.
Related

More finance API guides for agents

What is Bollard AI?

Control what every AI agent can do in Wave.

Bollard AI sits between a team's AI agents and Wave. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.

  • Set read, write, or full access per agent, never a shared full-access token.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
Wave
Bookkeeping Agent
Read invoices ResourceOffReadFull use
Create customers ActionOffReadFull use
Delete invoices ActionOffReadFull use
Per-agent access, set in Bollard AI, not in Wave