Alya Books

    Developer docs

    REST API, webhooks, MCP server and CLI for UAE e-invoicing

    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), a label (and optional Arabic label), a type (text, number, date, boolean, select with options), a level (head or line), and flags required and showOnPdf.
    • 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

    RoutePurpose
    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}/activateMake a template the active one for its kind

    Scopes: metadata:read, metadata:write. Business users manage the same objects under Settings → Documents → Custom fields.