Personal Access Tokens
Authenticate as yourself against the Workspace API using a personal access token.
Overview
Personal access tokens (PATs) let you call the Workspace API authenticated as your user. They're ideal for personal scripts, CLI tools, and CI/CD pipelines where actions should be attributed to you.
User-scoped — PATs are tied to your account, not to a single workspace. One token can access any workspace you belong to by passing the X-Workspace-Id header.
Prefixed with gcp_ — easy to identify in logs and environment variables. (Agent tokens use gca_.)
Optional expiration — tokens can be created with a 30-, 60-, 90-day, or 1-year expiry, or with no expiration at all.
Create a token
- Open Account Settings from your profile menu.
- Scroll to the Personal Access Tokens section.
- Click Create a personal access token.
- Enter a descriptive name (e.g. “CLI”, “CI/CD pipeline”, “Script”).
- Choose an expiration period (or leave it as “No expiration”).
- Click Create token. Your token will be displayed once — copy it immediately.
Authenticate
Pass your PAT as a Bearer token in the Authorization header, along with an X-Workspace-Id header for the target workspace:
curl -H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
https://groupchat.ai/api/v1/tasksThe server resolves your user identity from the token and uses the workspace from the header for the request scope.
Specifying the workspace (required)
400 Missing X-Workspace-Id header.X-Workspace-Id: <your-workspace-id>
You can find your workspace ID in the URL when viewing any project (the first path segment after /workspace/), or from the workspace settings page.
Examples
List tasks
curl -H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
https://groupchat.ai/api/v1/tasksCreate a task
curl -X POST \
-H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{"title": "Ship new feature", "projectId": "PROJECT_ID"}' \
https://groupchat.ai/api/v1/tasksList projects
curl -H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
https://groupchat.ai/api/v1/projectsEnvironment variable setup
# Store in your shell profile or CI secrets
export GROUPCHAT_TOKEN="gcp_YOUR_TOKEN"
export GROUPCHAT_WORKSPACE="YOUR_WORKSPACE_ID"
# Then use in scripts
curl -H "Authorization: Bearer $GROUPCHAT_TOKEN" \
-H "X-Workspace-Id: $GROUPCHAT_WORKSPACE" \
https://groupchat.ai/api/v1/tasksTask field reference
The full task schema is documented in the API reference under Task. Every settable field is always returned in GET /tasks responses (with explicit null when unset), so you can discover the schema by inspecting any task.
| Field | Type | Settable? | Notes |
|---|---|---|---|
| id | string | read-only | Convex document ID. |
| workspaceId | string | read-only | Always matches the X-Workspace-Id header. |
| projectId | string | null | create-only | Set on POST; cannot be moved between projects. |
| stageId | string | null | POST + PATCH | The kanban column the task lives in. |
| title | string | POST + PATCH | |
| description | string | null | POST + PATCH | |
| ownerId | string | null | POST + PATCH | User ID of the assignee. Pass null in PATCH to unassign. |
| creatorId | string | read-only | Whoever created the task. "api" for unattributed creates. |
| completed | boolean | PATCH | Read-only in responses (derived from completedAt). Pass true/false in PATCH to mark complete or reopen — the task is auto-moved to the nearest done/todo column when one exists. |
| completedAt | number | null | read-only | Unix ms when completed. |
| dueDate | number | null | POST + PATCH | Unix ms. Pass null in PATCH to clear. |
| dueTime | number | null | POST + PATCH | Unix ms. |
| estimate | number | null | POST + PATCH | Story points or hours. |
| order | number | read-only | Position within its column. |
| createdAt / updatedAt / lastActivityAt | number | read-only | Unix ms timestamps. |
| source | "manual" | "widget" | "sentry" | null | read-only | How the task was created. |
Fields not in this table (e.g. internal repeat-rule columns, autoAssignAgent*) are not part of the public API surface and may change without notice.
Deleting tasks
The REST-conventional path-param form is the recommended way to delete a task:
curl -X DELETE \
-H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
https://groupchat.ai/api/v1/tasks/TASK_IDFor backwards compatibility, the body-based form on DELETE /api/v1/tasks with { "id": "..." } still works, but new integrations should use the path-param variant.
Bulk operations
Use POST /api/v1/tasks/batch to apply up to 200 task updates or deletes in a single request. Each operation is processed independently — the endpoint always returns 200, and per-operation success is reported via the ok flag on each result.
Bulk unassign and move tasks
curl -X POST \
-H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"operations": [
{ "op": "update", "id": "TASK_1", "ownerId": null, "stageId": "TODO_STAGE" },
{ "op": "update", "id": "TASK_2", "ownerId": null, "stageId": "TODO_STAGE" },
{ "op": "delete", "id": "TASK_3" }
]
}' \
https://groupchat.ai/api/v1/tasks/batchResponse shape
{
"results": [
{ "ok": true, "op": "update", "id": "TASK_1", "task": { ... } },
{ "ok": true, "op": "update", "id": "TASK_2", "task": { ... } },
{ "ok": false, "op": "delete", "id": "TASK_3", "error": "Task not found" }
]
}Update operations accept the same fields as PATCH /tasks: title, description, ownerId, stageId, dueDate, dueTime, estimate, and completed. Pass null on nullable fields to clear them.
Filtering tasks
GET /api/v1/tasks supports two optional query filters:
projectId— return tasks in a specific project.stageId— return tasks in a specific status / kanban column. Combine withprojectIdto scope, otherwise the stage’s project is resolved automatically.
curl -H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
"https://groupchat.ai/api/v1/tasks?stageId=STAGE_ID"Naming: name vs title
Different resources use different field names for their human-readable label, for historical reasons. There’s only one canonical field per resource:
- Projects use
name(e.g.POST /projects { "name": "..." }). - Statuses / stages (kanban columns) use
title(e.g.POST /statuses { "title": "..." }). - Tasks use
title.
You can ignore any name: null you see on a status response — that field isn’t part of the schema and will be removed in a future release.
Delegate a task to your agent
You can hand a task off to one of your custom agents from a script — the same flow as picking your agent in the task owner picker. Discover your agents with GET /api/v1/agents, then call POST /api/v1/agents/delegate with the agent’s agentUserId and a taskId.
The authenticated user becomes the task owner before the run is created — agents work on tasks via runs (agentJobs), never via task ownership. If a run for the same agent and task is already PENDING or RUNNING, the existing run is returned with status: "already_active" instead of creating a duplicate.
List your agents
curl -H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
https://groupchat.ai/api/v1/agentsDelegate a task
curl -X POST \
-H "Authorization: Bearer gcp_YOUR_TOKEN" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{"taskId": "TASK_ID", "agentUserId": "agent-1234abcd...", "prompt": "optional override"}' \
https://groupchat.ai/api/v1/agents/delegateIf prompt is omitted, the task title (and description, if present) is used as the prompt — same as the in-app delegate button.
Token lifecycle
Creation
Tokens are created from Account Settings. The full token value is shown exactly once at creation time. Only the first 12 characters (prefix) are stored for display purposes.
Usage tracking
Each time a token is used, the “Last used” date is updated. This helps you identify unused tokens that can safely be revoked.
Expiration
If you set an expiration, the token stops working after that date. Expired tokens are marked in the UI but not automatically deleted — revoke them when convenient.
Revocation
You can revoke any token at any time from Account Settings. Revocation is immediate — any request using the token will fail with a 401 error.
API reference
See the Workspace API Reference for the full list of available endpoints, request/response schemas, and query parameters.