> ## Documentation Index
> Fetch the complete documentation index at: https://deepline.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Background Agents

> Run Deepline workflows safely from CI, scheduled jobs, and agent workers. Use it to pilot on a few rows, verify the output, and scale the workflow safely.

Job: let an agent or job run GTM workflows without babysitting.

Examples:

| Background job                | Play pattern                    |
| ----------------------------- | ------------------------------- |
| Refresh account signals daily | cron binding                    |
| Enrich inbound demo requests  | webhook binding                 |
| Clean CRM job changes weekly  | scheduled play                  |
| Process new CSV drops         | agent watches folder, runs play |

## Pin credentials in `.env.deepline`

```bash theme={null}
cd ~/gtm-workflows/customers/acme
cat >.env.deepline <<'ENV'
DEEPLINE_HOST_URL=https://code.deepline.com
DEEPLINE_API_KEY=dl_acme_workspace_key
ENV

deepline plays run account-refresh --watch --json
```

Do not rely on `deepline org switch` in unattended jobs, and do not prefix
individual Deepline commands with ad hoc API keys.

Use customer-specific output paths:

```bash theme={null}
cd ~/gtm-workflows/customers/acme
deepline plays check account-refresh.play.ts

deepline plays run plays/customers/acme/account-refresh.play.ts \
  --csv customers/acme/input/accounts.csv \
  --watch

deepline runs export <run-id> --out output/accounts-refreshed-2026-05-11.csv
```

## Name agents like operators

```bash theme={null}
deepline auth register \
  --org-name "Acme" \
  --agent-name "acme-nightly-enrichment"
```

When support looks at runs later, this name should explain who did the work.

## Watch status

```bash theme={null}
deepline runs list --play account-refresh --json
deepline runs tail <run-id> --json
```

Use these in runbooks and incident notes.

## Add small brakes

```ts theme={null}
import { definePlay } from 'deepline';

type Account = {
  domain: string;
};

export default definePlay('account-refresh', async (ctx, input: { accounts: Account[] }) => {
  const rows = await ctx
    .dataset('account_refresh', input.accounts)
    .withColumn('company_signal', (account, rowCtx) =>
      rowCtx.tools.execute({
        id: 'company_signal',
        tool: 'test_rate_limit',
        input: { key: account.domain },
        description: 'Refresh one account signal.',
      }),
    )
    .run({ key: 'domain' });

  return { rows };
}, {
  billing: { maxCreditsPerRun: 25 },
});
```

For a new workflow, pilot a few rows first. Then raise the cap when the output looks right.
