wave-api
Typed Rust client for the Wave Accounting GraphQL API.
No code generation, no raw GraphQL strings in user code. All connection types are flattened into Page<T> results, monetary values use rust_decimal::Decimal, and mutations use a builder pattern for inputs.
Features
- OAuth2 authentication with automatic token refresh on
UNAUTHENTICATEDerrors - Strongly typed queries, mutations, inputs, and enums
- Pagination — GraphQL connections are flattened into simple
Page<T>results - Decimal precision — all monetary values use
rust_decimal::Decimal - Builder pattern for mutation inputs with optional field skipping
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
use ;
let client = with_oauth;
let businesses = client.list_businesses.await?;
for biz in &businesses.items
API Coverage
Queries
| Resource | Methods |
|---|---|
| User | get_user |
| Business | list_businesses, get_business |
| Customer | list_customers, get_customer |
| Invoice | list_invoices, get_invoice |
| Account | list_accounts, get_account |
| Product | list_products, get_product |
| Vendor | list_vendors, get_vendor |
| Sales Tax | list_sales_taxes, get_sales_tax |
| Constants | list_currencies, list_countries, list_account_types, list_account_subtypes |
Mutations
| Resource | Methods |
|---|---|
| Customer | create_customer, patch_customer, delete_customer |
| Invoice | create_invoice, patch_invoice, delete_invoice, clone_invoice, approve_invoice, send_invoice, mark_invoice_sent |
| Account | create_account, patch_account, archive_account |
| Product | create_product, patch_product, archive_product |
| Sales Tax | create_sales_tax, patch_sales_tax, archive_sales_tax |
| Transaction | create_money_transaction, create_money_transactions |
Examples
Set up a .env file with your Wave OAuth credentials:
WAVE_CLIENT_ID=...
WAVE_CLIENT_SECRET=...
WAVE_ACCESS_TOKEN=...
WAVE_REFRESH_TOKEN=...
WAVE_REDIRECT_URI=http://localhost:3099/callback
WAVE_BUSINESS_ID=...
Then run any of the examples:
# List all businesses
# Create an invoice
# Profit & Loss report
Authentication
wave-api uses OAuth2. You'll need to register an application with Wave to obtain a client ID and secret. See oauth_flow.py for a helper that runs the authorization code flow locally.
When an API call receives an UNAUTHENTICATED error, the client automatically refreshes the access token using the refresh token and retries the request once. You can provide an on_token_refresh callback to persist new tokens:
let client = with_oauth;
Error Handling
All methods return Result<T, WaveError>. The error enum covers:
Http— network / HTTP errorsJson— serialization / deserialization failuresGraphQL— errors returned by the Wave APIMutationFailed— mutationdidSucceed: falsewithinputErrorsAuth— missing or invalid credentialsTokenRefresh— refresh token flow failed
License
MIT