GET the entity you intend to update and capture both its 'Id' and 'SyncToken' from the response
Construct a POST body containing only the fields you wish to change, plus the required 'Id', 'SyncToken', and 'sparse': true flag
POST to /v3/company/{realmId}/{entityType} (e.g., /invoice) — for sparse update, QBO updates only the supplied fields and leaves others unchanged
If you omit 'sparse': true, QBO treats the request as a full replace and may null out fields you did not include
Handle 400 responses with fault code 'PMT-5006' or similar; re-read the entity to get the current SyncToken and retry
After a successful update, the response contains the new SyncToken; store it if you plan to update the same record again in the same session
Known gotchas
SyncToken is a string, not an integer, even when it looks numeric; send it as a JSON string to avoid type coercion issues
Sparse updates on transaction lines (e.g., Invoice.Line) are not truly sparse at the line level — if you send a Line array it replaces the entire line collection; include all lines you want to retain
Concurrent updates from different OAuth clients to the same entity will cause a SyncToken mismatch; design integrations to serialize writes to the same entity or implement retry with re-read
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp