> For the complete documentation index, see [llms.txt](https://docs.taskade.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.taskade.com/developers/api-v2-reference.md).
# Action API v2 Reference
Reference for the Public API v2 â an action-based (RPC-over-HTTP) API. Every call is a POST to a named operation, with cURL, Python, and TypeScript examples.
The Public API **v2** is an **action-based** API: every operation is a `POST` to a named endpoint (`/listSpaces`, `/promptAgent`, `/createProject`), with a JSON body. It is not RESTful â there are no `GET /workspaces` or `PUT /tasks/{id}` style routes. (The only REST-style exceptions: media/bundle downloads and the [webhook registration](/developers/webhooks.md#webhook-registration-api) routes.)
{% hint style="info" %}
**v2 is in beta and runs alongside v1.** v2 is simpler and adds capabilities v1 lacks â most notably **`promptAgent`**. But v2 does **not** cover everything: tasks are **read-only** in v2, and there is no project-update endpoint. For full task CRUD (create/update/delete, assignees, dates, notes, fields) use the [REST API v1](/developers/comprehensive-api-guide.md). See [Which API should I use?](#which-api-should-i-use) below.
{% endhint %}
The live OpenAPI spec is published at [taskade.com/api/documentation/v2](https://www.taskade.com/api/documentation/v2).
## Table of Contents
* [Which API should I use?](#which-api-should-i-use)
* [Base URL & Authentication](#base-url-and-authentication)
* [Calling convention](#calling-convention)
* [Endpoints](#endpoints)
* [Pagination](#pagination)
* [Rate Limits](#rate-limits)
* [Error Handling](#error-handling)
* [Security Best Practices](#security-best-practices)
***
## Which API should I use?
Taskade ships **two** public HTTP APIs. They share the same authentication.
| | **REST API v1** | **Action API v2** |
| -------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- |
| Base URL | `https://www.taskade.com/api/v1` | `https://www.taskade.com/api/v2` |
| Style | RESTful (`GET`/`POST`/`PUT`/`DELETE`) | Action / RPC (`POST /{operation}`) |
| Status | Stable (GA) | Beta (`2.0.0-beta`) |
| Live spec | [/api/documentation/v1](https://www.taskade.com/api/documentation/v1) | [/api/documentation/v2](https://www.taskade.com/api/documentation/v2) |
| Task create / update / delete | â
Full CRUD | â Read-only (`listTasks`, `listBlocks`) |
| Task assignees / dates / notes / fields | â
| â |
| Project update | â
| â (create / complete / restore / copy only) |
| Prompt an agent | â | â
`promptAgent` |
| Agent lifecycle (create/update/delete) | Partial | â
|
| Bundles (export/import Taskade Genesis apps) | â | â
|
| Signed webhook registration | â | â
`POST /webhooks` |
| Reference | [Comprehensive API Guide](/developers/comprehensive-api-guide.md) | This page |
**Rule of thumb:** reach for **v1** when you need to write tasks or manage task metadata; reach for **v2** for agent prompting, agent lifecycle, bundles, and simpler list/read flows.
***
## Base URL & Authentication
All v2 operations live under:
```
https://www.taskade.com/api/v2
```
Authenticate with a **Personal Access Token** from [taskade.com/settings/api](https://www.taskade.com/settings/api), or an **OAuth 2.0 access token** for apps that act on behalf of other users:
```bash
Authorization: Bearer YOUR_TOKEN
```
See the [Authentication guide](/developers/authentication.md) for personal tokens vs. OAuth 2.0 (PKCE) details.
***
## Calling convention
Every v2 call is a `POST` to an operation name, with a JSON body and a JSON response. Successful responses are wrapped in `{ "ok": true, ... }`.
Here is a single Action API v2 call, from authentication to JSON response.
```mermaid
sequenceDiagram
participant C as Client
participant T as Taskade Action API v2
Note over C: Authenticate with PAT or OAuth 2.0 token
C->>T: POST /operation with Bearer token and JSON body
T->>T: Process operation
alt Success
T-->>C: JSON response, ok true
else Error
T-->>C: JSON error, ok false, message and code
end
```
```bash
curl -X POST https://www.taskade.com/api/v2/OPERATION \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "param": "value" }'
```
A typical response:
```json
{ "ok": true, "items": [ /* ... */ ] }
```
{% hint style="info" %}
**Receiving events:** register a **signed** outbound webhook with `POST /api/v2/webhooks` (Pro and above) â Taskade signs every delivery with an HMAC secret you can verify. See the [Webhook Registration API](/developers/webhooks.md#webhook-registration-api). The older `subscribeWebhook` / `unsubscribeWebhook` operations are deprecated.
{% endhint %}
***
## Endpoints
### List spaces (workspaces)
**`POST /listSpaces`** â every integration's entry point. Body is optional.
{% tabs %}
{% tab title="cURL" %}
```bash
curl -X POST https://www.taskade.com/api/v2/listSpaces \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
{% endtab %}
{% tab title="Python" %}
```python
import requests
res = requests.post(
"https://www.taskade.com/api/v2/listSpaces",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={},
)
print(res.json()["items"])
```
{% endtab %}
{% tab title="TypeScript" %}
```typescript
const res = await fetch("https://www.taskade.com/api/v2/listSpaces", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TASKADE_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
const { items } = await res.json();
```
{% endtab %}
{% endtabs %}
Filter with `{ "filterBy": { "name": { "operator": "contains", "value": "Marketing" } } }`.
***
### List folders in a space
**`POST /listFolders`**
```bash
curl -X POST https://www.taskade.com/api/v2/listFolders \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "spaceId": "SPACE_ID" }'
```
***
### List projects in a space
**`POST /listProjects`**
```bash
curl -X POST https://www.taskade.com/api/v2/listProjects \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "spaceId": "SPACE_ID" }'
```
***
### Get a project
**`POST /getProject`** â returns `{ ok, item: { id, name } }`.
```bash
curl -X POST https://www.taskade.com/api/v2/getProject \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "projectId": "PROJECT_ID" }'
```
***
### Create a project
**`POST /createProject`** â seed a project from Markdown.
{% tabs %}
{% tab title="cURL" %}
```bash
curl -X POST https://www.taskade.com/api/v2/createProject \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"spaceId": "SPACE_ID",
"contentType": "text/markdown",
"content": "# Q2 Planning\n\n- Review roadmap\n- Draft OKRs"
}'
```
{% endtab %}
{% tab title="Python" %}
```python
import requests
res = requests.post(
"https://www.taskade.com/api/v2/createProject",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={
"spaceId": "SPACE_ID",
"contentType": "text/markdown",
"content": "# Q2 Planning\n\n- Review roadmap\n- Draft OKRs",
},
)
print(res.json()["item"]["id"])
```
{% endtab %}
{% endtabs %}
***
### List tasks (read-only)
**`POST /listTasks`** â paginated with `after` / `before` cursors. Each task is `{ id, text, parentId?, completed }`.
```bash
curl -X POST https://www.taskade.com/api/v2/listTasks \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "projectId": "PROJECT_ID", "limit": 100 }'
```
{% hint style="info" %}
To **create, update, complete, or delete** tasks â or set assignees, dates, notes, and custom fields â use the [REST API v1 Tasks endpoints](/developers/comprehensive-api-guide/tasks.md). v2 is read-only for tasks.
{% endhint %}
***
### Prompt an agent
**`POST /promptAgent`** â send a single prompt to a workspace agent and get a synchronous text response. This capability is **v2-only**.
{% tabs %}
{% tab title="cURL" %}
```bash
curl -X POST https://www.taskade.com/api/v2/promptAgent \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"spaceId": "SPACE_ID",
"agentId": "AGENT_ID",
"prompt": "Summarize yesterday'\''s standup notes"
}'
```
{% endtab %}
{% tab title="Python" %}
```python
import requests
res = requests.post(
"https://www.taskade.com/api/v2/promptAgent",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={
"spaceId": "SPACE_ID",
"agentId": "AGENT_ID",
"prompt": "Summarize yesterday's standup notes",
},
)
print(res.json()["summary"])
```
{% endtab %}
{% tab title="TypeScript" %}
```typescript
const res = await fetch("https://www.taskade.com/api/v2/promptAgent", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TASKADE_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ spaceId, agentId, prompt: "Summarize standup notes" }),
});
const { summary } = await res.json();
```
{% endtab %}
{% endtabs %}
**Response:**
```json
{ "ok": true, "summary": "Here's a summary of the standup..." }
```
To review past conversations, use **`POST /listConversations`** (`{ agentId, limit?, page? }`) and **`POST /getConversation`** (`{ agentId, convoId, includeTranscript? }`). Pass `"includeTranscript": true` to get a Markdown `transcript` of the conversation in the response.
***
### Manage agents
| Operation | Body |
| ------------------------------- | ----------------------------------------------------------- |
| `POST /listAgents` | `{ spaceId, filterBy? }` |
| `POST /getAgent` | `{ agentId }` |
| `POST /createAgent` | `{ folderId, name, data }` |
| `POST /updateAgent` | `{ agentId, name?, data? }` |
| `POST /deleteAgent` | `{ agentId }` |
| `POST /generateAgent` | `{ folderId, text }` â generate an agent from a description |
| `POST /enablePublicAgentAccess` | `{ agentId }` â `{ ok, publicUrl }` |
***
### Attach knowledge to an agent
**`POST /addKnowledgeProject`** grounds an agent in a project. (`removeKnowledgeProject`, `addKnowledgeMedia`, `removeKnowledgeMedia` mirror it.)
```bash
curl -X POST https://www.taskade.com/api/v2/addKnowledgeProject \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "agentId": "AGENT_ID", "projectId": "PROJECT_ID" }'
```
***
### Export / import a bundle
**`POST /exportBundle`** returns a portable Genesis app bundle; **`POST /importBundle`** installs one. See [Bundles & App Kits](/developers/bundles.md) for the full schema and the binary `.tsk` variants.
```bash
curl -X POST https://www.taskade.com/api/v2/exportBundle \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "spaceId": "SPACE_ID" }'
```
***
### Full operation list
* **Workspaces & structure:** `listSpaces`, `listFolders`, `listMyProjects`, `listTemplates`, `listMedia`.
* **Projects:** `listProjects`, `getProject`, `createProject`, `createProjectFromTemplate`, `copyProject`, `completeProject`, `restoreProject`, `listTasks`, `listBlocks`, `listFields`, `listProjectMembers`, `getShareLink`, `enableShareLink`.
* **Agents:** `listAgents`, `getAgent`, `createAgent`, `updateAgent`, `deleteAgent`, `promptAgent`, `generateAgent`, `listConversations`, `getConversation`, `addKnowledgeProject`, `removeKnowledgeProject`, `addKnowledgeMedia`, `removeKnowledgeMedia`, `enablePublicAgentAccess`, `getPublicAgent`, `updatePublicAgent`.
* **Media:** `uploadMedia`, `getMedia`, `deleteMedia`, plus `GET /media/{mediaId}/content` and `GET /media/spaces/{spaceId}/content` for downloads.
* **Bundles:** `exportBundle`, `importBundle`, `importBundleZip`, plus `GET /bundles/{spaceId}/export/zip`.
* **Webhooks:** `POST /webhooks`, `GET /webhooks`, `GET /webhooks/{id}`, `DELETE /webhooks/{id}` (signed â see [Webhooks](/developers/webhooks.md#webhook-registration-api)); `subscribeWebhook` and `unsubscribeWebhook` are deprecated.
The authoritative, always-current list is the [live v2 spec](https://www.taskade.com/api/documentation/v2).
***
## Pagination
List operations that can return many rows use **cursor pagination** with `after` / `before` (tasks, blocks) or `page` / `limit` (members, conversations).
```bash
# next page of tasks
curl -X POST https://www.taskade.com/api/v2/listTasks \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "projectId": "PROJECT_ID", "limit": 100, "after": "LAST_TASK_ID" }'
```
***
## Rate Limits
Requests are rate-limited per token.
| Response | Meaning | Action |
| ----------------------- | ------------------- | --------------------------------------------- |
| `429 Too Many Requests` | Rate limit exceeded | Respect `Retry-After`, back off exponentially |
```typescript
async function withRetry