REST API
Hypertask's public REST API is available at https://app.hypertask.ai/api/v1. Use it to list projects, create and update tasks, manage comments, assign users, read inbox notifications, and manage task drafts.
Authentication
Section titled “Authentication”Send an API key in the Authorization header:
Authorization: Bearer htk_...Create API keys in the Hypertask app with Ctrl+K -> REST API. Each user can have up to 10 active keys. The full key is shown once when it is created, and keys can be revoked from the same modal.
export HT_API_KEY=htk_...
curl -s -H "Authorization: Bearer $HT_API_KEY" \ "https://app.hypertask.ai/api/v1/user/context"Error responses use this general shape:
{ "success": false, "error": "Validation error", "message": "project_id must be a positive integer", "details": { "field": "project_id", "code": "invalid_type" }}Error handling
Section titled “Error handling”Queries that include invalid date parameters receive API-level validation instead of server exceptions. For invalid or malformed updated_since filter values, the API returns HTTP 200 with a clear "invalid date" answer:
200 OKContent-Type: application/json
{ "success": true, "data": [ { "task_id": 123, "title": "Example task", "updated_at": "2026-08-01T10:00:00Z" } ]}Previously, malformed date filters triggered a server crash. Now, the API surface treats malformed dates as user input and handles them gracefully with a sanitized response, maintaining the HTTP 200 shape while clearly communicating that the filter value was not a valid date.
API validation for tasks
Section titled “API validation for tasks”When creating or updating tasks, Hypertask validates required and optional fields at the API level. Invalid inputs return a 400 Bad Request instead of a 500 server error, making it easier for agents and clients to handle failures gracefully:
- Null or empty
descriptionvalues trigger validation errors with a clear message. - Out-of-range values for numeric fields (for example, priority or estimate) are rejected with an explanatory error.
- The API also validates field types; sending a string where a number is expected returns
code: invalid_typein the error details.
This behavior improves robustness of AI-driven workflows by surfacing actionable validation feedback rather than generic server errors.
Example: Invalid task description
400 Bad RequestContent-Type: application/json
{ "success": false, "error": "Validation error", "message": "description cannot be empty", "details": { "field": "description", "code": "required" }}Example: Out-of-range priority
400 Bad RequestContent-Type: application/json
{ "success": false, "error": "Validation error", "message": "priority must be between 0 and 4", "details": { "field": "priority", "code": "out_of_range", "value": 5 }}REST API structure and migration
Section titled “REST API structure and migration”Hypertask's REST API has completed its migration from the legacy Pages Router to the App Router. Writes for key resources (tasks, projects, sections, and notifications) now use the App Router exclusively. The old Routes have been retired once the new-structure flag was fully enabled, eliminating duplicate code paths and simplifying the codebase.
Typed API client
Section titled “Typed API client”A typed client for the REST API is now available behind a feature flag. This client is generated from Zod schemas (and from the OpenAPI spec) and provides full TypeScript types for all API inputs and outputs. Access is initially limited to Owners and QAs, then gradually rolled out more broadly.
Chat session paging, writes, and the OpenAPI description now use the typed client for selected resources (Owners and QAs) behind the flag:typed_client switch. This provides type safety and automatic validation via Zod, and the OpenAPI spec is synchronized in real time from the same schemas.
Benefits:
- Full type safety across client implementations.
- Automatic validation via Zod, reducing runtime errors.
- Generated from a single source of truth (OpenAPI).
Flags:
flag:typed_client— controls typed client exposure (chat session paging and writes, plus OpenAPI).flag:api_router_migration— disperses now; both flags are widely enabled.
Notes:
- The new client uses shared contracts; existing utilities and parsers can depend on the same schemas.
- All derived clients now use the unified App Router endpoints.
- Flags are available per Server instance for Owner/QA preview access during rollout.
Router migration (final state)
Section titled “Router migration (final state)”All writes for these resources now use App Router endpoints:
POST /api/v1/tasks # create/update via App RouterPOST /api/v1/projectsPOST /api/v1/projects/:projectId/sectionsPOST /api/v1/notificationsThe legacy Routes have been retired. The schema and response shapes remain the same as before; existing clients require no change.
Sections and notifications (typed writes)
Section titled “Sections and notifications (typed writes)”A typed writer now handles sectionId and notificationId parameters for sections and notifications, fully integrated with the App Router:
- Sections: Section creates, renames, moves, and deletes use the typed writer.
- Notifications: Reading, marking as unread, archiving, and unarchiving flows use the typed writer.
All these operations now proceed via the consolidated App Router endpoints.
Session validated identity
Section titled “Session validated identity”Previously, several public API routes accepted an unsigned nookies_user cookie as the authenticated user identity. This has been tightened to prevent account takeover via forged cookies:
- Routes that set
nookies_user.idnow require a valid, matching signedht_sessioncookie with the sameidvalue to succeed. - The following route families are affected:
- Auth routes (e.g.,
/api/auth/*) - MCP routes (
/api/mcp/*) - Other 64 public sub-paths previously relying on unsigned nookies_user
- All associated webhook and logged-out call sites
- Auth routes (e.g.,
Verified live on production: forging nookies_user={"id":6} now returns 401 instead of 200+ full data, and forging {"id":1} for any other user also returns 401.
Compatibility: The consensus across the auth, MCP, public, webhook, logged-out, and Bearer-auth request families is that this change does not affect existing integrations or tools:
- Auth requests with standard
Authorization: Bearer $HT_API_KEYcontinue to work. - MCP tools retain their same param schema.
- Public integrations that already manage
ht_sessionvia the app workload continue untouched. - Work that previously shipped
nookies_userdirectly (e.g., via server-to-server calls) should now explicitly sign or addht_sessionwith the sameid, but it is a rare pattern in practice.
If your pattern relies on unsigned nookies_user outside these call sites, see /api/session/verify to validate the signed session instead.
Session paging (Rows)
Section titled “Session paging (Rows)”When fetching sessions via the Sessions rows API and using ?prefer=paged=true, response deltas are now computed from a session history paging key rather than from a historic row snapshot. This ensures accurate incremental updates across large session histories and makes pagination consistent with subsequent API changes on session detail and parent/subtask payloads. The same session history paging key is used to fetch selected transcripts via the .transcripts endpoint.
Board detail and parent/subtask payloads
Section titled “Board detail and parent/subtask payloads”The board detail responses for the Sessions rows API and session detail endpoints now include parent and child subtask payloads directly in the board-level response. This makes it easier for clients to compute relationships and summaries without additional follow-up calls. Parent and child lists are arrays of child task objects (subtasks) always attached to the applicable session and board.