ml-connector
Wave AccountingAvidXchange

Wave Accounting and AvidXchange integration

Wave Accounting keeps the books, the chart of accounts, and the vendor list. AvidXchange receives, codes, approves, and pays supplier bills. Connecting the two lets AP staff code invoices in AvidXchange against the same GL accounts and vendors that live in Wave, and lets the payments AvidXchange executes flow back into Wave as journal entries without re-keying. ml-connector handles the very different APIs on each side and moves the data on a schedule you control.

How Wave Accounting works

Wave Accounting exposes all accounting data through a single GraphQL endpoint at gql.waveapps.com, where reads are queries and writes are mutations. It authenticates with the OAuth2 authorization code flow, issuing access tokens that expire in about two hours plus a refresh token when offline_access is granted, and every query is scoped to a business ID fetched right after authorization. Key entities are the chart of accounts, vendors, customers, invoices, products, and money transactions, the last created with a caller-supplied externalId for dedup. Wave has no purchase order object and no structured AP bill workflow, and it offers webhooks only for its own invoice, customer, and transaction events, so the connector reads reference data by polling.

How AvidXchange works

AvidXchange exposes accounts payable through the AvidConnect REST API, behind a WSO2 gateway. The self-service Customer Token API authenticates with an opaque Company Token and User Token generated by an admin inside AvidSuite, while the partner tier uses client credentials. It syncs vendors, invoices and bills, purchase orders, and GL codes, and reads settled payment detail such as check number, ACH trace, or virtual card back to the accounting system. AvidXchange publishes no webhooks, so payment status and batch results are retrieved by scheduled polling. Invoice approval routing and supplier payment preferences stay inside AvidXchange and are not configured through the API.

What moves between them

Reference data moves from Wave Accounting into AvidXchange. The connector pushes the Wave chart of accounts as GL codes and the Wave vendor list as payees, so bills in AvidXchange can be coded and routed to suppliers that already exist. Vendors must land in AvidXchange before any bill referencing them is paid. Settled payments move the other way: after AvidXchange executes a payment, the connector reads the payment detail and writes it into Wave as a money transaction against the right cash and expense accounts. Wave invoices are customer-facing receivables and are not sent to AvidXchange. Both directions run on a schedule, since neither side pushes events for this pair.

How ml-connector handles it

ml-connector stores both credential sets encrypted, sends the Wave OAuth2 bearer token on every GraphQL call, and refreshes it proactively before the roughly two-hour expiry so a sync never fails mid-run. It fetches the Wave business ID first, since every query and mutation requires it, and sends the AvidXchange Company and User tokens as headers on each REST request. Wave GL accounts map to AvidXchange GL codes and Wave vendors map to AvidXchange payees, and those are aligned first so every coded bill references a code and supplier that exist. Each settled AvidXchange payment is written into Wave with the moneyTransactionCreate mutation using a stable externalId derived from the payment, so a retry never creates a duplicate journal entry. Because AvidXchange has no webhooks and Wave does not push AP events, payment status is polled on a schedule. GraphQL returns errors with an HTTP 200, so the connector checks the errors array on every Wave response, and it backs off on Wave rate-limit responses. The connected Wave business must hold an active Wave Pro subscription for third-party API access, and every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A growing property management firm with about 60 staff runs Wave Accounting for its books and pays a high volume of vendor bills, from maintenance contractors to utilities, across several buildings. Before the integration, an AP clerk keyed each bill into AvidXchange by hand, hunted for the right GL account, and then re-entered every completed payment back into Wave at month-end, where mismatched account codes regularly broke the reconciliation. With Wave Accounting and AvidXchange connected, the Wave chart of accounts and vendor list feed AvidXchange so bills are coded against valid accounts and routed to known suppliers, and each payment AvidXchange settles posts back into Wave as a journal entry automatically. The clerk stops double-entering, and the cash and expense accounts already tie out when close begins.

What you can do

  • Push the Wave Accounting chart of accounts into AvidXchange as GL codes for invoice coding.
  • Push the Wave Accounting vendor list into AvidXchange as payees so bills route to known suppliers.
  • Write settled AvidXchange payments back into Wave as journal entries using an externalId so retries never double-post.
  • Bridge Wave's OAuth2 bearer token and AvidXchange's Company and User tokens, refreshing Wave tokens before expiry.
  • Poll AvidXchange for payment status on a schedule, with retries and a full audit trail on every record.

Questions

Which direction does data move between Wave Accounting and AvidXchange?
GL accounts and vendors move from Wave Accounting into AvidXchange so bills can be coded and routed to the right suppliers. Settled payments move the other way, posting back into Wave as journal entries once AvidXchange executes them. Wave invoices are customer receivables and are not sent to AvidXchange.
Does Wave Accounting send AP bills or purchase orders to AvidXchange?
No. Wave has no purchase order object and no structured AP bill workflow in its API, so bills are created and approved inside AvidXchange. What Wave provides is the chart of accounts and vendor list that AvidXchange uses to code those bills, and the journal entries where the resulting payments are recorded.
How are payments recorded in Wave without creating duplicates?
AvidXchange has no webhooks, so the connector polls it on a schedule for settled payments. Each payment is written into Wave with the moneyTransactionCreate mutation, and a stable externalId derived from the payment is set as a dedup key, so re-running a poll or retrying a failed write never posts the same payment twice.

Related integrations

Connect Wave Accounting and AvidXchange

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started