POST
/api/public/v1/transactionsRecord a transaction
Writes to the ledger. Send a **positive** `amount` in cents — the `type` decides the sign, so an expense is stored negative without the caller having to know that. The write posts the double-entry journal for it and re-runs the tax liability that depends on it, so the books and the liability never disagree with the ledger. Raise something not yet settled with `status: "PENDING"` and a `dueDate`; it then appears in payables until you mark it paid.
Required scope
The access token must carry this scope. A token missing it gets 403 Forbidden. Grant them to an API client under Settings → Company → API, and to a teammate under Employee → Permissions.
transactions:write
Request Body
| Property | Type | Description |
|---|---|---|
type | string | EXPENSE, DEDUCTION and TAX_PAYMENT are stored negative; the rest positive. |
amount | number | Cents, positive. At least 1. |
description | string | What it was for. |
date | string | ISO 8601. |
status | string | PENDING for something not yet settled; defaults to confirmed. |
dueDate | string | ISO 8601. |
notes | string | |
locationId | string | Attribute to a location. |
legalEntityId | string | Attribute to an entity. |
irsCategory | string | Drives how it lands in the tax figures. |
taxYear | number | |
taxQuarter | number | 1–4. |
counterpartyName | string | |
counterpartyEmail | string |
POSTExample request
curl
curl -X POST "https://www.pxb.app/api/public/v1/transactions" \
-H "Authorization: Bearer your_access_token" \
-H "Content-Type: application/json" \
-d '{
"type": "EXPENSE",
"amount": 48000,
"description": "Q3 hosting",
"date": "2026-08-01T00:00:00.000Z",
"status": "PENDING",
"dueDate": "2026-09-01T00:00:00.000Z",
"irsCategory": "Utilities"
}'200Example response
json
{
"message": "Transaction created!",
"content": {
"transaction": {
"id": "txn_4410",
"type": "EXPENSE",
"status": "PENDING",
"amount": -48000,
"description": "Q3 hosting",
"counterpartyName": "Cloud Co",
"irsCategory": "Utilities",
"date": "2026-08-01T00:00:00.000Z",
"dueDate": "2026-09-01T00:00:00.000Z",
"legalEntityId": "le_7788",
"createdAt": "2026-08-01T09:00:00.000Z",
"updatedAt": "2026-08-01T09:00:00.000Z"
}
}
}In the console
The same thing done by hand, for anyone comparing the API against the screen they already use.