REST API: POST /journals stores credit_amount as a debit

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

  1. Write credit_amount to the credit column.
  2. 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, journals permission, Authorization: Bearer <token>
  • Schema reference: https://api-beta.quickfile.co.uk/api-docs/v2,
    definition JournalCreateLine, which documents debit_amount and
    credit_amount as 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.

Hi @EndreC

Thank you bringing this to our attention. I’ve made our developers aware of the issue, who will now investigate and resolve this.

As soon as we have an update on this, we’ll update you here.

1 Like

I have just had this problem too and was about to submit a bug report.

Thanks,

Julian