Skip to main content

The sync object

status is idle, running (a run is queued or in progress) or attention (the last run failed or the sync is parked; attention.code says why). latest_run is filled with include[]=latest_run.

Create a sync

Returns 201 with the sync and, unless run_now: false, latest_run set to the queued first run. Rules:
  • The destination must be active (400 destination_incomplete otherwise) and not already used by a sync (409 destination_in_use).
  • YNAB needs account_mappings (budget account per bank account, ids from GET /v2/destinations/{id}/resources?type=account&parent=<budget>); Sheets per_account without mappings gets a tab per banking account created for you.
  • Brokerage accounts need a Sheets destination; holdings/trades syncs need brokerage accounts.
  • options.data_from is clamped to the last 84 months, and a date in the future is clamped to today; the default is 6 months (3 on trial). The response carries the clamped value, so read it back rather than assuming what you sent.
  • Plan sync limit: 403 sync_limit_reached.

Endpoints

On a per_account Sheets sync, adding accounts needs account_mappings for the new ones (400 mapping_required); brokerage accounts share the Holdings and Trades tabs and need none.

The sync_run object

status: queuedrunningsucceeded | failed | cancelled. trigger: schedule, api, dashboard, webhook, resync. A failed run carries failure.code (destination_auth_failed, destination_resource_missing, rate_limited, timeout, superseded, run_failed) and retryable. Watch a run: poll GET /v2/sync_runs/{id} or subscribe an event destination to sync_run.*.

Categories

Your taxonomy is a tree one level deep: groups (parent: null) contain categories. Each category claims provider category codes (sources); a transaction resolves to the category that claims its subcategory, then its primary category.