Custom fields
Metadata templates: define your own fields on documents and lines, validate them, print them, and get them back in webhooks.
Custom fields let you carry information Alya Books does not model itself (purchase order numbers, cost codes, project phases, sales representatives) on invoices, quotes, order confirmations, proformas and incoming invoices, at document ("head") level and per line.
Concepts
- A field has a
key(lowercase letters, digits, underscores; used in the API), alabel(and optional Arabic label), atype(text,number,date,boolean,selectwith options), alevel(headorline), and flagsrequiredandshowOnPdf. - A template groups fields for one
documentKind(invoice,credit_note,debit_note,proforma,quote,order_confirmation,incoming_invoice). Exactly one template per kind can be active. - Values travel as
metadata: { key: value }on the document and on each line, are validated against the active template when created through the API or the editor, and are returned on every read and in webhook payloads.
Define fields and a template
curl -X POST "$BASE/metadata/fields" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
-d '{ "label": "PO number", "type": "text", "level": "head", "required": true, "showOnPdf": true }'
# → { "id": "f1…", "key": "po_number", … }
curl -X POST "$BASE/metadata/fields" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
-d '{ "label": "Cost code", "type": "select", "level": "line", "options": [{ "value": "OPS", "label": "Operations" }, { "value": "RND", "label": "R&D" }] }'
# → { "id": "f2…", "key": "cost_code", … }
curl -X POST "$BASE/metadata/templates" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
-d '{ "name": "Standard", "documentKind": "invoice", "fieldIds": ["f1…", "f2…"], "isActive": true }'
Use them
{
"invoices": [{
"buyer": { "id": "…" },
"metadata": { "po_number": "PO-4711" },
"items": [{ "description": "Consulting", "quantity": 10, "unitPrice": 500, "metadata": { "cost_code": "OPS" } }]
}]
}
Validation errors come back as E_VALIDATION with field: "metadata" (or items[i].metadata) and extra.fields[] naming the offending keys. Values are coerced: numbers from strings, yes/no to booleans, YYYYMMDD to YYYY-MM-DD. Unknown keys are kept as-is, so you can attach data that is not part of the template.
Head-level values on issued invoices can still be changed with PATCH /invoices/{id} (mergeMetadata defaults to true), because they are not part of the reported document. Fields flagged showOnPdf print under "Additional information" on the PDF.
Routes
| Route | Purpose |
|---|---|
GET/POST /metadata/fields, GET/PATCH/DELETE /metadata/fields/{id} | Field definitions |
GET/POST /metadata/templates, GET/PATCH/DELETE /metadata/templates/{id} | Templates with their fields |
POST /metadata/templates/{id}/activate | Make a template the active one for its kind |
Scopes: metadata:read, metadata:write. Business users manage the same objects under Settings → Documents → Custom fields.