Alya Books

    Developer docs

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

    Recurring invoices

    Templates with a schedule that generate invoices through the same path as POST /invoices.

    A recurring invoice is an invoice template plus a schedule and automation flags. The daily jobs (02:00 and 18:45 UAE time) turn due templates into invoices; each generated invoice goes through the normal creation path (PINT AE validation, number allocation, optional submission and email), so everything documented for outgoing invoices applies.

    Create and activate

    curl -X POST "$BASE/recurring-invoices" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" -d '{
      "name": "Monthly retainer – Buyer LLC",
      "buyer": { "id": "…" },
      "items": [{ "description": "Retainer", "quantity": 1, "unitPrice": 5000, "unitCode": "MON" }],
      "subject": "Monthly retainer",
      "payment": { "termsDays": 14 },
      "projectId": "…",
      "schedule": { "frequency": "monthly", "dayOfMonth": 1, "startDate": "2027-01-01", "periodOffset": -1, "periodTextTemplate": "for {{periodMonth}} {{periodYear}}" },
      "automation": { "validate": true, "submit": true, "send": true, "sendTo": ["ap@buyer.ae"] },
      "status": "active"
    }'
    

    Templates are created as draft unless status: "active" is given. POST /recurring-invoices/{id}/activate, /pause and /cancel change the status; PATCH edits the template (items replaces all lines; schedule changes recompute nextRunOn).

    Schedule

    FieldMeaning
    frequencyweekly, monthly, quarterly, half_yearly, yearly, custom
    intervalCountEvery N periods (default 1)
    dayOfMonth1–31, or 0 for the last day; clamped in shorter months
    weekdayISO weekday 1 (Monday) to 7 (Sunday), weekly only
    customDatesExplicit dates for custom
    startDate, endDate, maxOccurrencesBounds; the template becomes completed when they are reached
    periodOffsetBilled period relative to the run: -1 previous (in arrears), 0 current, 1 next (in advance)
    issueDateOffsetDaysIssue date = run date + offset
    fillInvoicingPeriodWrite the billed period into BT-73/BT-74 (default true)
    periodTextTemplateAppended to the subject; tokens {{periodStart}}, {{periodEnd}}, {{periodMonth}}, {{periodYear}}, {{runDate}}, {{n}}

    GET /recurring-invoices/{id}/preview returns the next occurrences with their periods and the exact POST /invoices payload of the next run. The MCP resource einvoicing://reference/recurring-schedules documents the same fields.

    Runs

    • The daily jobs process templates whose nextRunOn is today or earlier, at most twelve catch-up occurrences per template.
    • POST /recurring-invoices/{id}/run (body { "date": "YYYY-MM-DD" } optional) generates now and returns 201 with invoiceId, or 422 with the error.
    • GET /recurring-invoices/{id}/runs lists runs (success, failed, skipped) with the invoice id and number. One invoice per template and date is guaranteed; failed runs are retried at the next run.
    • Generated invoices carry recurringInvoiceId and externalId: "recurring:<templateId>:<date>"; filter with GET /invoices?recurringInvoiceId=.
    • POST /invoices/{id}/make-recurring copies an existing invoice into a draft template.

    Webhooks and MCP

    Events recurring_invoice.generated (with invoiceId, nextRunOn) and recurring_invoice.failed (with error). MCP tools: list_recurring_invoices, get_recurring_invoice, create_recurring_invoice, update_recurring_invoice, activate_recurring_invoice, pause_recurring_invoice, cancel_recurring_invoice, run_recurring_invoice_now, list_recurring_runs, preview_recurring_invoice, make_invoice_recurring, delete_recurring_invoice.