- Extract accounts: runs once per credential. Returns a list of accounts behind a single credential.
- Fetch bill history: runs against a single account. Downloads every bill for that account, optionally bounded by a start date.
- Per-account attribution. If a bill is missing for an account, there is one run to inspect.
- Retry granularity. A failed run is tightly scoped and can be retried on its own.
- Bounded runs. One account’s history is a bounded unit of work, so runtime and file counts stay predictable.
- Resumable backfill. The
since_bill_dateinput picks up where a partial backfill stopped, without re-fetching bills you already have. - A durable account list. Every run returns the current account list. If an account disappears from a later run, you notice.
- One login per credential. The workflow runs every step in one session, so the agent signs in once and works through the accounts.
Prerequisites
This guide assumes you have an agent, a source, and a stored credential; the Quickstart covers those steps. The history task uses storage, extraction, and deduplication, available as an add-on on paid plans. The workflows guide covers the step types and run body used here.Create the tasks
Both tasks belong to the same agent. See Tasks for guidance on writing prompts.1
Extract accounts
Runs once per credential per refresh cycle, typically monthly, or on demand when a user adds or removes accounts on the source. You store the returned list. The task returns metadata only, so leave storage off.Not every source labels service type or account status, so treat both as hints.
Request
2
Fetch bill history
Runs once per account. It takes the account number and an optional The captured files appear in storage, not the output. The
since_bill_date that bounds the fetch, used to resume a partial backfill or recover a gap. Storage, extraction, and deduplication are enabled: extraction pulls each bill’s fields from the file, and deduplication skips bills a previous run already captured.Request
bills array carries the dates the agent read from the listing, which is what you use to update your stored state.Create the workflow
One workflow runs both tasks for a credential. Steps run in order in one session, so the agent logs in once. The loop runs underfailure_behavior: "continue", so one account’s failure doesn’t stop the rest.
Request
fetch_history loops over the accounts the first step returned. The if skips accounts the source marks closed. An account with no status still runs, since is_active is only a hint. Skipped accounts get null in the step’s output and no task run.
The definition sets only the account number. since_bill_date comes from the run body when you need it, below.
Run the workflow
Run the workflow once per credential. Pass the credential on every step. On the first backfill, leavesince_bill_date out so each account fetches its full history:
Request
since_bill_date to fetch_history. The run-time input merges into every item’s input alongside the account number, so one date applies to every account in the run:
queued. Runs are asynchronous: subscribe to workflow_run.completed and workflow_run.failed events, or poll the run.
Each run holds one session until it finishes, so when backfilling many credentials, pace the starts to stay within your organization’s session limit. A run requested over the limit is rejected with session_limit_exceeded rather than queued. To backfill every credential on a source without writing the loop yourself, point a trigger at the workflow with a concurrency_max inside that limit, then deactivate it once the fire completes.
Read the results
Fetch the run withinclude=storage to get each account’s bills and their extractions inline:
Response
output has one slot per account, in the order the first step returned them. Each task_runs entry names the account it processed in item, and with include=storage carries every bill it delivered. For anything beyond that, fetch the task run itself with GET /v2/task-runs/{task_run_id}.
Store the account list from extract_accounts and the date you ran the backfill. On the next run, set since_bill_date to the day before that date. A bill issued on the run date can land on either side of the cutoff, and deduplication skips any bill the overlap picks up again.
Bounding the backfill
For sources with years of history, walk the history in windows instead of one large run: start withsince_bill_date a few months back, then run again with the date further back each time. One date applies to every account in a run, so each run is one window across the whole credential. Deduplication skips bills already captured, so overlapping windows don’t produce duplicate files, and each run’s file count and runtime stay predictable.
To recover a delivery gap on specific accounts, run the task that fetches bill history directly for just those accounts, with since_bill_date set to the newest bill you have. The workflow doesn’t need to run.
Handle failures
Ifextract_accounts fails, the run ends failed with the step named in its errors, and nothing else runs. Fix the cause and run the workflow again.
Inside the loop, a failed account doesn’t stop the others. The run finishes completed with result: "failure", the account’s slot in the step’s output is null, and its task_runs entry carries the errors. See Errors. To retry that account alone, run the history task directly with the credential and account number, without re-running the workflow.
If the credential goes invalid (a changed password, for example), Deck emits a credential.invalid event so you can prompt the user to re-authenticate. Skip that credential until it recovers, then run the workflow with since_bill_date set to the day before its last successful run.