Skip to main content

Invoice customerMetadata on the public API

Summary

Invoices support custom metadata (key/value pairs) similar to contacts and products:

  • updateInvoiceMetadata — add or update an entry (max key length 40, value 500, up to 50 keys per invoice).
  • deleteInvoiceMetadata — remove an entry by key. If the key does not exist, the mutation returns the invoice unchanged and does not return an error.
  • Invoice.metadata — read entries as [MetadataEntry] (key, value).
  • invoices(filters: …) — optional filters.metadata with a required key and an optional value.

Filter behaviour matches contacts and products:

  • key only — returns invoices that have any value stored for that key.
  • key + value — returns invoices where that key/value pair matches the same entry.

Values are matched after the same sanitisation rules as updateInvoiceMetadata.

This release is additive: existing invoice and invoices calls behave as before. filters is optional; omit it to keep current list behaviour (date range, pagination, and query options only).

Invoice mutation error codes: For updateInvoiceMetadata and deleteInvoiceMetadata, validation failures and missing invoices return HTTP 4xx responses with error populated in the GraphQL payload (for example 400 for validation problems and 404 when the invoice is not found), instead of surfacing only as GraphQL 500 errors. Validation errors include the invalid field name in messages such as invoiceId must be an ObjectId.

Metadata deletes are idempotent: deleteInvoiceMetadata only removes an entry when the key is present. If the key is absent, the mutation completes successfully, returns the invoice unchanged, and leaves error empty. Treat this as "the key is not present after the call" rather than as proof that an entry existed before the call.

Integration guidance

  • Writing metadata: Call updateInvoiceMetadata with invoiceId, key, and value.
  • Removing metadata: Call deleteInvoiceMetadata with invoiceId and key. Missing keys are a successful no-op.
  • Reading metadata: Query invoice(id:) or invoices and request metadata { key value }.
  • Listing by metadata: Use invoices(filters: { metadata: { key: … } }) to match any value for a key, or add value: … for an exact key/value pair. Combine with dateRange, pagination, and options as today.
  • Discovery: Use filters.metadata for metadata-only lookup; do not assume other invoice fields cover custom keys.

Example

query InvoicesByExternalRef {
invoices(
dateRange: { start: "2026-01-01", end: "2026-12-31" }
pagination: { page: 1, pageSize: 50 }
filters: { metadata: { key: "external_ref", value: "INV-42" } }
) {
data {
id
invoiceNumber
metadata {
key
value
}
}
pageInfo {
page
pageSize
hasMore
}
}
}

Migration

No breaking schema changes for existing invoice / invoices clients. If you store partner references only in Semble invoice metadata today, you can now read them via metadata and find invoices with filters.metadata instead of maintaining a separate id map outside Semble.