# Build with AI Source: https://docs.deck.co/ai Skill and context prompt for building Deck integrations with AI coding agents. AI coding tools write better Deck integration code when they have the right context. This page provides a skill and system prompt you can load into your tool of choice so it understands the Deck v2 API, follows correct patterns, and avoids common mistakes. ## Deck skill The Deck skill is a [SKILL.md](https://docs.deck.co/skill.md) file your agent can load to learn how to build Deck integrations. It bundles a product summary, API quick reference, decision rules, common gotchas, and a verification checklist. Download it from [https://docs.deck.co/skill.md](https://docs.deck.co/skill.md) and drop it in your agent's skills directory. ## Prompt If you'd rather use a prompt than the skill, paste the prompt below into your project's context file so it loads in every session. Common locations: | Tool | How to load | | ------------------ | -------------------------------------------------------------------------------------- | | **Cursor** | Add to your [project rules](https://cursor.com/docs/context/rules) in `.cursor/rules/` | | **Claude Code** | Add to your `CLAUDE.md` file in the project root | | **Codex** | Add to your `AGENTS.md` file in the project root | | **GitHub Copilot** | Save to `.github/copilot-instructions.md` | | **Other** | Paste into your tool's system prompt or project context | Copy the full prompt below, or combine sections that are relevant to your integration. ````markdown theme={null} # 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 an **Agent** (a use case that groups related tasks, e.g. hotel reservations) 2. Create a **Source** (an external website, defined by type and URL) 3. Store a **Credential** (encrypted auth details for a user on a source) 4. Create a **Task** (defines what to do; belongs to an agent, runs on any supporting source) 5. Run the **Task** with a credential (Deck creates a session, authenticates, and executes) 6. 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 agent | POST | `/v2/agents` | | 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,artifacts` | | Create event destination | POST | `/v2/event-destinations` | ## Credential Authentication Most sources use `username_password`: ```json { "source_id": "src_...", "auth_method": "username_password", "auth_credentials": { "username": "...", "password": "..." } } ``` Valid `auth_method` values: `username_password`, `source_fields`, `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": { "": "" } }` ## 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 - `interaction_timeout` (408) - interaction 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. Optional fields return `null` when the source doesn't contain that information; if the source doesn't contain a `required` field, the run fails with a `task_not_supported` error. Do not mirror a single source's data model. 10. Reference task inputs by name in the prompt, never inline values: "Download bills between {start_date} and {end_date}". 11. Name agents and tasks after the use case, never after a source. An agent works across many sources: "Hotel Reservations", not "Hilton Reservations". ### 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. 9. Do not put credentials or login instructions in task prompts. Deck authenticates the session with the stored credential. 10. Do not put a source name in an agent or task name. Only sources are named after the site ("Hilton"); agents and tasks span sources. ```` ## MCP server If your tool supports MCP, connect the [Deck Docs MCP server](/integrations/mcp) at `https://docs.deck.co/mcp`. It gives your agent live search over this site, so answers come from the current docs instead of training data. It also exposes the Deck skill as an MCP resource. ## Raw files Point your AI assistant at these URLs to give it canonical source data: | File | Purpose | | ---------------------------------------------------------------------- | ------------------------------------------------- | | [`/api-reference/v2.json`](https://docs.deck.co/api-reference/v2.json) | OpenAPI 3.1 spec for the Deck v2 API | | [`/llms.txt`](https://docs.deck.co/llms.txt) | Index of all docs pages, formatted for LLMs | | [`/llms-full.txt`](https://docs.deck.co/llms-full.txt) | Full docs content concatenated into a single file | # Create an agent Source: https://docs.deck.co/api-reference/agents/create-an-agent /api-reference/v2.json post /agents Creates a new agent. An agent is an automation scoped to a use case that organizes related tasks. # Delete an agent Source: https://docs.deck.co/api-reference/agents/delete-an-agent /api-reference/v2.json delete /agents/{agent_id} Permanently deletes an agent. # List agents Source: https://docs.deck.co/api-reference/agents/list-agents /api-reference/v2.json get /agents Returns a paginated list of agents in your organization. # Retrieve an agent Source: https://docs.deck.co/api-reference/agents/retrieve-an-agent /api-reference/v2.json get /agents/{agent_id} Returns the full agent object including its associated tasks. # Update an agent Source: https://docs.deck.co/api-reference/agents/update-an-agent /api-reference/v2.json patch /agents/{agent_id} Updates an agent's name or description. Only the fields you include in the request body are updated. # Create a session token Source: https://docs.deck.co/api-reference/components/create-a-session-token /api-reference/v2.json post /token Creates a short-lived session token for the Auth Component. # Create a credential Source: https://docs.deck.co/api-reference/credentials/create-a-credential /api-reference/v2.json post /credentials Stores a new credential for authenticating with an external source. The credential is created immediately and can be used on task runs. # Delete a credential Source: https://docs.deck.co/api-reference/credentials/delete-a-credential /api-reference/v2.json delete /credentials/{credential_id} Permanently deletes a credential. # List credentials Source: https://docs.deck.co/api-reference/credentials/list-credentials /api-reference/v2.json get /credentials Returns a paginated list of credentials. Supports filtering by source, status, and external ID. # Retrieve a credential Source: https://docs.deck.co/api-reference/credentials/retrieve-a-credential /api-reference/v2.json get /credentials/{credential_id} Returns a single credential by ID. # Update a credential Source: https://docs.deck.co/api-reference/credentials/update-a-credential /api-reference/v2.json patch /credentials/{credential_id} Updates a credential's authentication details or external ID. Only the fields you include in the request body are updated. # Create an event destination Source: https://docs.deck.co/api-reference/event-destinations/create-an-event-destination /api-reference/v2.json post /event-destinations Creates a new event destination (e.g. a webhook endpoint) to receive platform events. # Delete an event destination Source: https://docs.deck.co/api-reference/event-destinations/delete-an-event-destination /api-reference/v2.json delete /event-destinations/{destination_id} Permanently deletes an event destination. # List event deliveries Source: https://docs.deck.co/api-reference/event-destinations/list-event-deliveries /api-reference/v2.json get /event-destinations/{destination_id}/event-deliveries Returns a paginated list of event deliveries for a destination. Supports filtering by delivery status. # List event destinations Source: https://docs.deck.co/api-reference/event-destinations/list-event-destinations /api-reference/v2.json get /event-destinations Returns a paginated list of event destinations. # Retrieve an event destination Source: https://docs.deck.co/api-reference/event-destinations/retrieve-an-event-destination /api-reference/v2.json get /event-destinations/{destination_id} Returns a single event destination by ID. # Send a test event to a destination Source: https://docs.deck.co/api-reference/event-destinations/send-a-test-event-to-a-destination /api-reference/v2.json post /event-destinations/{destination_id}/test Delivers a `test.ping` event with a `data` payload of `{"ok": true}` to the destination and returns the attempt status and HTTP response code. Test events are delivered once and not retried. The destination must be `active`; a destination still in `pending_verification` returns a `422`. # Update an event destination Source: https://docs.deck.co/api-reference/event-destinations/update-an-event-destination /api-reference/v2.json patch /event-destinations/{destination_id} Updates an event destination's name, status, or subscribed events. Only the fields you include in the request body are updated. # List event types Source: https://docs.deck.co/api-reference/events/list-event-types /api-reference/v2.json get /event-types Returns a list of all available event types you can subscribe to. # List events Source: https://docs.deck.co/api-reference/events/list-events /api-reference/v2.json get /events Returns a paginated list of events. Supports filtering by event type. # Retrieve an event Source: https://docs.deck.co/api-reference/events/retrieve-an-event /api-reference/v2.json get /events/{event_id} Returns a single event by ID, including its full data payload. # End a session Source: https://docs.deck.co/api-reference/sessions/end-a-session /api-reference/v2.json post /sessions/{session_id}/end Ends an active session. # List sessions Source: https://docs.deck.co/api-reference/sessions/list-sessions /api-reference/v2.json get /sessions Returns a paginated list of sessions. # Retrieve a session Source: https://docs.deck.co/api-reference/sessions/retrieve-a-session /api-reference/v2.json get /sessions/{session_id} Returns a single session by ID, including the task runs executed within it. # Start a session Source: https://docs.deck.co/api-reference/sessions/start-a-session /api-reference/v2.json post /sessions Starts a new isolated compute session for executing tasks. # Create a source Source: https://docs.deck.co/api-reference/sources/create-a-source /api-reference/v2.json post /sources Registers a new source. A source is a website or service that your agents connect to. # Delete a source Source: https://docs.deck.co/api-reference/sources/delete-a-source /api-reference/v2.json delete /sources/{source_id} Permanently deletes a source. # List sources Source: https://docs.deck.co/api-reference/sources/list-sources /api-reference/v2.json get /sources Returns a paginated list of sources in your organization. # Reset a source Source: https://docs.deck.co/api-reference/sources/reset-a-source /api-reference/v2.json post /sources/{source_id}/reset Re-runs Deck's antibot analysis for the source. Runs keep using the existing analysis until the new one completes. Resetting again shortly after a previous reset has no effect and returns the current source; `reset_at` shows when the last reset took effect. # Retrieve a source Source: https://docs.deck.co/api-reference/sources/retrieve-a-source /api-reference/v2.json get /sources/{source_id} Returns a single source by ID. # Update a source Source: https://docs.deck.co/api-reference/sources/update-a-source /api-reference/v2.json patch /sources/{source_id} Updates a source's name or URL. Only the fields you include in the request body are updated. # Retrieve a storage item Source: https://docs.deck.co/api-reference/storage/retrieve-a-storage-item /api-reference/v2.json get /storage/{storage_id} Returns a single storage item by ID, including a signed download URL for the file. # Cancel a task run Source: https://docs.deck.co/api-reference/task-runs/cancel-a-task-run /api-reference/v2.json post /task-runs/{run_id}/cancel Cancels a running or queued task run. # List task run screenshots Source: https://docs.deck.co/api-reference/task-runs/list-task-run-screenshots /api-reference/v2.json get /task-runs/{run_id}/screenshots Returns a paginated list of agent screenshots captured during a task run, oldest first. Each item includes a pre-signed download URL and the agent's reasoning at the time of capture. # List task run storage items Source: https://docs.deck.co/api-reference/task-runs/list-task-run-storage-items /api-reference/v2.json get /task-runs/{run_id}/storage Returns all storage items (files) produced by a task run in a single response. # List task runs Source: https://docs.deck.co/api-reference/task-runs/list-task-runs /api-reference/v2.json get /task-runs Returns a paginated list of task runs. Supports filtering by agent, credential, source, task, workflow, status, result, and date range. # Retrieve a task run Source: https://docs.deck.co/api-reference/task-runs/retrieve-a-task-run /api-reference/v2.json get /task-runs/{run_id} Returns a single task run by ID, including its status, input, output, errors, and interaction state. # Submit interaction input Source: https://docs.deck.co/api-reference/task-runs/submit-interaction-input /api-reference/v2.json post /task-runs/{run_id}/interaction Submits user input to resume a task run that is paused waiting for interaction (e.g. MFA code, security question). # Create a task Source: https://docs.deck.co/api-reference/tasks/create-a-task /api-reference/v2.json post /tasks Creates a new task on an agent. A task is a defined action an agent can perform, such as fetching data or submitting a form. # Delete a task Source: https://docs.deck.co/api-reference/tasks/delete-a-task /api-reference/v2.json delete /tasks/{task_id} Permanently deletes a task. # List tasks Source: https://docs.deck.co/api-reference/tasks/list-tasks /api-reference/v2.json get /tasks Returns a paginated list of tasks. Supports filtering by agent and status. # Reset a task Source: https://docs.deck.co/api-reference/tasks/reset-a-task /api-reference/v2.json post /tasks/{task_id}/reset Resets a task's status to `learning`. The next run re-learns the flow from scratch. # Retrieve a task Source: https://docs.deck.co/api-reference/tasks/retrieve-a-task /api-reference/v2.json get /tasks/{task_id} Returns a single task by ID, including its input/output schemas and storage configuration. # Run a task Source: https://docs.deck.co/api-reference/tasks/run-a-task /api-reference/v2.json post /tasks/{task_id}/run Executes a task, creating a new task run. The run executes asynchronously. Use events or poll the task run endpoint to track progress. # Update a task Source: https://docs.deck.co/api-reference/tasks/update-a-task /api-reference/v2.json patch /tasks/{task_id} Updates a task's name, schemas, prompt, or storage configuration. Only the fields you include in the request body are updated. # Test your API key Source: https://docs.deck.co/api-reference/test/test-your-api-key /api-reference/v2.json get /test Verifies your API key is valid. # Create a trigger Source: https://docs.deck.co/api-reference/triggers/create-a-trigger /api-reference/v2.json post /triggers Creates a trigger that runs a task on a schedule across a set of credentials. The trigger is created active and fires on its schedule immediately. # Delete a trigger Source: https://docs.deck.co/api-reference/triggers/delete-a-trigger /api-reference/v2.json delete /triggers/{trigger_id} Permanently deletes a trigger. Scheduled fires stop immediately. # List trigger credentials Source: https://docs.deck.co/api-reference/triggers/list-trigger-credentials /api-reference/v2.json get /triggers/{trigger_id}/credentials Returns the credentials currently in scope for this trigger: the explicit `credential_ids`, or the current matches of `credential_filter`. This is the set that will get runs on the next fire. Each entry is a standard credential object. # List triggers Source: https://docs.deck.co/api-reference/triggers/list-triggers /api-reference/v2.json get /triggers Returns a paginated list of triggers in your organization. # Retrieve a trigger Source: https://docs.deck.co/api-reference/triggers/retrieve-a-trigger /api-reference/v2.json get /triggers/{trigger_id} Retrieves a single trigger by ID. # Update a trigger Source: https://docs.deck.co/api-reference/triggers/update-a-trigger /api-reference/v2.json patch /triggers/{trigger_id} Updates a trigger. Send any subset of fields; omitted fields are left unchanged. Set `status` to `active` or `inactive` to resume or pause the trigger. # API status and changes Source: https://docs.deck.co/api/api-status-and-changes Versioning, breaking changes, and how Deck communicates platform updates. ## Platform status Deck publishes real-time operational status at [status.deck.co](https://status.deck.co). Subscribe to receive notifications about downtime, degraded performance, and scheduled maintenance. ## Versioning Deck uses semantic versioning (e.g., v1.6, v2.2, v3) to manage breaking changes. Each version defines how Deck interprets requests, structures responses, and delivers events. Every team has a default API version that applies to all API keys and event deliveries. New teams start on the latest stable version automatically. ## Breaking changes Deck only releases new API versions when changes would break existing integrations. Breaking changes include: * Removing or renaming fields * Changing response structures or data types * Modifying required parameters * Altering authentication or error formats * Backwards-incompatible changes to endpoint behavior * Removing endpoints Deck provides advance notice before releasing breaking changes, announced in the changelog with migration notes. ## Additive changes Deck continuously ships additive, non-breaking updates that improve the API without requiring a new version. These roll out automatically to all supported versions. Examples include: * New optional request parameters * New response fields * New endpoints or resources * New event types * New optional HTTP headers * Changes to the order of properties in responses * Changes to the length or format of object IDs (up to 255 characters) * Bug fixes that improve correctness Your integration should handle additive changes gracefully. Ignore fields you don't recognize, don't fail on unexpected enum values, and handle unfamiliar event types in your event handlers. ## Building resilient integrations * Subscribe to the [status page](https://status.deck.co) for incident notifications * Handle unknown fields and enum values without failing * Use the `request_id` on error responses when contacting support * Use [events](/events/events) instead of polling to reduce your dependency on API availability # Error handling Source: https://docs.deck.co/api/errors Every error returns a consistent structure with a deterministic type, code, and request ID. Errors are always returned as an array, regardless of how many occurred, so your error handling logic only needs one code path. ## Error structure ```json theme={null} { "errors": [ { "type": "request", "code": "input_missing", "field": "name", "message": "`name` is required and cannot be empty." } ], "request_id": "req_a1b2c3d4..." } ``` | Field | Description | | ------------ | ---------------------------------------------------------------------------------- | | `type` | Error category. Determines the class of failure. | | `code` | Machine-readable error code. Use this for programmatic handling. | | `field` | The input field that caused the error, when applicable. | | `message` | Human-readable explanation. Do not rely on this for logic. | | `request_id` | Unique identifier for the request. Send this to Deck support when troubleshooting. | ## Handling errors Use `type` and `code` for branching logic. The `message` field is for logging and display only. It may change. ```javascript theme={null} if (error.type === "auth" && error.code === "auth_invalid") { promptUserToReAuthenticate(); } if (error.type === "interaction" && error.code === "interaction_timeout") { promptUserForNewMfaCode(); } if (error.type === "rate_limit") { retryWithBackoff(); } ``` ## Error types Errors are grouped as **Deck Errors**, **Request Errors**, or **Source Errors**. Only Deck Errors count against a task's [success rate](#success-rate). | Type | When it occurs | Group | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | | `api` | Deck platform failure | Deck Error | | `idempotency` | Idempotency key error | Request Error | | `session` | Session could not be established | Deck Error | | `rate_limit` | Too many requests | Request Error | | `source` | External source failure or unavailability | Source Error | | `request` | Invalid input, missing fields, or unsupported action | Request Error | | `auth` | Credential or authentication method failure | Request Error | | `interaction` | MFA or interaction timeout | Request Error | | `task` | Task execution failure | Deck Error | | `storage` | File storage or extraction failure | Deck Error | | `organization` | Plan, billing, or entitlement state blocks the request. Retrying will not help; the customer must upgrade, take billing action, or wait for the next billing cycle. | Request Error | ## Success rate Success rate is the share of task runs that completed successfully over a given time period. Only Deck Errors count against it. * Runs that succeed count as successes. * Runs that fail with a Deck Error count as failures. * Runs that fail with a Request Error or Source Error are excluded from the calculation, since it was impossible for Deck to complete the task. ``` success_rate = successes / (successes + deck_error_failures) ``` ## Error codes by type ### api | Code | Description | | --------------------- | ------------------------------------------ | | `api_error` | Platform error | | `timeout` | Platform timed out | | `endpoint_deprecated` | Endpoint is deprecated and pending removal | ### idempotency | Code | Description | | ----------------------- | ---------------------------------------------- | | `idempotency_error` | Same key, different parameters | | `idempotency_key_error` | Idempotency key must be at most 256 characters | ### session | Code | Description | | --------- | ------------------------------- | | `timeout` | Session could not start in time | ### rate\_limit | Code | Description | | ------------------------ | ---------------------------- | | `rate_limit_exceeded` | Too many requests | | `session_limit_exceeded` | Agent sandbox limit exceeded | ### source | Code | Description | | ---------------------- | ----------------------------- | | `source_error` | External source failure | | `source_not_available` | Source is down or unreachable | | `source_blocked` | Source is on a blocklist | ### request These are the most common errors. They indicate a problem with your request. | Code | Description | | --------------------------- | ------------------------------------------------------------------------------------------------ | | `input_invalid` | Validation failed | | `input_type_invalid` | Wrong type | | `input_format_invalid` | Wrong format | | `input_missing` | Required field missing | | `input_too_long` | Exceeds max length | | `input_too_short` | Below min length | | `input_duplicate` | Must be unique | | `query_param_invalid` | Unsupported query parameter | | `invalid_field_value` | A submitted field value is not valid (e.g. `settings.timeout_seconds` is not a positive integer) | | `timeout_exceeds_plan_max` | The requested task timeout exceeds the maximum allowed by your plan | | `cursor_invalid` | Pagination cursor is invalid or expired | | `resource_not_found` | Resource does not exist | | `resource_not_ready` | Resource is not in a usable state | | `api_key_invalid` | Invalid API key | | `token_invalid` | Invalid token | | `credential_not_found` | Credential does not exist | | `source_not_found` | Source does not exist | | `action_not_supported` | Not supported for this source | | `task_not_found` | Task does not exist | | `task_not_supported` | Task not supported for this source | | `interaction_required` | Blocked until pending interaction is resolved | | `interaction_input_invalid` | Submitted interaction data is invalid | | `interaction_not_required` | No interaction was requested | | `interaction_not_found` | Interaction does not exist | | `storage_not_found` | Storage item does not exist | | `attachment_invalid` | Input file failed its security scan. Returned asynchronously on the task run. | ### auth | Code | Description | | --------------------------- | ----------------------------------------- | | `auth_method_not_supported` | Auth method not supported for this source | | `auth_not_supported` | Source does not require authentication | | `auth_required` | Authentication is required | | `auth_invalid` | Credentials are wrong | | `password_reset_required` | Source is forcing a password reset | | `account_locked` | Account is locked at the source | ### interaction | Code | Description | | --------------------- | -------------------------- | | `interaction_timeout` | Interaction window expired | ### task | Code | Description | | --------------------- | --------------------------------------------------------- | | `blocked` | Blocked by antibot | | `extraction_failed` | Document extraction failed for one or more captured files | | `task_failed` | Task execution failed | | `task_result_unknown` | Completed but result could not be determined | | `timeout` | Execution timed out | ### storage | Code | Description | | -------------------- | ------------------------- | | `timeout` | Storage request timed out | | `extraction_timeout` | Extraction timed out | ### organization | Code | Description | | ----------------------- | ---------------------------------------------------- | | `quota_exceeded` | Plan quota exceeded | | `task_length_exceeded` | Task exceeded the maximum length allowed by the plan | | `feature_not_available` | Feature is not available on the current plan | | `plan_inactive` | Subscription is past due or canceled | ## Errors on resource objects When a task run fails, the `errors` array is populated on the run object itself. This is the same structure as API-level errors. ```json theme={null} { "id": "trun_a1b2c3d4...", "object": "task_run", "status": "failed", "result": "failure", "task_id": "task_a1b2c3d4...", "credential_id": "cred_a1b2c3d4...", "session_id": "sess_x9y8z7...", "agent_id": "agt_a1b2c3d4...", "source_id": "src_a1b2c3d4...", "runtime_ms": 12453, "output": null, "errors": [ { "type": "source", "code": "source_blocked", "message": "Source blocked the credential." } ], "interaction": null, "created_at": "2025-01-15T09:30:00Z", "updated_at": "2025-01-15T09:31:15Z", "request_id": "req_a1b2c3d4..." } ``` ## Request IDs Every response includes a `request_id`. When contacting Deck support, include this value to speed up troubleshooting. # External IDs Source: https://docs.deck.co/api/external-ids Map Deck credentials to users in your system with external identifiers. The `external_id` field on credentials lets you associate a Deck resource with an identifier from your own system. This is the primary mechanism for mapping Deck credentials to your users, accounts, or tenants. ## How it works When you create a credential, pass an `external_id` to link it to a record in your system: ```bash theme={null} curl -X POST "https://api.deck.co/v2/credentials" \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "source_id": "src_abc", "external_id": "user_12345", "auth_method": "username_password", "auth_credentials": { "username": "...", "password": "..." } }' ``` The `external_id` is stored on the credential and returned in all API responses and event payloads for that credential. ## Constraints * Maximum length: **255 characters** * Must be a string * Can be `null` (no external mapping) * Not required to be unique across credentials, but in most cases you'll want it to be meaningful ## Multi-tenant patterns If you're building a platform where multiple end users connect to the same source, `external_id` is how you keep track of which credential belongs to which user. The simplest pattern. Each user in your system has a single credential per source. Use your internal user ID as the `external_id`. ```json theme={null} { "source_id": "src_utility", "external_id": "user_12345", "auth_method": "username_password", "auth_credentials": { ... } } ``` To find a user's credential later: ```bash theme={null} curl "https://api.deck.co/v2/credentials?source_id=src_utility&external_id=user_12345" \ -H "Authorization: Bearer sk_live_..." ``` Some users may need multiple credentials to the same source (e.g., multiple utility accounts). Use a composite identifier. ```json theme={null} { "source_id": "src_utility", "external_id": "user_12345:home", "auth_method": "username_password", "auth_credentials": { ... } } ``` Or use your own account-level identifier: ```json theme={null} { "source_id": "src_utility", "external_id": "account_67890", "auth_method": "username_password", "auth_credentials": { ... } } ``` For B2B platforms, map credentials to organizations or teams rather than individual users. ```json theme={null} { "source_id": "src_payroll", "external_id": "org_acme_corp", "auth_method": "username_password", "auth_credentials": { ... } } ``` This lets you query all credentials for an organization: ```bash theme={null} curl "https://api.deck.co/v2/credentials?external_id=org_acme_corp" \ -H "Authorization: Bearer sk_live_..." ``` ## Updating an external ID You can update the `external_id` on an existing credential: ```bash theme={null} curl -X PATCH "https://api.deck.co/v2/credentials/{credential_id}" \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "external_id": "new_user_id" }' ``` Set it to `null` to remove the mapping: ```json theme={null} { "external_id": null } ``` ## External IDs in events When a credential triggers an event (e.g., `credential.verified`), the event payload includes the credential's `external_id`. This lets you route event processing to the right user in your system without an extra API call. ```json theme={null} { "id": "evt_abc", "type": "credential.verified", "data": { "id": "cred_def", "object": "credential", "external_id": "user_12345", "status": "verified" } } ``` Use this to look up the user in your database and take action (send a notification, update a record, trigger a downstream process) without needing to call `GET /v2/credentials/{credential_id}`. ## Best practices * **Set `external_id` at creation time.** It's easier to set it upfront than to backfill later. * **Use stable identifiers.** Choose IDs that won't change, like your database primary key or a UUID. Avoid using emails or usernames that users can modify. * **Keep it consistent.** Use the same `external_id` format across all credentials for a given user. If you use `user_12345` for one source, use it for all sources. * **Use it for filtering.** The [list credentials](/api/filtering-list-endpoints) endpoint supports filtering by `external_id`, making it easy to find all credentials for a specific user. You can also search by `external_id` in the Console. # Filtering list endpoints Source: https://docs.deck.co/api/filtering-list-endpoints Narrow down API results using query parameters on list endpoints. Most list endpoints accept query parameters that let you filter results server-side. This is more efficient than fetching everything and filtering in your application. All filters are combined with AND logic. Every list endpoint also supports [cursor-based pagination](/api/pagination) via the `limit` and `cursor` parameters. Some filters accept multiple values as a comma-separated list and match any of them: `status`, `source_id`, and `outcome` on task runs; `source_id` and `status` on credentials; and `type` on events. ## Filters by endpoint `GET /v2/credentials` Return only credentials for a specific source. Filter by credential status. One of `unverified`, `verified`, `invalid`, `deleted`. Filter by the external ID you assigned when creating the credential. Useful for finding all credentials belonging to a specific user in your system. ```bash theme={null} curl "https://api.deck.co/v2/credentials?source_id=src_abc&status=verified" \ -H "Authorization: Bearer sk_live_..." ``` `GET /v2/tasks` Return only tasks belonging to a specific agent. Filter by task status. One of `learning`, `test`, `live`. ```bash theme={null} curl "https://api.deck.co/v2/tasks?agent_id=agt_abc&status=live" \ -H "Authorization: Bearer sk_live_..." ``` `GET /v2/task-runs` Filter by agent. Filter by credential. Returns only runs that used a specific credential. Filter by source. Filter by task. Filter by run status. One of `queued`, `running`, `canceling`, `interaction_required`, `review_required`, `completed`, `canceled`, `failed`. Filter by run result. One of `success`, `failure`, `unknown`. Maps to the `result` field on the task run object. Return runs created after this timestamp (ISO 8601). Return runs created before this timestamp (ISO 8601). Free-text search matching task name, task ID, or task run ID. ```bash theme={null} curl "https://api.deck.co/v2/task-runs?agent_id=agt_abc&status=completed&outcome=success&created_after=2026-01-01T00:00:00Z" \ -H "Authorization: Bearer sk_live_..." ``` `GET /v2/event-destinations/{destination_id}/event-deliveries` Filter by delivery status. One of `success`, `failure`. Filter by event type, e.g. `task_run.completed`. ```bash theme={null} curl "https://api.deck.co/v2/event-destinations/evtd_abc/event-deliveries?status=failure&type=task_run.completed" \ -H "Authorization: Bearer sk_live_..." ``` `GET /v2/events` Filter by event type (e.g., `task_run.completed`, `credential.verified`). Return events created after this timestamp (ISO 8601). Return events created before this timestamp (ISO 8601). ```bash theme={null} curl "https://api.deck.co/v2/events?type=task_run.completed" \ -H "Authorization: Bearer sk_live_..." ``` ## Endpoints without filters The following list endpoints only support pagination (`limit` and `cursor`) with no additional filters: * `GET /v2/agents` * `GET /v2/sources` ## Combining filters with date ranges For endpoints that support `created_after` and `created_before`, you can combine them to query a specific window of time. ```bash theme={null} curl "https://api.deck.co/v2/task-runs?created_after=2026-06-01T00:00:00Z&created_before=2026-06-30T23:59:59Z&status=failed" \ -H "Authorization: Bearer sk_live_..." ``` This returns all failed task runs from June 2026. Combine date ranges with other filters to build precise queries for dashboards, reports, or debugging. Both bounds are inclusive, so a record created exactly at the `created_after` or `created_before` timestamp is returned. Always send timestamps in UTC ISO 8601 with a trailing `Z` (for example, `2026-06-01T00:00:00Z`) so results are consistent across endpoints. ## Tips * **Filter server-side.** Fetching all records and filtering in your app wastes bandwidth and API quota. * **Combine filters.** All query parameters are AND-combined, so adding more filters narrows results. * **Use date ranges for historical queries.** `created_after` and `created_before` are the most efficient way to pull data for a time window. * **Pair with pagination.** Large result sets should use `limit` and `cursor` together with filters. See the [pagination guide](/api/pagination) for details. Navigate large result sets with cursor-based pagination. Authentication, base URLs, and request conventions. # Idempotency Source: https://docs.deck.co/api/idempotency Safely retry requests without performing the same operation twice. All `POST`, `PATCH`, and `DELETE` requests accept an `Idempotency-Key` header. Retry with the same key and Deck returns the original response instead of performing the operation again. `GET` requests are naturally idempotent and do not require a key. ## How it works Include an `Idempotency-Key` header on any `POST`, `PATCH`, or `DELETE` request. ```bash theme={null} curl -X POST https://api.deck.co/v2/agents \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \ -d '{ "name": "Hotel Reservations" }' ``` When Deck receives a request with an idempotency key and the request succeeds, it caches the response and associates it with that key. Only successful responses are cached. If the original request returned an error, retrying with the same key will execute the request again. Keys are scoped to your organization, so different organizations can use the same key independently. If the same key is sent again: * Same parameters: Deck returns the cached response. The operation is not repeated. * Different parameters: Deck returns a `409 Conflict` with an `idempotency_error` to prevent accidental misuse. * After 24 hours: the key expires and can be reused. ## When to use them Use idempotency keys on any create operation where a duplicate would cause problems: | Operation | Why | | ------------------------------- | ------------------------------------------------ | | Storing a credential | Prevents duplicate credentials for the same user | | Running a task | Prevents the same task from executing twice | | Creating agents, sources, tasks | Prevents duplicate resources | | Creating event destinations | Prevents duplicate webhook subscriptions | | Updating or deleting resources | Guarantees the operation happens exactly once | You don't need idempotency keys for `GET` requests. Reads are naturally idempotent. ## Key format Keys can be any string up to 256 characters. Keys longer than 256 characters are rejected with a `400` error. ```text theme={null} Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000 ``` Common patterns: | Pattern | Example | When to use | | ------------------ | -------------------------------------- | -------------------------------------------- | | Business logic key | `user_456_run_task_789` | When the operation maps to a domain action | | Request identifier | `req_20260218_abc123` | When you track requests in your system | | UUID | `550e8400-e29b-41d4-a716-446655440000` | When you need a guaranteed-unique random key | ## Generating keys ```javascript Node.js (UUID) theme={null} const { randomUUID } = require('crypto') const idempotencyKey = randomUUID() ``` ```javascript Node.js (business key) theme={null} const idempotencyKey = `user_${userId}_run_${taskId}` ``` ```python Python (UUID) theme={null} import uuid idempotency_key = str(uuid.uuid4()) ``` ```python Python (business key) theme={null} idempotency_key = f"user_{user_id}_run_{task_id}" ``` ## Retry pattern A typical retry flow with idempotency: ```javascript theme={null} async function createAgent(name, retries = 3) { const idempotencyKey = `create_agent_${name}` for (let attempt = 1; attempt <= retries; attempt++) { try { const res = await fetch('https://api.deck.co/v2/agents', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.DECK_API_KEY}`, 'Content-Type': 'application/json', 'Idempotency-Key': idempotencyKey, }, body: JSON.stringify({ name }), }) return await res.json() } catch (err) { if (attempt === retries) throw err await new Promise(r => setTimeout(r, 1000 * attempt)) } } } ``` The key stays the same across retries. If the first request succeeded but the response was lost, the second request returns the cached result. If the first request failed or never reached the server, the second one executes normally since only successful responses are cached. ## Error handling **Key reuse with different parameters** returns HTTP `409`: ```json theme={null} { "errors": [ { "type": "idempotency", "code": "idempotency_error", "message": "Idempotency key has already been used with different parameters." } ], "request_id": "req_a1b2c3d4..." } ``` If you see this error, use a new key for the new request. **Key exceeds 256 characters** returns HTTP `400`: ```json theme={null} { "errors": [ { "type": "idempotency", "code": "idempotency_key_error", "message": "Idempotency key must be at most 256 characters" } ], "request_id": "req_a1b2c3d4..." } ``` # Pagination Source: https://docs.deck.co/api/pagination Page through list endpoint results using cursor-based pagination. All list endpoints in the Deck API use cursor-based pagination. Each response includes a `data` array, a `has_more` flag, and a `next_cursor` value you pass on subsequent requests to fetch the next page. ## Request parameters | Parameter | Type | Default | Description | | --------- | ------- | ------- | --------------------------------------------------------- | | `limit` | integer | 20 | Number of results per page. Min 1, max 100. | | `cursor` | string | | Cursor from a previous response. Omit for the first page. | ```bash theme={null} curl "https://api.deck.co/v2/agents?limit=50" \ -H "Authorization: Bearer sk_live_your_key_here" ``` ## Response format Every list response has the same shape: Array of resource objects for the current page. `true` if there are more results beyond this page. `false` on the last page. An opaque string to pass as the `cursor` query parameter on the next request. `null` when there are no more pages. Unique identifier for the API request. ```json theme={null} { "data": [ { "id": "agt_abc...", "object": "agent", "name": "Hotel Reservations" }, { "id": "agt_def...", "object": "agent", "name": "Expense Reports" } ], "has_more": true, "next_cursor": "eyJpZCI6ImFnZW50X2RlZiJ9", "request_id": "req_a1b2c3d4..." } ``` ## Fetching the next page Pass `next_cursor` from the previous response as the `cursor` query parameter: ```bash theme={null} curl "https://api.deck.co/v2/agents?limit=50&cursor=eyJpZCI6ImFnZW50X2RlZiJ9" \ -H "Authorization: Bearer sk_live_your_key_here" ``` Continue until `has_more` is `false`. ## Paginating through all results ```javascript Node.js theme={null} async function fetchAll(endpoint) { const results = [] let cursor = null do { const url = new URL(`https://api.deck.co/v2/${endpoint}`) url.searchParams.set('limit', '100') if (cursor) url.searchParams.set('cursor', cursor) const res = await fetch(url, { headers: { 'Authorization': `Bearer ${process.env.DECK_API_KEY}` }, }) const page = await res.json() results.push(...page.data) cursor = page.next_cursor } while (cursor) return results } const allAgents = await fetchAll('agents') ``` ```python Python theme={null} import requests def fetch_all(endpoint): results = [] cursor = None while True: params = {"limit": 100} if cursor: params["cursor"] = cursor res = requests.get( f"https://api.deck.co/v2/{endpoint}", headers={"Authorization": f"Bearer {DECK_API_KEY}"}, params=params, ) page = res.json() results.extend(page["data"]) if not page["has_more"]: break cursor = page["next_cursor"] return results all_agents = fetch_all("agents") ``` ```go Go theme={null} func fetchAll(endpoint string) ([]json.RawMessage, error) { var results []json.RawMessage cursor := "" for { u := fmt.Sprintf("https://api.deck.co/v2/%s?limit=100", endpoint) if cursor != "" { u += "&cursor=" + cursor } req, _ := http.NewRequest("GET", u, nil) req.Header.Set("Authorization", "Bearer "+os.Getenv("DECK_API_KEY")) resp, err := http.DefaultClient.Do(req) if err != nil { return nil, err } defer resp.Body.Close() var page struct { Data []json.RawMessage `json:"data"` HasMore bool `json:"has_more"` NextCursor *string `json:"next_cursor"` } json.NewDecoder(resp.Body).Decode(&page) results = append(results, page.Data...) if !page.HasMore || page.NextCursor == nil { break } cursor = *page.NextCursor } return results, nil } ``` ## Filtering and sorting List endpoints may accept additional query parameters for filtering. Filters are applied server-side before pagination, so the `limit` applies to filtered results. ```bash theme={null} curl "https://api.deck.co/v2/task-runs?credential_id=cred_abc123&limit=50" \ -H "Authorization: Bearer sk_live_your_key_here" ``` Results are returned in reverse chronological order (newest first) by default. ## Cursors are opaque Cursor values are opaque strings. Do not parse, construct, or store them long-term. They encode internal position state and may change format between API versions. * Pass them exactly as received from the API. * Do not reuse cursors across different endpoints or filter combinations. * If a cursor becomes invalid, the API returns a `400` error with `cursor_invalid`. Start from the first page. ## Stable ordering Deck guarantees stable ordering within a paginated sequence. If no records are created or deleted between requests, every record appears exactly once across all pages. Records created after you begin paginating may or may not appear depending on their position in the sort order. # Rate limits & concurrency Source: https://docs.deck.co/api/rate-limits How Deck rate limits API requests and manages session concurrency. Deck enforces two types of limits: rate limits on API requests and concurrency limits on sessions running in agent sandboxes. ## Limits The rate limit is 200 requests per 10 seconds per organization. Limits are applied across all API keys in your organization. If you have multiple services making requests with different keys, they share the same quota. ## Rate limited responses When a request is rate limited, Deck returns: ```json theme={null} { "errors": [ { "type": "rate_limit", "code": "rate_limit_exceeded", "message": "Too many requests." } ], "request_id": "req_a1b2c3d4..." } ``` ## Handling rate limits Implement retries with exponential backoff when you receive a `429` response. ```javascript theme={null} async function requestWithBackoff(url, options, retries = 5) { for (let attempt = 0; attempt < retries; attempt++) { const res = await fetch(url, options) if (res.status !== 429) return res const delay = Math.min(1000 * Math.pow(2, attempt), 30000) await new Promise(r => setTimeout(r, delay)) } throw new Error('Rate limit retries exhausted') } ``` ## Session concurrency Each task that Deck runs executes in an agent sandbox tied to a session. The number of sessions your organization can run concurrently depends on your [plan](https://deck.co/pricing). The default limit on the Enterprise plan is 25 concurrent sessions. This limit applies across all sessions in your organization regardless of connector or credential. When you submit a task that would exceed your concurrency limit, Deck returns a `429` status code: ```json theme={null} { "errors": [ { "type": "rate_limit", "code": "session_limit_exceeded", "message": "Agent sandbox limit exceeded." } ], "request_id": "req_a1b2c3d4..." } ``` Retry with backoff until a running session reaches a terminal state and a slot becomes available. ## Best practices * Use events instead of polling. Register an [event destination](/events/events) and let Deck push status updates to you rather than polling `GET` endpoints in a loop. * Paginate list requests. Use `limit` and `cursor` to fetch results in pages rather than requesting large datasets in a single call. * Stagger task submissions. If you have many tasks to run, queue them and submit the next one after the previous completes. Use [events](/events/events) to know when a session finishes rather than polling. # Resource IDs Source: https://docs.deck.co/api/resource-ids How Deck identifies objects across the API. Every object in the Deck API has a unique identifier with a type prefix. The prefix tells you what kind of resource the ID refers to, making it easier to debug, log, and route objects through your system without additional lookups. ## Format All IDs follow the same pattern: ```text theme={null} {type_prefix}_{unique_string} ``` The prefix is always lowercase, followed by an underscore and a unique, case-sensitive string. Treat the full identifier as opaque: match on the prefix to determine the resource type, but don't parse or depend on the format of the random portion, which may change. ## ID Reference | Prefix | Resource | Example | Description | | ---------- | ----------------- | ------------------- | ------------------------------------------------------------------------ | | `agt_` | Agent | `agt_a1b2c3d4` | An automation agent scoped to a use case. | | `src_` | Source | `src_a1b2c3d4` | A website or service your agent connects to. | | `cred_` | Credential | `cred_a1b2c3d4` | Stored authentication details for a user on a source. | | `sess_` | Session | `sess_a1b2c3d4` | An isolated compute session used to execute tasks. | | `task_` | Task | `task_abc123` | A defined action an agent can perform. | | `trun_` | Task Run | `trun_a1b2c3d4` | A single execution of a task. | | `stor_` | Storage Item | `stor_a1b2c3d4` | A file or document captured during a task run. | | `evt_` | Event | `evt_a1b2c3d4` | A lifecycle event emitted by the platform. | | `evtd_` | Event Destination | `evtd_a1b2c3d4` | An endpoint that receives events. | | `req_` | Request | `req_a1b2c3d4` | A unique identifier for an API request, returned in error responses. | | `sk_live_` | API Key | `sk_live_abc123...` | Your API key. Not a resource ID, but follows the same prefix convention. | ## Using prefixed IDs ### Type checking Because the prefix encodes the resource type, you can validate IDs before making API calls. ```javascript theme={null} function getResourceType(id) { const prefix = id.split("_").slice(0, -1).join("_"); const types = { agt: "agent", src: "source", cred: "credential", sess: "session", task: "task", trun: "task_run", stor: "storage", evt: "event", evtd: "event_destination", }; return types[prefix] || null; } ``` ### Logging and debugging Prefixed IDs make it easy to trace activity across resources in your logs. A log entry containing `cred_a1b2c3d4` and `trun_x9y8z7` immediately tells you which credential and task run were involved, without needing to cross-reference separate tables. ### Cross-referencing resources Many API responses include related resource IDs. A task run object, for example, includes `task_id`, `credential_id`, `agent_id`, and `source_id`. The prefixes let you quickly verify the relationships are correct. ```json theme={null} { "id": "trun_a1b2c3d4", "object": "task_run", "task_id": "task_abc123", "credential_id": "cred_a1b2c3d4", "session_id": "sess_a1b2c3d4", "agent_id": "agt_a1b2c3d4", "source_id": "src_a1b2c3d4", "status": "completed" } ``` ## Notes * IDs are immutable. Once assigned, they never change. * IDs are globally unique. You will never see the same ID across different resource types or organizations. * IDs are case-sensitive. `agt_A1B2` and `agt_a1b2` are different identifiers. * Passing an ID with the wrong prefix to an endpoint returns a `400` validation error. * Resource IDs are variable in length but will never exceed 64 characters. API keys (`sk_live_`) are not covered by this bound. # Using the API Source: https://docs.deck.co/api/using-the-api Base URL, authentication, request format, and response conventions. The Deck API is a REST API that accepts JSON request bodies and returns JSON responses. All endpoints require authentication via a Bearer token. ## Base URL All requests are made against the Deck API at: ```text theme={null} https://api.deck.co/v2 ``` ## Authentication Every request requires an API key passed as a Bearer token in the `Authorization` header. Keys are available in your [Console](https://console.deck.co). ```bash theme={null} curl https://api.deck.co/v2/test \ -H "Authorization: Bearer sk_live_your_key_here" ``` ## Verify your key Call the test endpoint to confirm your key is valid. ```bash theme={null} curl https://api.deck.co/v2/test \ -H "Authorization: Bearer sk_live_your_key_here" ``` ```json theme={null} { "status": "ready", "environment": "live", "request_id": "req_a1b2c3d4..." } ``` ## Request format All requests use `Content-Type: application/json`. Pass request bodies as JSON. ```bash theme={null} curl -X POST https://api.deck.co/v2/agents \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "name": "Hotel Reservations", "description": "Fetch and manage hotel bookings" }' ``` Path parameters are part of the URL. Query parameters are used for filtering and pagination on list endpoints. ## Response format Every resource response includes a standard set of fields: ```json theme={null} { "id": "agt_a1b2c3d4...", "object": "agent", "name": "Hotel Reservations", "description": "Fetch and manage hotel bookings", "created_at": "2025-01-15T09:00:00Z", "updated_at": "2025-01-15T09:00:00Z", "request_id": "req_a1b2c3d4..." } ``` | Field | Description | | ------------ | ------------------------------------------------------------------------------------------------------- | | `id` | Unique identifier, prefixed by resource type (`agt_`, `src_`, `cred_`, `sess_`, `task_`, `trun_`, etc.) | | `object` | Resource type as a string. Useful for parsing polymorphic responses. | | `created_at` | ISO 8601 timestamp | | `updated_at` | ISO 8601 timestamp | | `request_id` | Unique identifier for the API request. Include this when contacting support. | Delete responses return a confirmation object: ```json theme={null} { "id": "agt_a1b2c3d4...", "object": "agent", "deleted": true, "request_id": "req_a1b2c3d4..." } ``` ## Request IDs Every response includes a `request_id`. When something goes wrong, include this value in support requests so Deck can trace exactly what happened. ## Next steps Cursor-based pagination for list endpoints. Safely retry requests without creating duplicates. Error structure, types, and codes. Request limits and retry strategies. # Auth Component Source: https://docs.deck.co/components/auth A drop-in React component for secure credential capture, source selection, and authentication.