Record expenses and receipts

Capture operational spend, attach receipt files, and post expenses to the ledger with the right account and dimensions.

Record expenses and receipts

Use expenses for purchases paid at the time of the transaction—for example card spend, petty cash, and employee-paid operating costs. Use bills when the supplier must be paid later.

Prepare the accounting context

Resolve these IDs before creating the expense:

  • account: where the expense appears in the chart of accounts.
  • paid_through_account: the bank, card, cash, or clearing account used to pay.
  • tax_rate: the tax treatment, when applicable.
  • contact: the merchant or supplier, when useful.
  • project, cost_center, and branch: optional reporting dimensions.

Use List accounts with is_payment_enabled=true to find eligible payment accounts.

Upload receipt files

Create the supporting document with Create file, then place the returned file ID in the expense attachments array. Keep the original filename and source-system reference so finance users can trace the evidence.

See Work with files and attachments for multipart and raw uploads, file metadata, later updates, and safe deletion.

Create the expense

curl --request POST "https://api.wafeq.com/v1/expenses/" \
  --header "Authorization: Api-Key <API_KEY>" \
  --header "Content-Type: application/json" \
  --header "X-Wafeq-Idempotency-Key: expense-<SOURCE_ID>" \
  --data '{
    "account": "<EXPENSE_ACCOUNT_ID>",
    "paid_through_account": "<CARD_OR_CASH_ACCOUNT_ID>",
    "amount": 315,
    "currency": "AED",
    "date": "2026-08-29",
    "description": "Team travel",
    "reference": "TRIP-882",
    "external_id": "expense_882",
    "tax_amount_type": "TAX_INCLUSIVE",
    "tax_rate": "<TAX_RATE_ID>",
    "contact": "<MERCHANT_CONTACT_ID>",
    "project": "<PROJECT_ID>",
    "cost_center": "<COST_CENTER_ID>",
    "attachments": ["<FILE_ID>"]
  }'

The returned status shows whether the expense is a draft or has posted to the ledger.

Draft and posted states

Use Mark expense as posted when review is complete:

curl --request POST "https://api.wafeq.com/v1/expenses/<EXPENSE_ID>/mark-as-posted/" \
  --header "Authorization: Api-Key <API_KEY>" \
  --header "Content-Type: application/json"

Use Mark expense as draft only when the accounting workflow permits the record to return to draft.

Avoid duplicate spend

Use both controls:

  • external_id maps the Wafeq expense to the durable ID in your source system.
  • X-Wafeq-Idempotency-Key makes retries of the same create request safe.

Do not generate a new idempotency key when retrying a timed-out request for the same expense.

Expense or bill?

SituationRecord
Paid immediately by card, cash, or clearing accountExpense
Supplier invoice is due laterBill
Procurement approval precedes the supplier invoicePurchase order, then bill

For payable workflows, continue with Purchase to pay.


Did this page help you?