Manual journal entries

Create a manual journal entry

Writes a balanced journal entry straight into the books' pipeline, as a draft by default. Requires the manual_journal_entries:write permission.

POST
https://services.magicdoor.com/accounting/company-portal/manual-journal-entries

Authorization

Authorizationstringrequired
Bearer token — Send your API token in the Authorization header as Bearer <token>. Requests without a valid token are rejected with 401 Unauthorized.

Body

application/json

companyBillbooleanrequired

true books the entry against the management company, false against the properties. Setting it to true needs a company that has the company ledger enabled.

example: false
postingDatestring · date-timerequired

The date the entry is booked on, read in the company's timezone.

example: 2026-08-05T00:00:00
linesLine[]required

At least two lines that balance.

descriptionstring

What the entry is for, up to 1000 characters.

statusenum<string>

The state to create the entry in. Setting it to posted here puts the entry into the general ledger immediately, without going through submit, approve and post.

default: draftdraftpendingApprovalapprovedpostedrejected
rejectionReasonstring

Stored as-is, up to 1000 characters. Only meaningful alongside status: "rejected".

Response

200 · The entry that was created.

idstring

Snowflake id of the entry.

createdstring · date-time

When the entry was created, in the company's timezone.

updatedstring · date-time

When the entry was last changed, in the company's timezone.

companyBillboolean

true puts the entry on the management company's own books, false on the property books. It decides which set of reports the entry shows up in — a company entry never appears in a property report and vice versa.

postingDatestring · date-time

The date the entry is booked on, in the company's timezone. Reports include it from this date.

descriptionstring

What the entry is for. Absent when none was set.

statusenum<string>

Where the entry sits in the approval flow. Only posted entries reach the general ledger and the financial reports.

draftpendingApprovalapprovedpostedrejected
rejectionReasonstring

Why the entry was rejected. Cleared when the entry is resubmitted, and absent otherwise.

creatorobject

Who created the entry. Deprecated mirrors of id — propertyManagerId, tenantId, vendorId, ownerId — are also present, whichever matches type.

submittedByUserIdstring

Who was recorded as submitting it for approval. Absent until it is submitted.

submittedAtstring · date-time

When it was submitted, in the company's timezone. Absent until it is submitted.

approvedByUserIdstring

Who was recorded as approving it. Absent until it is approved.

approvedAtstring · date-time

When it was approved, in the company's timezone. Absent until it is approved.

postedByUserIdstring

Who was recorded as posting it. Absent until it is posted.

postedAtstring · date-time

When it was posted, in the company's timezone. Absent until it is posted.

rejectedByUserIdstring

Who was recorded as rejecting it. Absent unless it has been rejected.

rejectedAtstring · date-time

When it was rejected, in the company's timezone. Absent unless it has been rejected.

linesLine[]

The debit and credit lines. There are always at least two, and the debits equal the credits.

chartOfAccountsChartOfAccount[]

The chart-of-account entries every line refers to, resolved so you do not have to look them up.

400 · A field failed validation: fewer than two lines, a line amount outside 0.01–999999999.99, a negative or duplicated `order`, a description over 1000 characters, debits that do not equal credits, or an entry with only debits or only credits.

401 · The access token is missing, expired, or not for this company.

403 · The caller does not hold the `manual_journal_entries:write` permission.

404 · A `chartOfAccountId` or `bankAccountId` names nothing visible to this company.

422 · `companyBill` is `true` for a company that does not have the company ledger enabled.

The entry must balance before it is accepted

Every amount is positive; isDebit decides the side. The sum of the debit lines and the sum of the credit lines must agree to within one cent, there must be at least one line of each kind, and there must be at least two lines in total. Anything else is rejected with a 400 that names Lines.

`status` is not validated against the approval flow

Creating an entry with status: "posted" skips submit, approve and post entirely, and the entry lands in the general ledger and every financial report straight away. Leave status out unless you mean exactly that.