REST API: POST /journals stores credit_amount as a debit
Summary
POST /journals on the REST API (https://api-beta.quickfile.co.uk) accepts a
journal line carrying credit_amount, validates that field, and then writes the
value to the debit column. There appears to be no way to create a credit line
through this endpoint.
Because the endpoint does not reject an unbalanced journal, a two-line journal
posts “successfully” with both lines as debits and no error, warning, or non-2xx
response. The result is silently incorrect accounting data.
Expected vs actual
Posting a line with credit_amount: 39.96:
credit |
debit |
|
|---|---|---|
| Expected | 39.96 |
null |
| Actual | null |
39.96 |
Minimal reproduction
POST https://api-beta.quickfile.co.uk/journals
Authorization: Bearer <token with 'journals' permission>
Content-Type: application/json
{
"date": "2026-08-31",
"name": "credit test",
"lines": [
{ "nominal_code": 7400, "description": "probe debit", "debit_amount": 0.01 },
{ "nominal_code": 1201, "description": "probe credit", "credit_amount": 0.01 }
]
}
Returns 200 OK with a reference. Reading it straight back with
GET /journals/{reference} gives:
{
"lines": [
{ "nominal_code": 7400, "description": "probe debit", "credit": null, "debit": 0.01 },
{ "nominal_code": 1201, "description": "probe credit", "credit": null, "debit": 0.01 }
]
}
Both lines are debits. The journal totals 0.02 debit against 0.00 credit and was
accepted without complaint.
Control: the storage model is fine
Creating the equivalent journal in the web UI, then reading it via
GET /journals/{reference}, returns exactly what’s expected:
{ "nominal_code": 1201, "description": "...", "credit": 39.96, "debit": null }
So credit is representable and the read endpoint reports it correctly. The
defect is isolated to the create endpoint’s handling of credit_amount.
Encodings tested
Every accepted variant produced a debit. The validation messages show the field
is being parsed — it is validated and then written to the wrong column.
| Line sent | Result |
|---|---|
credit_amount: 0.01 |
200 — stored as debit 0.01 |
credit_amount: "0.01" (string) |
200 — stored as debit 0.01 |
| Credit line placed before the debit line | 200 — stored as debit 0.01 |
| Single credit line, no debit line at all | 200 — stored as debit 0.01 |
debit_amount: -0.01 |
400 — “Either debit_amount or credit_amount must be supplied and greater than zero.” |
credit_amount: -0.01 |
400 — same message |
debit_amount: 0.0 + credit_amount: 0.01 |
400 — “debit_amount must be greater than zero.” |
debit_amount: 0.01 + credit_amount: 0.01 |
400 — “Only one of debit_amount or credit_amount may be supplied.” |
Impact
Any integration posting journals through the REST API produces one-sided
entries. The two conditions compound: credits silently become debits, and
unbalanced journals are accepted without error, so nothing surfaces the problem
at post time. It is only visible by reading the journal back or opening it in the
UI.
This blocks the common case of a journal with expense debits against a balancing
credit — expense claims, director’s loan postings, accruals, and similar.
Suggested fixes
- Write
credit_amountto the credit column. - Separately, consider rejecting journals whose debits and credits don’t balance
— that would have surfaced this immediately rather than silently.
Environment
- Endpoint:
https://api-beta.quickfile.co.uk/journals - Auth: personal API token,
journalspermission,Authorization: Bearer <token> - Schema reference:
https://api-beta.quickfile.co.uk/api-docs/v2,
definitionJournalCreateLine, which documentsdebit_amountand
credit_amountas independent optional numbers - Observed: August 2026
Account number and the affected journal references can be supplied privately on
request. All journals created during testing were deleted afterwards via
DELETE /journals/{reference}, which worked correctly.