---
name: Deck
description: Use when building computer use agents that automate websites and software, managing credentials and task execution, handling multi-step workflows, processing interactions like MFA, and integrating event-driven architectures into applications.
metadata:
    mintlify-proj: deck
    version: "1.0"
---

# Deck Skill

## Product summary

Deck is a computer use agent platform that automates websites and software like a human would. Agents operate any software with a browser interface, returning structured JSON output. Use Deck to automate data collection, form submission, account management, and other web-based tasks across sources that lack APIs.

**Key resources:**
- **Base URL:** `https://api.deck.co/v2`
- **Authentication:** Bearer token in `Authorization` header (format: `sk_live_...`)
- **Core objects:** Agents (use case containers), Sources (websites), Credentials (encrypted auth), Tasks (work definitions), Task Runs (executions), Sessions (isolated compute), Storage (file capture)
- **Primary docs:** https://docs.deck.co

## When to use

Reach for this skill when:
- Building agents to automate websites or software without APIs
- Storing and managing user credentials securely
- Running tasks that require structured output (JSON schema validation)
- Handling multi-factor authentication or security prompts mid-execution
- Chaining multiple tasks into workflows without server-side orchestration
- Integrating event-driven notifications (webhooks, SQS, Pub/Sub)
- Capturing and extracting data from documents during task execution
- Debugging task failures or monitoring agent execution

## Quick reference

### Core API endpoints

| Resource | Create | List | Get | Update | Delete |
| --- | --- | --- | --- | --- | --- |
| Agents | `POST /agents` | `GET /agents` | `GET /agents/{id}` | `PATCH /agents/{id}` | `DELETE /agents/{id}` |
| Sources | `POST /sources` | `GET /sources` | `GET /sources/{id}` | `PATCH /sources/{id}` | `DELETE /sources/{id}` |
| Tasks | `POST /tasks` | `GET /tasks` | `GET /tasks/{id}` | `PATCH /tasks/{id}` | `DELETE /tasks/{id}` |
| Credentials | `POST /credentials` | `GET /credentials` | `GET /credentials/{id}` | `PATCH /credentials/{id}` | `DELETE /credentials/{id}` |
| Task Runs | `POST /tasks/{id}/run` | `GET /task-runs` | `GET /task-runs/{id}` | — | — |
| Sessions | `POST /sessions` | `GET /sessions` | `GET /sessions/{id}` | — | `POST /sessions/{id}/end` |
| Event Destinations | `POST /event-destinations` | `GET /event-destinations` | `GET /event-destinations/{id}` | `PATCH /event-destinations/{id}` | `DELETE /event-destinations/{id}` |

### Task statuses

| Status | Meaning | Success rate |
| --- | --- | --- |
| `learning` | Agent is learning the task | Lower (expect failures) |
| `test` | Agent understands task, improving | Higher |
| `live` | Production-ready | Highest |

Tasks graduate after **3 successful runs** in each stage. Reset with `POST /tasks/{id}/reset` to restart learning.

### Credential auth methods

| Method | Use case |
| --- | --- |
| `username_password` | Standard login (email + password) |
| `none` | No authentication required |

### Interaction types

| Type | Triggered by | Typical fields |
| --- | --- | --- |
| `mfa` | One-time codes (SMS, email, app) | `code` |
| `security_question` | Knowledge-based verification | `answer` |
| `account_selection` | Multiple accounts at source | `account_id` |

### Event types (common)

| Event | Fired when |
| --- | --- |
| `credential.verified` | Credential successfully authenticated |
| `credential.invalid` | Source rejected credentials |
| `task_run.queued` | Run waiting to start |
| `task_run.running` | Execution began |
| `task_run.interaction_required` | MFA or verification needed |
| `task_run.completed` | Run finished successfully |
| `task_run.failed` | Run encountered error |

### Resource ID prefixes

| Prefix | Resource |
| --- | --- |
| `agt_` | Agent |
| `src_` | Source |
| `cred_` | Credential |
| `sess_` | Session |
| `task_` | Task |
| `trun_` | Task Run |
| `evt_` | Event |

## Decision guidance

### When to use task runs vs. workflows

| Scenario | Use task runs | Use workflows |
| --- | --- | --- |
| Single task execution | ✓ | — |
| Sequential multi-step operations | — | ✓ |
| Chaining outputs between tasks | — | ✓ |
| Conditional branching or loops | — | ✓ |
| Simple data fetch | ✓ | — |
| Complex orchestration | — | ✓ |

**Rule:** If you're polling for completion or writing retry logic on your server, use workflows instead.

### When to store credentials vs. pass them per-run

| Approach | When to use |
| --- | --- |
| Store in Credential Vault | Recurring tasks, same user, credential reuse across runs |
| Pass per-run (headless) | One-off tasks, different credentials per run, no user interaction |

### When to use sessions

| Scenario | Action |
| --- | --- |
| Single task, no reuse | Omit `session_id`; Deck creates and cleans up automatically |
| Multiple tasks, same user | Pass `session_id` from first run to subsequent runs; avoids re-authentication |
| Long-running operations | Reuse session; Deck keeps it open while active |

## Workflow

### Setting up a new agent and task

1. **Create an agent** — Scope it to a single use case (e.g., "Hotel Reservations")
   ```bash
   curl -X POST https://api.deck.co/v2/agents \
     -H "Authorization: Bearer sk_live_..." \
     -H "Content-Type: application/json" \
     -d '{"name": "Hotel Reservations", "description": "Fetch bookings"}'
   ```

2. **Create a source** — Add the website URL
   ```bash
   curl -X POST https://api.deck.co/v2/sources \
     -H "Authorization: Bearer sk_live_..." \
     -H "Content-Type: application/json" \
     -d '{"name": "Hilton", "type": "website", "website": {"url": "https://hilton.com"}}'
   ```

3. **Create a task** — Define input schema, output schema, and prompt
   - Write a goal-focused prompt (not step-by-step instructions)
   - Design input schema for what changes between runs
   - Design output schema for what your app needs
   - Tasks start in `learning` status

4. **Store credentials (optional)** — If the source requires login
   ```bash
   curl -X POST https://api.deck.co/v2/credentials \
     -H "Authorization: Bearer sk_live_..." \
     -H "Content-Type: application/json" \
     -d '{"source_id": "src_...", "auth_method": "username_password", "auth_credentials": {"username": "user@example.com", "password": "..."}, "external_id": "user_123"}'
   ```

5. **Run the task** — Execute with input and credential
   ```bash
   curl -X POST https://api.deck.co/v2/tasks/task_.../run \
     -H "Authorization: Bearer sk_live_..." \
     -H "Content-Type: application/json" \
     -d '{"credential_id": "cred_...", "input": {"check_in_date": "2026-04-01"}}'
   ```

6. **Handle the response** — Poll or listen for events
   - Response comes back immediately with `status: "queued"`
   - Poll `GET /task-runs/{id}` every 5 seconds, or
   - Subscribe to `task_run.completed` / `task_run.failed` events

7. **Handle interactions** — If `status: "interaction_required"`, collect user input
   ```bash
   curl -X POST https://api.deck.co/v2/task-runs/trun_.../interaction \
     -H "Authorization: Bearer sk_live_..." \
     -H "Content-Type: application/json" \
     -d '{"input": {"code": "123456"}}'
   ```

### Handling task run failures

1. Check the `errors` array on the task run object
2. Identify the error `type` and `code` (not the message)
3. Branch on type:
   - `auth` → Credential invalid; prompt user to update
   - `source` → Website down or blocked; retry later
   - `task` → Agent failed; check task prompt or reset task to `learning`
   - `interaction_timeout` → User didn't respond in time; run task again
   - `rate_limit` → Too many requests; back off exponentially

### Setting up event delivery

1. Create an event destination
   ```bash
   curl -X POST https://api.deck.co/v2/event-destinations \
     -H "Authorization: Bearer sk_live_..." \
     -H "Content-Type: application/json" \
     -d '{"name": "Production", "type": "webhook", "webhook": {"url": "https://your-app.com/webhooks/deck"}, "events": ["task_run.completed", "task_run.failed", "credential.verified"]}'
   ```

2. Implement a webhook handler that:
   - Returns `2xx` within 5 seconds to acknowledge
   - Verifies the webhook signature (HMAC-SHA256)
   - Processes events idempotently (same event may be delivered multiple times)
   - Logs the `request_id` for debugging

3. Track delivery status via `GET /event-destinations/{id}/event-deliveries`

## Common gotchas

- **Task prompts are too prescriptive** — Don't write step-by-step instructions. Write goal-focused prompts ("Log in and fetch my latest bill"). The agent harness handles navigation.

- **Input/output schemas are source-specific** — Schemas should be generic across all sources. Don't include Hilton-specific fields in a task that should work on Marriott too. Fields come back `null` if a source doesn't have the data.

- **Polling without backoff** — Don't poll every 100ms. Task runs take seconds to minutes. Poll every 5 seconds and use exponential backoff on rate limits.

- **Ignoring error types** — Don't branch on error messages; they change. Use `type` and `code` for logic. Example: `if (error.type === "auth" && error.code === "auth_invalid")`.

- **Reusing cursors across endpoints** — Pagination cursors are opaque and tied to a specific endpoint and filter set. Don't reuse them elsewhere.

- **Not using idempotency keys** — Always include `Idempotency-Key` on create operations. Prevents duplicate agents, tasks, credentials, and runs if a request is retried.

- **Storing credentials client-side** — Credentials must go to your server over HTTPS, then to Deck. Never send credentials directly from the browser to Deck.

- **Forgetting to handle interactions** — Some sources require MFA or security questions. Listen for `task_run.interaction_required` events and submit responses via the interaction endpoint.

- **Task stuck in `learning`** — If a task isn't progressing, reset it with `POST /tasks/{id}/reset` and run it again. The agent will re-learn.

- **Credential status never changes** — Credentials start as `unverified`. They become `verified` only after a successful task run. They become `invalid` if the source rejects them.

## Verification checklist

Before submitting work with Deck:

- [ ] API key is valid (test with `GET /v2/test`)
- [ ] Agent, source, and task are created and IDs are correct
- [ ] Task prompt describes the goal, not step-by-step instructions
- [ ] Input and output schemas are generic (not source-specific)
- [ ] Credentials are stored with correct `auth_method` and `external_id`
- [ ] Task run request includes valid `credential_id` and input matching the schema
- [ ] Error handling branches on `type` and `code`, not message text
- [ ] Idempotency keys are included on all create/update/delete operations
- [ ] Event destination is configured and webhook handler returns `2xx` within 5 seconds
- [ ] Interaction handler collects fields from the `interaction.fields` array dynamically
- [ ] Polling uses 5-second intervals with exponential backoff on rate limits
- [ ] Task has run at least 3 times successfully before moving to production (`live` status)

## Resources

**Comprehensive navigation:** https://docs.deck.co/llms.txt

**Critical pages:**
- [Quickstart](https://docs.deck.co/guides/quickstart) — Create an agent, store credentials, run your first task
- [Concepts overview](https://docs.deck.co/concepts/overview) — Agents, sources, credentials, tasks, sessions, and how they fit together
- [Using the API](https://docs.deck.co/api/using-the-api) — Authentication, request/response format, and conventions

---

> For additional documentation and navigation, see: https://docs.deck.co/llms.txt