Metadata
Metadata is a map of string keys to string values you attach to a record for your own purposes: an id in your CRM or ERP, a segment, an owner, a flag your integration reads. LedgerBee stores the map with the record, returns it on every read, and lets you filter list endpoints on it. LedgerBee does not interpret the values.
The map
Code
| Limit | Value |
|---|---|
| Entries per record | 50 |
| Key length | 128 characters |
| Value length | 500 characters |
| Filter pairs per list request | 10 |
Keys are trimmed before they are stored, and a key must not be empty after
trimming. Keys are compared case-insensitively: Tier and tier are the same
key, and a request that carries both is rejected with METADATA_DUPLICATE_KEY.
Values are stored as sent, including an empty string.
Where metadata is available
| Resource | Write | Read | Filter |
|---|---|---|---|
| Customers | POST /v1/customers, PATCH /v1/customers/{id} | GET /v1/customers, GET /v1/customers/{id} | GET /v1/customers |
| Customer groups | In the LedgerBee app | GET /v1/customers/groups | GET /v1/customers/groups |
| Suppliers | POST /v1/suppliers | GET /v1/suppliers | GET /v1/suppliers |
| Vendors (deprecated alias of suppliers) | POST /v1/vendors | GET /v1/vendors | GET /v1/vendors |
| Products | POST /v1/products, PATCH /v1/products/{id} | GET /v1/products, GET /v1/products/{id} | GET /v1/products |
Reads and filters use the resource's read scope (customers-read,
suppliers-read, products-read); writes use its write scope
(customers-write, suppliers-write, products-write). See the
API Reference for each operation.
Suppliers and vendors are the same records under two route families, so
metadata written through one is returned by the other, under the same
metadata field name. Supplier metadata is also editable in the LedgerBee app.
A customer group's metadata is set in the LedgerBee app and is read-only over
the API. A key holding only the checkout scope receives each group slimmed to
id, number, and name; the metadata requires customers-read.
Writing metadata
Send metadata on a create request to store the map with the new record.
Code
The map is validated before the record is created, so an invalid map is
rejected and no record exists. The key __proto__ is reserved and cannot be
written. The create responses for customers, suppliers
and vendors carry only the new record's id and number; read the metadata back
through the single-record or list endpoint. The product create response carries
the map.
On an update, metadata replaces the stored map wholesale. Send the complete
map you want to end up with; a key you leave out is removed. An empty object
clears every entry. Omit the field to leave the metadata unchanged.
Code
To change one key, read the current map, change the key, and send the whole map back.
Reading metadata
Every response that returns the full record carries its metadata map: the
single-record read, the product create and update responses, and the customer
update response. List endpoints return it on each item, so a sync can read the
map without a per-record request. A record with no metadata returns {}. The
customer, supplier and vendor create responses return only the id and number,
so read the record afterwards for its map.
Filtering a list
Pass one or more metadata[key]=value query parameters to a list endpoint. A
record matches only when its metadata carries every given key with exactly the
given value: matching is exact on both key and value, and several pairs combine
with AND. At most 10 pairs per request; more returns 400
METADATA_TOO_MANY_FILTERS.
Code
On GET /v1/products the filter composes with search and productGroupId,
and total counts the filtered set. On GET /v1/customers it composes with
customerNumber, externalSystemId, and parentCustomerId.
The unfiltered customer, customer group, supplier, and vendor lists are cached for 5 seconds. A filtered list is never cached, so a metadata write is visible on the next filtered read. The product list is not cached.
Lifecycle
Archiving a product keeps its metadata, and the archive response carries it. Deleting a product deletes its metadata with it. A customer or supplier deleted in the LedgerBee app loses its metadata the same way.
Errors
| Condition | Error code | Fix |
|---|---|---|
| A key is empty after trimming | METADATA_KEY_REQUIRED | Give every entry a non-empty key. |
| A key is longer than 128 characters | METADATA_KEY_TOO_LONG | Shorten the key. |
| A value is longer than 500 characters | METADATA_VALUE_TOO_LONG | Shorten the value, or store a reference to it. |
| More than 50 entries | METADATA_TOO_MANY_ENTRIES | Keep the map to 50 entries. |
| Two keys are the same after trimming and case-folding | METADATA_DUPLICATE_KEY | Send each key once. |
More than 10 metadata[key] pairs on a list request | METADATA_TOO_MANY_FILTERS | Filter on at most 10 pairs and narrow further client-side. |
A __proto__ key in a create or update metadata map, or a metadata[__proto__] filter pair | METADATA_KEY_RESERVED | Use another key; this one cannot be a property of a JSON object. |
All are returned as 400 in the error envelope described in Errors.