Fetch Latest From Provider
POST/api/ledger/entries/:entry/fetch-remote
The inbound mirror of "Sync Now" (— two-way sync, on demand): instead of PUSHING local changes out, it re-reads this entry's remote document(s) FROM the accounting provider (Xero / QuickBooks) and re-grades the sync link RIGHT NOW. For each supported, still-linked connection it fetches the current remote truth via the same InboundChangeProcessor funnel the webhook + nightly sweep use — picking up drift (→ linked_conflict), a void/delete (→ remote_gone), a settled/paid lock (→ remote_locked), or a previously settled lock that has re-opened for edits — the paying payment / credit note was reversed at the provider, e.g. Xero PAID → AUTHORISED — which un-parks the link (→ linked_stale) so it is ready to resync — and refreshes last_remote_seen_at. A 404 at the provider degrades to a synthetic-deleted snapshot so the link still parks remote_gone rather than silently staying Synced.
Any valid API token can call this endpoint — no specific scope required. Manage tokens.
Runs synchronously (the response reflects the re-read); the bulk equivalent is the fetch_remote action on POST /api/ledger/entries/bulk, which runs the same per-entry work as a tracked job.
Deferral: if a push for this entry is in flight, the funnel writes NOTHING (touching the link would erase the drift signals reconciliation needs) and the response carries data.fetch.deferred: true with a "try again once the in-flight sync settles" message — still HTTP 200.
Authentication: Requires Bearer token + accounting.sync permission (403 without it).
Request body: none.
Response: 200 with data.fetch ({ checked, not_linked, deferred, primary, outcomes }) and data.entry (the refreshed ledger entry object so the new link state renders without a second round-trip). data.fetch.primary is the most-notable settled outcome across the re-read links by severity (remote_gone > remote_locked > conflict > remote_reopened > current), or null when nothing was re-read. message explains the outcome. Returns 502 Bad Gateway when the provider read itself fails (e.g. expired auth / network) — no link state is changed. Returns 404 when the entry does not exist.
When the provider has settled the bill with a credit note that SKU has not mirrored as a vendor-credit allocation, the response reports data.fetch.unreflected_credit = true and lists the affected notes in data.fetch.unreflected_credit_notes (each with credit_note_number, applied_amount and shortfall), and message explains that a matching vendor credit must be created or allocated to reconcile the bill.
Request
Responses
- 200
- 401
- 403
- 404
- 422
- 429
- 502
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.
Bad Gateway