Recurring invoice generation uses a selector input that identifies a client and an execution window. In practice, the workflow is preview first, generate second, and then optionally finalize and send the invoice.
Both preview and generate use the same high-level body: a top-level selector_input object with clientId, windowStart, windowEnd, and an executionWindow object. The current schema expects the top-level and nested window values to stay aligned.
{
"selector_input": {
"clientId": "$CLIENT_ID",
"windowStart": "2026-04-01",
"windowEnd": "2026-04-30",
"executionWindow": {
"kind": "client_cadence_window",
"identityKey": "client:$CLIENT_ID:2026-04-01:2026-04-30",
"cadenceOwner": "client",
"clientId": "$CLIENT_ID",
"windowStart": "2026-04-01",
"windowEnd": "2026-04-30"
}
}
}curl -X POST "https://algapsa.com/api/v1/invoices/preview" \
-H "Content-Type: application/json" \
-H "X-API-Key: $ALGA_API_KEY" \
-d @preview-request.jsoncurl -X POST "https://algapsa.com/api/v1/invoices/generate" \
-H "Content-Type: application/json" \
-H "X-API-Key: $ALGA_API_KEY" \
-d @preview-request.json
curl -X POST "https://algapsa.com/api/v1/invoices/$INVOICE_ID/finalize" \
-H "Content-Type: application/json" \
-H "X-API-Key: $ALGA_API_KEY" \
-d '{"finalized_at": "2026-04-19"}'
curl -X POST "https://algapsa.com/api/v1/invoices/$INVOICE_ID/send" \
-H "Content-Type: application/json" \
-H "X-API-Key: $ALGA_API_KEY" \
-d '{
"email_addresses": ["billing@example.com"],
"subject": "April invoice",
"message": "Please find the invoice attached.",
"include_pdf": true
}'