API Reference
Endpoint-by-endpoint reference for the current Whagons v1 External API.
The External API is the API exposed by keys created in Settings → Integrations → API Keys.
Base URL: https://cvx-share.whagons.com/api/v1
OpenAPI: https://docs.whagons.com/openapi/whagons-v1.jsonNew integrations should use /api/v1/*. The production gateway also serves /api/ext/* as compatibility aliases for existing integrations.
Authentication and scopes
Send a Settings-issued key in either header form:
X-API-Key: whg_live_...Authorization: Bearer whg_live_...| Scope | Allows |
|---|---|
ext:read | Reference-data, task, comment, assignment, tag, and log reads. |
ext:tasks:write | Task creation and mutation, comments, assignments, tags, approval decisions, and acknowledgments. |
Keys currently receive both scopes when created in Settings. Every API-key call acts as the user who created the key and is evaluated against that user's current tenant permissions, teams, workspace visibility, and task access.
Endpoint index
| Method | Path | Scope | Result |
|---|---|---|---|
GET | /me/tenants | user session | Tenants for a signed-in first-party user. API keys are not accepted. |
GET | /workspaces | ext:read | Visible active workspaces. |
GET | /spots | ext:read | Visible physical locations. |
GET | /users | ext:read | Visible active users. |
GET | /categories | ext:read | Task types/categories. |
GET | /statuses | ext:read | Task statuses. |
GET | /priorities | ext:read | Task priorities. |
GET | /teams | ext:read | Teams. |
GET | /templates | ext:read | Task templates. |
GET | /tags | ext:read | Tags. |
GET | /tasks | ext:read | A visible task or a filtered task list. |
POST | /tasks | ext:tasks:write | A newly created task identity. |
PATCH | /tasks | ext:tasks:write | The updated task identity. |
DELETE | /tasks | ext:tasks:write | Soft-delete confirmation. |
GET, POST | /task-comments | read / write | Task notes and attachment notes. |
GET, POST | /task-assignments | read / write | Current assignees or the assignment delta. |
GET, POST | /task-tags | read / write | Current tags or the tag delta. |
GET | /task-logs | ext:read | Newest-first task history. |
POST | /task-approval | ext:tasks:write | Approval or rejection result. |
POST | /task-acknowledgment | ext:tasks:write | Acknowledgment result. |
Paths in the sections below are relative to the v1 base URL.
Request conventions
tenantIdis required on every API-key request. On reads it is a query parameter; on writes it is in the JSON body.tenantIdmust exactly match the tenant attached to the key.- Resource IDs are opaque Convex IDs. Read them from Whagons instead of constructing them.
- Dates such as
dueDateandstartDateare Unix timestamps in milliseconds. - Request bodies use
Content-Type: application/json. - List endpoints currently return JSON arrays directly; responses are not wrapped in a
dataenvelope. - There is not yet a cursor-pagination contract.
GET /tasksinstead accepts a boundedlimit.
Session
GET /me/tenants
Lists tenants for the signed-in first-party Whagons user. This route uses the product's user session and does not accept a tenant API key. Server-to-server integrations normally already know their tenantId and do not need this endpoint.
Reference data
All reference-data calls require tenantId and ext:read. They return arrays of Whagons row objects. Common fields include _id, _creationTime, tenantId, name, and an optional legacy pgId; each resource can include additional configuration fields.
| Endpoint | Optional filters | Integration use |
|---|---|---|
GET /workspaces | — | Use _id as workspaceId. Only active, visible workspaces are returned. |
GET /spots | — | Use _id as spotId. |
GET /users | — | Use _id in userIds, assignedTo, or reporting fields. Only active users are returned. |
GET /categories | workspaceId | Use _id as categoryId. Categories are the task types configured by the tenant. |
GET /statuses | categoryId | Use _id as statusId. Filter by category whenever possible. |
GET /priorities | categoryId | Use _id as priorityId. |
GET /teams | — | Use _id as teamId or reportedByTeamId. |
GET /templates | workspaceId, categoryId | Use _id as templateId. Both filters may be combined. |
GET /tags | — | Use _id with /task-tags. |
Example:
curl --request GET \
--url 'https://cvx-share.whagons.com/api/v1/workspaces?tenantId=hotel-1' \
--header 'X-API-Key: whg_live_REPLACE_ME'Tasks
GET /tasks
With taskId or pgId, returns one visible task object. Without either identity, returns a newest-first array of visible tasks.
| Query parameter | Required | Behavior |
|---|---|---|
tenantId | yes | Tenant attached to the key. |
taskId | no | Fetch one task by its current opaque ID. Takes the detail path when present. |
pgId | no | Fetch one task by its legacy numeric ID. |
workspaceId | no | Match one workspace. |
categoryId | no | Match one task type/category. |
statusId | no | Match one status. |
priorityId | no | Match one priority. |
teamId | no | Match the owning team. |
spotId | no | Match a location. |
templateId | no | Match a task template. |
assignedTo | no | Use me for the key creator or supply a Whagons user ID. |
assignedToMe | no | true is equivalent to assignedTo=me. |
search | no | Case-insensitive match against task name or description. |
limit | no | Integer from 1 to 500; defaults to 100. Values are clamped to that range. |
Task visibility is applied after filters. A caller never receives tasks outside the key creator's current permissions.
POST /tasks
Creates a task and optionally assigns users.
| JSON field | Type | Required | Notes |
|---|---|---|---|
tenantId | string | yes | Tenant attached to the key. |
name | string | yes | Human-readable task title. |
workspaceId | string | yes | ID from /workspaces. |
description | string | no | Task details. |
categoryId | string | no | ID from /categories. |
teamId | string | no | Owning team ID. |
templateId | string | no | Template ID. |
spotId | string | no | Physical location ID. |
statusId | string | no | Initial status ID. |
priorityId | string | no | Priority ID. |
slaId | string | no | SLA ID when that configuration is known to the integration. |
dueDate | number | no | Epoch milliseconds. |
startDate | number | no | Epoch milliseconds. |
latitude, longitude | number | no | Optional coordinates. |
reportedByTeamId | string | no | Reporting-team context. |
reportedByUserId | string | no | Reporting-user context. |
userIds | string[] | no | Users to assign during creation. |
Minimal body:
{
"tenantId": "hotel-1",
"name": "Inspect room 304",
"workspaceId": "j57..."
}Response:
{
"id": "j97...",
"pgId": 1234
}pgId can be null or absent when no legacy numeric identity exists.
PATCH /tasks
Requires tenantId and taskId. Put changes in updates, or send the same update fields at the top level. When updates is present, it is used as the update source.
{
"tenantId": "hotel-1",
"taskId": "j97...",
"updates": {
"description": "Updated from automation",
"statusId": "s12...",
"priorityId": "p34..."
}
}Allowed fields are name, description, statusId, priorityId, teamId, spotId, categoryId, templateId, dueDate, startDate, latitude, and longitude. Nullable fields can be sent as null to clear them. Unknown fields are ignored by the current handler.
The result includes taskId. Status changes and field updates still pass normal workflow, team, approval-lock, and field-permission checks.
DELETE /tasks
Soft-deletes a task. Send both identifiers as query parameters:
DELETE /tasks?tenantId=hotel-1&taskId=j97...The handler also accepts the identifiers in a JSON body for compatibility. A successful response is:
{
"ok": true,
"taskId": "j97..."
}Task subresources
Every read below requires tenantId and taskId as query parameters. Every write requires them in the JSON body. The task must be visible to the key creator.
Comments and attachment notes
GET /task-comments returns task notes from oldest to newest.
POST /task-comments accepts:
| Field | Required | Notes |
|---|---|---|
tenantId, taskId | yes | Task identity. |
note | no | Comment text. |
source | no | comment by default, or task_attachment. |
attachments | no | Array of { storageId, fileName, fileSize, fileType }. Storage IDs must already be valid. |
mentionedUserIds | no | Array of user IDs referenced by the note. |
The response contains the new note id and taskId.
Assignments
GET /task-assignments returns the task's assignment rows.
POST /task-assignments requires a non-empty userIds array. mode is set by default and can be add or remove. The response contains taskId, plus added and removed user-ID arrays.
Set replaces the complete assignment set
Use add or remove when another person or integration may be changing assignments concurrently. An assignment request cannot use an empty userIds array.
Tags
GET /task-tags returns the task's tag-link rows.
POST /task-tags accepts tagIds and a mode of set (default), add, or remove. Unlike assignments, tagIds may be empty; mode: "set" with an empty array clears all tags. The response contains taskId, added, and removed tag-ID arrays.
Logs
GET /task-logs returns task log rows newest first. Logs reflect changes made in both Whagons and the External API.
Approval decisions
POST /task-approval requires decision: "approved" | "rejected" and accepts optional contextId, comment, and signatureStorageId.
{
"tenantId": "hotel-1",
"taskId": "j97...",
"contextId": "workspace-context-id",
"decision": "approved",
"comment": "Reviewed and approved"
}Approvals belong to a workspace context on the source task. They are not duplicated action tasks. Omit contextId only when the intended context is unambiguous.
Acknowledgments
POST /task-acknowledgment accepts optional contextId and comment:
{
"tenantId": "hotel-1",
"taskId": "j97...",
"contextId": "workspace-context-id",
"comment": "Acknowledged"
}OpenAPI
The versioned, machine-readable description is available at /openapi/whagons-v1.json. It can be imported into API clients, code generators, or testing tools.
The prose guide is the operational source for permission and workflow behavior; OpenAPI is the request-and-response contract. Changes to either are recorded in the API changelog.
Compatibility routes
The same handlers remain available at /api/ext/*. New clients should use /api/v1/*, and existing clients should follow the migration guide.