Skip to content

Create & Book Invoice

Issuing an invoice is two stages: create it (status CREATED), then activate it. Activation posts the invoice into the ledger and is what “booked” means - the invoice reaches status ACTIVATED with a bookedDate. Factoring adds a credit-decision step on top of the same path.

POST /invoices takes the structured createInvoice object (nested debtor, dates, articleRows, currency), not a flat amount. Required right: CreateInvoices. There is also a machine-to-machine variant, POST /invoices/integration (permission invoice:create), for token-based integrations.

FieldRequiredNotes
invoiceNumberyesYour invoice number.
articleRowsyesList of line items (see below).
debtoryesNested debtor object (see below). The debtor is matched/created automatically - no separate debtor call.
datesyesNested object with invoiceDate and expireDate.
clientIdconditionalTop-level. Required with a system token (scopes the invoice to a client). Omit it with a client token - it is taken from the token.
currencynoNested object; see Currency below. Defaults to the tenant’s configured currency.
typenoINVOICE, CREDIT_INVOICE, etc. Defaults to a standard invoice.
serviceProviderCodenoWhich installed service provider administers the invoice.

productCode is not set here - it is chosen at activation (step 2).

FieldRequiredNotes
customerNumberyesYour customer number for the debtor. This is the matching key - Quiddly maps it to an existing debtor or creates one.
nameyesPerson or company name.
typeyesCOMPANY or PERSON.
identificationNumbernoOrg/SSN. Recommended; improves matching and is needed for collection.
email, phone, invoiceAddress, deliveryAddress, peppolId, …noContact and routing details.
FieldRequired
invoiceDateyes
expireDateyes
deliveryDateno

The list is required. Individual rows have no single mandatory field - send the ones you have (description, quantity, unit, price, vatPercentage, articleNumber, accountNumber, …). Alternatively set articleRowsGenerate: true to let Quiddly compute the rows/totals from the invoice data.

Currency is set inside the nested currency object, not at the top level:

"currency": { "invoiceCurrency": "SEK", "baseCurrency": "SEK" }

invoiceCurrency is what the PDF shows; baseCurrency (optional) is the currency the invoice is handled in. If no baseCurrency is sent Quiddly defaults to the system currency. baseCurrency will decide which client account it will be handled in. Totals (totals) and VAT breakdown (vats) are normally derived by Quiddly - you do not have to send them.

The response marshals the created invoice; the main status surfaces under statuses.main (and ledger progress under statuses.ledger).

statuses.mainWhen
CREATEDFreshly created, not yet activated.
PENDING_AUTHORIZATIONHeld for authorization before activation (tenant-dependent).
PENDINGActivation accepted, queued.
ACTIVATINGActivation running (documents, ledger, financial events).
ACTIVATEDBooked. bookedDate is set.
DENIED_FINANCINGFactoring decision denied.
PAUSED / DISPUTED / STOPPED / CLOSED / ARCHIVEDLater lifecycle states.
CREATED ──activate──> PENDING ──> ACTIVATING ──> ACTIVATED (booked)
request factoring + decision
├── approved ─> ACTIVATED (financed, product INVOICE_FACTORING_SELL)
└── denied ──> DENIED_FINANCING
  1. Create the invoice.

    Terminal window
    curl -X POST "https://$HOST/invoices" \
    -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \
    -d '{
    "clientId": "C.100100",
    "invoiceNumber": "2026-0001",
    "debtor": {
    "customerNumber": "CUST-42",
    "name": "Acme AB",
    "type": "COMPANY",
    "identificationNumber": "5560000001"
    },
    "dates": { "invoiceDate": "2026-06-01", "expireDate": "2026-06-30" },
    "currency": { "invoiceCurrency": "SEK" },
    "articleRows": [
    { "description": "Consulting", "quantity": "1", "unit": "h", "price": "1250.00", "vatPercentage": 25 }
    ]
    }'

    Returns the created invoice with statuses.main = CREATED. Omit clientId if you authenticate with a client token. Add ?returnResource=false to get just { "id": "I...." } back.

  2. Activate it. Requires ActivateInvoices. Choose the product here - INVOICE_SERVICE for a plain service invoice.

    Terminal window
    curl -X PUT "https://$HOST/invoices/$INVOICE_ID/activate" \
    -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \
    -d '{ "productCode": "INVOICE_SERVICE" }'

    The call returns quickly with PENDING; activation finishes asynchronously (document generation, ledger and financial events) and the invoice lands on ACTIVATED with bookedDate set. Subscribe to the INVOICE / INVOICE_BALANCE webhooks instead of polling.

  3. (Factoring only) Request factoring on the activated service invoice.

    Terminal window
    curl -X PUT "https://$HOST/factoring-decisions/$INVOICE_ID/factoring" \
    -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" -d '{}'

    Requires UpdateCreditDecisionStatus. Guards: the invoice must be ACTIVATED and product INVOICE_SERVICE, and the debtor must not be blocked for factoring. See the factoring decision flow below.

The credit decision is tracked by a credit-decision status separate from the invoice main status. Values: PENDING, READY_FOR_DECISION, WAITING, REFINANCE, DECIDED (plus tenant-specific groupings/sub-statuses).

Quiddly distinguishes internal decisions (made inside Quiddly, by the engine rule or an operator) from external decisions (made by an external financing provider):

ActionEndpointRightUse
Request factoringPUT /factoring-decisions/<invoiceId>/factoringUpdateCreditDecisionStatusAsk to factor an activated service invoice.
Move internal decisionPUT /factoring-decisions/<id>/moveUpdateCreditDecisionStatusAdvance the internal credit-decision status (+ optional sub-status grouping).
Record external decisionPUT /factoring-decisions/<id>/move-externalUpdateExternalFactoringDecisionRecord an external provider’s decision: APPROVED, DENIED, or DENIED_SERVICE.

The decision resolves to one of FinanceDecision = APPROVED, DENIED, DENIED_SERVICE, REFINANCE:

  • Approved: the product switches to INVOICE_FACTORING_SELL, financed financial events are generated, the invoice is re-booked as financed, and the credit-decision status becomes DECIDED. The invoice stays ACTIVATED.
  • Denied: main status becomes DENIED_FINANCING.

Track the decision with GET /factoring-decisions/invoice/<id> and the FACTORING_STATUS webhook.