# Deck v2 API Context
Deck is a platform that connects to external websites on behalf of your users. You make REST API calls, Deck handles authentication, navigation, and data extraction, and returns structured JSON results. You never interact with websites directly.
## API Basics
- Base URL: `https://api.deck.co/v2`
- Auth: `Authorization: Bearer sk_live_...`
- Content type: `application/json`
- All work is asynchronous. API calls return immediately. Results arrive via events.
- There is no sandbox or test environment. All calls are live.
## Core Integration Flow
1. Create a **Source** (an external website, defined by type and URL)
2. Store a **Credential** (encrypted auth details for a user on a source)
3. Create a **Task** (defines what to do on the source)
4. Run the **Task** with a credential (Deck creates a session, authenticates, and executes)
5. Receive results via **Events** pushed to your webhook or queue
## Resource ID Prefixes
Every resource ID is prefixed by type:
| Prefix | Resource |
| --- | --- |
| `agt_` | Agent |
| `src_` | Source |
| `cred_` | Credential |
| `sess_` | Session |
| `task_` | Task |
| `trun_` | Task Run |
| `stor_` | Storage Item |
| `evt_` | Event |
| `evtd_` | Event Destination |
| `edlv_` | Event Delivery |
| `req_` | Request ID |
## Key Endpoints
| Action | Method | Path |
| --- | --- | --- |
| Create source | POST | `/v2/sources` |
| Store credential | POST | `/v2/credentials` |
| Delete credential | DELETE | `/v2/credentials/{credential_id}` |
| Create task | POST | `/v2/tasks` |
| Run task | POST | `/v2/tasks/{task_id}/run` |
| Submit interaction | POST | `/v2/task-runs/{run_id}/interaction` |
| List task runs | GET | `/v2/task-runs` |
| Get task run | GET | `/v2/task-runs/{run_id}?include=input,storage,screenshots` |
| Create event destination | POST | `/v2/event-destinations` |
## Credential Authentication
Credentials support three auth methods:
```json
{
"source_id": "src_...",
"auth_method": "username_password",
"auth_credentials": { "username": "...", "password": "..." }
}
```
Valid `auth_method` values: `username_password`, `none`.
## Credential Statuses
`unverified` → `verified` → (optionally `invalid`) → `deleted`
- `unverified` means stored but not yet used in a successful authentication
- `verified` means successfully authenticated at least once
- `invalid` means the source rejected the credentials
- `deleted` means permanently removed from the vault
## Session Statuses
Sessions are created automatically when a task runs: `queued` → `running` → `idle` (no active tasks) → `completing` → `completed` | `failed`
You can reuse a session by passing `session_id` when running a task.
## Interactions
When a task run needs user input (MFA, security question, account selection), status becomes `interaction_required`. The response includes an `interaction` object with `type`, `message`, and `fields`. Each field has a `name`, `type`, and `label`. Submit the response to:
- Task runs: `POST /v2/task-runs/{run_id}/interaction`
Body: `{ "input": { "<field_name>": "<value>" } }`
## Events and Webhooks
Deck pushes events to destinations you configure (webhooks, AWS SQS, Kinesis, S3, GCP Pub/Sub, Azure Service Bus, RabbitMQ, Hookdeck).
Event format:
```json
{
"id": "evt_...",
"type": "task_run.completed",
"data": { ... },
"created_at": "2025-01-15T09:30:00Z"
}
```
Key event types:
- `credential.verified`, `credential.invalid`, `credential.deleted`
- `session.queued`, `session.running`, `session.idle`, `session.completing`, `session.completed`, `session.failed`
- `task_run.queued`, `task_run.running`, `task_run.pending`, `task_run.completed`, `task_run.failed`
- `task_run.interaction_required`
Webhook signatures follow the Standard Webhooks specification. Use the `standardwebhooks` SDK to verify with your `whsec_` signing secret.
## Pagination
All list endpoints use cursor-based pagination:
- Query params: `limit` (default 20, max 100), `cursor`
- Response: `{ "data": [...], "has_more": true, "next_cursor": "eyJ..." }`
- Loop until `has_more` is `false`
## Idempotency
All POST, PATCH, and DELETE endpoints accept an `Idempotency-Key` header (max 256 chars, expires after 24h). Same key + same params returns the original response. Same key + different params returns HTTP 409.
## Error Format
```json
{
"errors": [{ "type": "request", "code": "input_missing", "field": "name", "message": "..." }],
"request_id": "req_..."
}
```
Always branch on `type` and `code`, never on `message`. Always log `request_id` for debugging.
Common error codes:
- `rate_limit_exceeded` (429) - back off with exponential delay
- `auth_invalid` (401) - credentials are wrong
- `mfa_timeout` (408) - MFA expired, resubmit the task run
- `input_missing` (400) - check the `field` property
- `source_not_available` (503) - external website is down, retry later
- `idempotency_error` (409) - same key with different params
## CRITICAL RULES FOR AI MODELS
### Always do
1. Use event destinations (webhooks, queues) to receive results. Never poll.
2. Use `Idempotency-Key` on all create requests.
3. Handle `interaction_required` status on task runs.
4. Paginate with `cursor` and `has_more`, never offsets.
5. Verify webhook signatures using the Standard Webhooks SDK.
6. Handle errors by `type` and `code`, never by `message`.
7. Write task prompts as high-level, source-agnostic goals. A task runs across every source that supports it, so never reference a specific website or UI. The prompt is combined with Deck's agent harness, which handles navigation, authentication, and tool use. Example: "Log in and fetch the latest bill." not "Click the sign-in button, enter credentials, navigate to billing..."
8. Design task input schemas with only the fields that change between runs. Keep them source-agnostic. Do not add fields tied to a specific source.
9. Design task output schemas with generic fields any supporting source can populate. Fields return `null` when a source doesn't have that data. Do not mirror a single source's data model.
### Never do
1. Do not poll `/v2/task-runs/{id}` in a loop. Use events.
2. Do not hardcode source IDs. Create sources via the API or look them up.
3. Do not ignore `interaction_required`. Users may need to complete MFA.
4. Do not assume task runs complete synchronously. They are always async.
5. Do not send credentials from the client. Always proxy through your server.
6. Do not branch on error `message` strings. They can change without notice.
7. Do not include detailed navigation steps in task prompts. They conflict with the agent harness and can restrict tools the agent needs.
8. Do not add source-specific fields to task schemas. A task must work across all sources that support it.