Raw provider error messages and response bodies are never persisted or returned. What you receive is a fixed set of codes. This keeps another system’s internal detail—file names, user identities, tenant structure—out of your logs and your users’ screens.
Request errors
These come back from the call you just made.
A
connect_url that has expired returns 410; one that has already been used returns 404. Either way, generate a fresh one.
Provider failures
Every provider error is classified before it touches your data. The classification decides whether the run retries, fails the file, or stops.
Two more are specific rather than classified:
Recovering from each
Reauthorization required
The most common one. Refresh tokens get revoked when a user changes their password, an admin removes an app, or a provider expires a grant. The connection moves toreauth_required and a connection.reauth_required event fires. Links stop; nothing is lost.
Send the user through the connect flow again. Because reconnection merges into the existing connection, links resume with their ledgers and cursors intact and nothing re-imports.
Access lost
The account still works, but the linked folder does not. Someone moved it, deleted it, or removed this user’s access. The link becomesorphaned with an orphan_reason:
An orphaned link will not run again. Point the user at a new folder with a fresh transfer, or delete the link.
Throttling
Backoff is automatic. The run slows down and keeps going; you do not need to do anything. For interactive browse calls, a429 may carry Retry-After when a retry deadline is known—honor it rather than looping.
Interactive browsing and background runs share one request budget per provider account. A large sync in progress can make browsing feel slow for the same user. This is most noticeable on providers with tight rate limits—see the provider guides.
Transient failures
Retried automatically within the run. If a run endscompleted_with_errors, the files that failed are in the ledger with state=failed. Re-post the same transfer to retry only those—the ledger means settled files are not touched again.
Permanent failures
The file failed and will not be retried. Read the row fromGET /connectors/v1/links/{id}/objects?state=failed and surface it to the user.
What a crash does not do
Transfers are built so that an interrupted run is safe to resume:- Every external side effect is preceded by a persisted ledger intent, so a retry lands on the same identity instead of creating a duplicate
- Files stream end to end and nothing buffers whole, so a large file cannot exhaust memory mid-run
- Deleting a link soft-deletes it before cancelling its run, so an in-flight executor cannot resurrect it
A practical error-handling loop
- On
run.failed, readerrorfrom the run and decide whether it is reauth, access loss, or something else - On
run.completedwithstatus: "completed_with_errors", pull?state=failedfrom the ledger and show the affected files - On
connection.reauth_required, prompt the user to reconnect—do not delete anything - On
link.orphaned, ask the user to reselect a folder - Treat
403 installation_requiredas a bug in your request path, not a permissions problem
Next steps
Import & Export
Run mechanics, ledger states, and progress
Events
Full payloads for connector lifecycle events
Providers
Rate budgets and capability differences per provider

