Rebuild Journal Entry
POST/api/ledger/entries/:entry/rebuild
Rebuild the entry's SOURCE document INLINE (single-entry action): the user clicked Rebuild on the entry detail page and expects the regenerated entry to be current the instant the request returns, not after the async drain catches up. The rebuild writes the same updated outbox row a real source mutation rides, then processes JUST that row synchronously through the shared outbox processor (build → persistSet → batch-assign → sync-select) — so posted-immutability (reversal + replacement) holds exactly as on the async path.
Any valid API token can call this endpoint — no specific scope required. Manage tokens.
Two cases fall back to the queue instead of running inline (the message says which):
- Batch-aggregate entries (source = a LedgerBatch) ride the batch state machine (markDirty + a background job) — identical effect to POST /api/ledger/batches/{batch}/rebuild.
- Generation disabled (the
ledger.generation_enabledkill-switch is off): theupdatedrow is parked for whenever the drain next runs.
Authentication: Requires Bearer token.
Request body: none.
Response: 200 with a message. When the rebuild ran inline the message is "Entry rebuilt from its source document."; on the queued fallback it is "Rebuild queued — the entry will regenerate from its source document shortly." (App\Response normalizes every 2xx to 200.) Returns 404 when the entry does not exist.
Permission: requires accounting.sync (granular permissions; admins bypass; unenforced when the tenant's granular_permissions feature flag is off). Returns 403 without it.
Request
Responses
- 200
- 401
- 403
- 404
- 422
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Not found — no record with the given identifier (or the route does not exist). Verify the ID before retrying.
Validation failed — the body is a field → messages map (Laravel shape) or the platform envelope with a stable machine-readable code. Fix the payload and resubmit.
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.