# Whagons documentation (/docs) ## Choose your path [#choose-your-path] ## What you will find here [#what-you-will-find-here] * **Product guides** explain the Whagons operating model without requiring technical background. * **API documentation** follows the API keys created in Whagons under Settings → Integrations. * **Agent documentation** covers delegated `auth.md` access and the built-in Whagons assistant. * **Machine-readable exports** help API clients and AI systems consume the same documentation. Whagons is tenant-aware and permission-bound. Examples may use hotel operations because that is a common Whagons environment, but the same model works for facilities, retail, field service, education, construction, and other operations-heavy teams. ## Machine-readable documentation [#machine-readable-documentation] | Resource | URL | Use | | -------------------- | -------------------------------------------------------------------- | ------------------------------------------------------ | | OpenAPI 3.1 | [`/openapi/whagons-v1.json`](/openapi/whagons-v1.json) | Generate clients and inspect the v1 REST contract. | | Documentation index | [`/llms.txt`](/llms.txt) | Discover public documentation pages from an AI system. | | Full public corpus | [`/llms-full.txt`](/llms-full.txt) | Read the public documentation as one text response. | | Agent authentication | [`https://gon.whagons.com/auth.md`](https://gon.whagons.com/auth.md) | Discover the current user-claimed agent access flow. | Internal maintainer documentation is intentionally separate and access-controlled. # Agent API access (/docs/agents/api-access) An approved agent calls the same public task API used by Settings-issued API keys. The credential and lifecycle differ; endpoint request and response shapes do not. ## Current production endpoints [#current-production-endpoints] ```bash export WHAGONS_API_BASE="https://cvx-share.whagons.com/api/v1" export WHAGONS_AGENT_TOKEN="whg_agent_…" export WHAGONS_TENANT_ID="" ``` The underlying `cvx-share.whagons.com` host is the production HTTP action gateway. Agent access is tenant-specific: the approved claim determines the tenant and user context, and API requests must carry that matching `tenantId`. ## Authenticate [#authenticate] Agent tokens use bearer authentication: ```http Authorization: Bearer whg_agent_… ``` Unlike Settings-issued API keys, an agent token cannot be sent as `X-API-Key`. ## Read visible workspaces [#read-visible-workspaces] ```bash curl "$WHAGONS_API_BASE/workspaces?tenantId=$WHAGONS_TENANT_ID" \ -H "Authorization: Bearer $WHAGONS_AGENT_TOKEN" ``` The API returns only workspaces visible to the user who approved the agent. ## Create a task [#create-a-task] ```bash curl -X POST "$WHAGONS_API_BASE/tasks" \ -H "Authorization: Bearer $WHAGONS_AGENT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "tenantId": "", "workspaceId": "", "name": "Inspect room 304" }' ``` The token needs `ext:tasks:write`, and the approving user must be allowed to create that task in the selected workspace. ## Token-aware client behavior [#token-aware-client-behavior] * Discover token lifetime from authorization-server metadata and token responses. * Refresh or re-register before running a long multi-step workflow. * Treat `401` as a credential, expiry, scope, or tenant mismatch until proven otherwise. * Do not retry a write after an ambiguous network failure without an idempotency strategy in the agent's own workflow. * Never switch `tenantId` from the tenant approved in the claim. * Resolve current reference IDs before writing; names and IDs vary by tenant. * Keep an external correlation ID in the agent's own logs without recording raw credentials. ## What agents can do through v1 [#what-agents-can-do-through-v1] With the right scope and user permissions, an agent can: * read workspaces, spots, users, task types, statuses, priorities, teams, templates, and tags; * list or fetch visible tasks; * create, update, or soft-delete tasks; * read and add comments; * read or change assignments and tags; * read task logs; * approve or reject visible approval contexts; * acknowledge visible acknowledgment contexts. See the [API reference](/docs/external-api/reference) for exact fields and the [OpenAPI document](/openapi/whagons-v1.json) for machine-readable schemas. # Whagons assistant (/docs/agents/assistant) The Whagons assistant is an in-product collaborator that works in the signed-in user's tenant context. It can explain, navigate, inspect, analyze, export, and—when authorized—apply changes through curated product actions. It is not the same as an external agent calling the REST API. ## What the assistant understands [#what-the-assistant-understands] The assistant has compact, product-maintained skill documentation for: * workspaces, tasks, filters, exports, and comments; * users, teams, roles, settings, and personal preferences; * task types, templates, forms, custom fields, statuses, transitions, priorities, tags, and SLAs; * approvals, acknowledgments, workflows, KPI cards, reminders, and notifications; * integrations and API keys; * CSV and Excel inspection, analysis, and imports; * messages and workspace chat; * Workbench Write documents, Grid spreadsheets, and Present decks; * product routes and safe navigation. ## Read, preview, apply [#read-preview-apply] The assistant separates work into three modes: 1. **Read** — inspect visible state, reference data, task sets, settings, files, or workbench content. 2. **Preview** — validate mappings, imports, forms, templates, or structured edits before mutation. 3. **Apply** — run an approved curated action and verify the result. This pattern is especially important for bulk imports, destructive changes, permission edits, and document operations. ## Files and data [#files-and-data] The assistant can inspect attached CSV, XLSX, and XLS files, page through large datasets, profile columns, query data, map source fields to Whagons concepts, preview skipped values, and apply supported imports. For large tenant task sets, it can create a permission-filtered data snapshot for analysis rather than loading every row into chat context. ## Navigation and exports [#navigation-and-exports] The assistant can open safe in-product routes, prepare a filtered task view, and export task results to supported formats such as PDF, Excel, CSV, or JSON. ## Product writes [#product-writes] Writes use named, curated actions with validated payloads. The current families are listed in [Assistant capabilities](/docs/agents/capabilities). The available result always depends on current user permissions, tenant configuration, enabled powerups, and backend rollout state. ## What the assistant will not do [#what-the-assistant-will-not-do] * It will not bypass Whagons permissions. * It will not claim a write succeeded without a confirmed tool result. * It should not ask users to paste secrets into chat. * It should not run a destructive action without clear intent and required confirmation. * It should not invent a task, workspace, user, field, or action when live data is required. Read [Safety and permissions](/docs/agents/safety) for the full user-facing model. # auth.md agent access (/docs/agents/auth-md) Whagons publishes an `auth.md`-style agent authentication service at: ```txt https://gon.whagons.com/auth.md ``` `auth.md` is an open, Markdown-based discovery pattern for agents. Whagons currently supports a **user-claimed `service_auth` flow**: an agent starts with the user's email address, and that signed-in Whagons user approves the agent for a selected tenant. Agent authentication is being actively refined. Build clients to read discovery metadata at runtime and handle unknown fields and recoverable errors. ## Security model [#security-model] * Anonymous pre-claim access is not supported. * The approving user must sign in to Whagons. * The claim is bound to the email address supplied by the agent. * The user chooses the tenant when more than one is available. * The agent acts on behalf of that user and never gains more product access than the user currently has. * Registrations, claims, token issuance, use, and revocation are auditable. * Raw tokens are stored as hashes by Whagons. ## Discovery endpoints [#discovery-endpoints] | Resource | URL | | ------------------------------- | ---------------------------------------------------------------- | | Human- and agent-readable guide | `https://gon.whagons.com/auth.md` | | Protected resource metadata | `https://gon.whagons.com/.well-known/oauth-protected-resource` | | Authorization server metadata | `https://gon.whagons.com/.well-known/oauth-authorization-server` | | Identity registration | `POST https://gon.whagons.com/agent/identity` | | Token exchange | `POST https://gon.whagons.com/oauth2/token` | | Token revocation | `POST https://gon.whagons.com/oauth2/revoke` | Fetch metadata instead of hard-coding token lifetimes or supported grants. ## Supported scopes [#supported-scopes] | Scope | Allows | | ----------------- | ------------------------------------------------------------------------------------------- | | `ext:read` | Read tenant reference data and visible task data. | | `ext:tasks:write` | Perform documented task writes allowed by the approving user's current Whagons permissions. | If the request contains no recognized scope, Whagons defaults to `ext:read`. Unknown scopes are ignored. ## 1. Register an identity [#1-register-an-identity] ```bash curl -X POST "https://gon.whagons.com/agent/identity" \ -H "Content-Type: application/json" \ -d '{ "type": "service_auth", "login_hint": "operator@example.com", "name": "Guest request triage agent", "scopes": ["ext:read", "ext:tasks:write"] }' ``` The response contains secrets and user-facing values: ```json { "type": "service_auth", "claim_token": "whg_claim_…", "claim_attempt_token": "whg_claim_attempt_…", "user_code": "123456", "verification_uri": "https://app.whagons.com/auth/agent-claim", "verification_uri_complete": "https://app.whagons.com/auth/agent-claim?claim_attempt_token=…", "expires_in": 600, "interval": 5, "scopes": ["ext:read", "ext:tasks:write"] } ``` The response-supplied verification URI is authoritative. Show the six-digit `user_code` to the user and open or share `verification_uri_complete`. Keep `claim_token` and `claim_attempt_token` private. The user only needs the verification link and code. ## 2. Wait for user approval [#2-wait-for-user-approval] The user signs in, confirms the displayed code, and chooses a tenant. Claims expire after ten minutes. The agent may poll the token endpoint at the response's `interval`, currently five seconds: ```bash curl -X POST "https://gon.whagons.com/oauth2/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=urn:workos:agent-auth:grant-type:claim" \ --data-urlencode "claim_token=$WHAGONS_CLAIM_TOKEN" ``` While approval is pending, the service returns: ```json { "error": "authorization_pending", "error_description": "User claim is still pending" } ``` Respect the polling interval and stop when the claim expires or returns a terminal error. ## 3. Receive a token [#3-receive-a-token] After approval, the token exchange returns: ```json { "access_token": "whg_agent_…", "token_type": "Bearer", "expires_in": 900, "scope": "ext:read ext:tasks:write", "identity_assertion": "eyJ…" } ``` The access token is short-lived and must be sent only in the `Authorization` header. The identity assertion is also time-limited; clients should use discovery metadata and be prepared to restart the claim flow when renewal is no longer accepted. ## 4. Re-exchange an assertion [#4-re-exchange-an-assertion] While the latest identity assertion is valid, exchange it with the JWT bearer grant: ```bash curl -X POST "https://gon.whagons.com/oauth2/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \ --data-urlencode "assertion=$WHAGONS_IDENTITY_ASSERTION" ``` Each successful response includes a new access token and identity assertion. If renewal fails, do not loop indefinitely; start a new user claim. ## 5. Revoke a token [#5-revoke-a-token] ```bash curl -X POST "https://gon.whagons.com/oauth2/revoke" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "token=$WHAGONS_AGENT_TOKEN" ``` Revocation is idempotent and returns success even when the token is already unknown or revoked. ## Protocol reference [#protocol-reference] Whagons follows an early `auth.md`-style flow and publishes its implemented behavior through its own discovery documents. For the broader protocol background, see the [auth.md project](https://workos.com/auth-md). Continue with the [user claim flow](/docs/agents/claim-flow) or [call the Whagons API](/docs/agents/api-access). # Assistant capabilities (/docs/agents/capabilities) This page describes the built-in Whagons assistant. The technical action names are included for transparency and support; they are **not public REST endpoints**. External agents use `/api/v1/*`. Every capability remains permission-bound and some features depend on tenant configuration or staged rollout. ## Core work [#core-work] | Area | What the assistant can help with | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Tasks | Find, filter, summarize, create, update by task number, bulk-create, bulk-delete, validate next statuses, comment, and export. | | Workspaces | List visible workspaces, navigate to one, inspect task state, ensure a default workspace, and remove a workspace with confirmation. | | Views and exports | Build filtered task views and export to PDF, Excel, CSV, or JSON. | | Spots | List, create, update, bulk-manage, or remove nested operational locations. | | Messages | Inspect conversations, send and edit messages, manage reactions and read state, and use workspace chat. | ## Tenant setup and administration [#tenant-setup-and-administration] | Area | What the assistant can help with | | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | | Users | List, create, update, bulk-manage, assign teams or team roles, transfer ownership, and remove users with safeguards. | | Roles | Inspect roles and permissions, create custom roles, update them, synchronize permissions, and remove non-protected roles. | | Teams | List, create, update, bulk-manage, and remove teams. | | Personal settings | Inspect or update language, theme, task-grid density, and workspace display preferences. | | Integrations | List API keys and create a new key after explicit user approval. Key plaintext is returned only once. | | Fresh tenant setup | Inspect missing foundations and create an aligned task type, team, workspace, statuses, priorities, and templates. | ## Task design and policy [#task-design-and-policy] | Area | What the assistant can help with | | ------------------ | -------------------------------------------------------------------------------------------------------- | | Task types | List, create, update, bulk-manage, and remove categories/task types. | | Templates | Inspect, preview, and ensure reusable task templates, including form and priority links. | | Forms | Inspect, preview, create, and version forms, fields, option lists, scoring, and supported capture types. | | Custom fields | List, create, update, assign to task types, remove assignments, and set values on tasks. | | Statuses | List, create, update, bulk-manage, and remove lifecycle statuses. | | Status transitions | List and create transition groups or edges and remove invalid rules. | | Priorities | List, create, update, bulk-manage, and remove tenant priorities. | | Tags | List, create, update, bulk-manage, and remove task tags. | | SLAs | Inspect and manage service-level definitions when the current backend supports the requested operation. | ## Automation and accountability [#automation-and-accountability] | Area | What the assistant can help with | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | Approvals | List, create, update, bulk-manage, remove, and manage approvers; configure triggers, signatures, deadlines, and outcome actions. | | Acknowledgments | Explain source-task and action-context behavior, inspect audience state, and navigate users to the correct action context. | | Workflows | List, create, update, bulk-manage, and remove event/condition/action workflow graphs. | | KPI cards | List, create, update, remove, deduplicate, and bulk-create workspace or global KPI cards. | | Cleaning configuration | Inspect and manage supported cleaning statuses and related setup. | | Reminders and sounds | Explain and navigate to current configuration; write support depends on the active backend surface. | ## Files, imports, and analysis [#files-imports-and-analysis] | Area | What the assistant can help with | | ------------- | --------------------------------------------------------------------------------------------------------------- | | CSV and text | Read attached files in chunks, inspect headers, map columns, and prepare safe imports. | | Excel | Inspect workbooks and sheets, page rows, select columns, validate mappings, and import supported records. | | Data analysis | Profile data, run read-only queries over uploaded files, and analyze permission-filtered tenant task snapshots. | | Imports | Preview tenant setup or task mappings, report skipped values, then apply through curated bulk actions. | ## Workbench [#workbench] The assistant can work with Whagons Workbench files across three editors: * **Write** — create, inspect, rename, replace or append content, edit exact fragments, change page settings and styles, and patch images or equations. * **Grid** — create and inspect workbooks, set ranges and formulas, autofill, copy formatting, manage themes and sheets, and apply structured cell or sheet patches. * **Present** — create and inspect decks, add or replace slides, manage themes and guides, edit master/layout elements, copy formatting, reorder slides, and patch individual slide elements. It can also manage Workbench folders, revision history, AI undo, comments, and sharing when the user has access. ## Curated action catalog [#curated-action-catalog] These are the current named action families used by the assistant runtime: | Family | Curated names | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Workspaces and imports | `workspace.ensureDefault`, `workspaces.remove`, `workspace.remove`, `imports.previewSetup`, `imports.applySetup` | | Users | `users.list`, `users.create`, `users.bulkCreate`, `users.update`, `users.bulkUpdate`, `users.assignTeams`, `users.assignTeamRole`, `users.transferTenantOwnership`, `users.remove`, `users.bulkRemove` | | Roles | `roles.list`, `roles.create`, `roles.update`, `roles.syncPermissions`, `roles.remove` | | User settings | `userSettings.get`, `userSettings.setLanguage`, `userSettings.setTheme`, `userSettings.setWorkspaceDensity`, `userSettings.setWorkspaceDisplayPreference` | | Teams | `teams.list`, `teams.create`, `teams.bulkCreate`, `teams.update`, `teams.bulkUpdate`, `teams.remove`, `teams.bulkRemove` | | Spots | `spots.list`, `spots.create`, `spots.bulkCreate`, `spots.update`, `spots.bulkUpdate`, `spots.remove`, `spots.bulkRemove` | | Task types | `categories.list`, `categories.create`, `categories.bulkCreate`, `categories.update`, `categories.bulkUpdate`, `categories.remove`, `categories.bulkRemove` | | Tasks | `tasks.create`, `tasks.updateByNumericId`, `tasks.bulkCreate`, `tasks.bulkDelete`, `tasks.bulkRemove`, `tasks.getValidNextStatuses` | | Tags | `tags.list`, `tags.create`, `tags.bulkCreate`, `tags.update`, `tags.bulkUpdate`, `tags.remove`, `tags.bulkRemove` | | Statuses | `statuses.list`, `statuses.create`, `statuses.bulkCreate`, `statuses.update`, `statuses.bulkUpdate`, `statuses.remove`, `statuses.bulkRemove` | | Transitions | `statusTransitions.listGroups`, `statusTransitions.createGroup`, `statusTransitions.list`, `statusTransitions.create`, `statusTransitions.bulkCreate`, `statusTransitions.remove` | | Priorities | `priorities.list`, `priorities.create`, `priorities.bulkCreate`, `priorities.update`, `priorities.bulkUpdate`, `priorities.remove`, `priorities.bulkRemove` | | Approvals | `approvals.list`, `approvals.create`, `approvals.bulkCreate`, `approvals.update`, `approvals.bulkUpdate`, `approvals.remove`, `approvals.bulkRemove`, `approvals.addApprover`, `approvals.removeApprover` | | Custom fields | `customFields.list`, `customFields.create`, `customFields.bulkCreate`, `customFields.update`, `customFields.bulkUpdate`, `customFields.remove`, `customFields.bulkRemove`, `customFields.assignToCategory`, `customFields.removeFromCategory`, `customFields.setTaskValueByPgId` | | Integrations | `integrations.list`, `integrations.create`, `integrations.bulkCreate` | | Cleaning | `cleaningStatuses.list`, `cleaningStatuses.create`, `cleaningStatuses.bulkCreate`, `cleaningStatuses.update`, `cleaningStatuses.bulkUpdate`, `cleaningStatuses.remove`, `cleaningStatuses.bulkRemove` | | Workflows | `workflows.list`, `workflows.create`, `workflows.bulkCreate`, `workflows.update`, `workflows.bulkUpdate`, `workflows.remove`, `workflows.bulkRemove` | | KPI cards | `kpis.list`, `kpis.create`, `kpis.update`, `kpis.remove`, `kpis.dedupe`, `kpis.bulkCreate` | | Forms and templates | `forms.listOptionLists`, `forms.ensureOptionList`, `forms.preview`, `forms.ensure`, `templates.preview`, `templates.ensure` | | Workbench | `workbench.list`, `workbench.listTrash`, `workbench.get`, `workbench.inspect`, `workbench.create`, `workbench.previewOperations`, `workbench.applyOperations`, `workbench.undoAIEdit`, `workbench.remove`, `workbench.restore`, `workbench.listRevisions`, `workbench.restoreRevision`, `workbench.listFolders`, `workbench.createFolder`, `workbench.listComments`, `workbench.createComment`, `workbench.resolveComment`, `workbench.listShares`, `workbench.upsertShare`, `workbench.removeShare` | Action availability can temporarily differ during backend migration. The assistant should report a failed or unavailable action plainly rather than pretending it succeeded. # User claim flow (/docs/agents/claim-flow) The claim ceremony keeps a human in control of the first connection between an external agent and a Whagons tenant. ## Agent-side sequence [#agent-side-sequence] 1. Ask the user which Whagons email address should approve access. 2. Register a `service_auth` identity with only the necessary scopes. 3. Show the six-digit code exactly as returned. 4. Open or present `verification_uri_complete`. 5. Explain that the agent will act with the user's current Whagons permissions. 6. Poll no faster than the returned interval. 7. Stop polling on expiry, rejection, or another terminal error. 8. Store the resulting credential in a secret store, never in conversation history or logs. ## User-side sequence [#user-side-sequence] 1. Open the verification link supplied by the agent. 2. Sign in to Whagons with the same email address the agent used as `login_hint`. 3. Compare the six-digit code on the page with the code shown by the agent. 4. Select the tenant if the account belongs to more than one. 5. Review the agent's purpose and requested access. 6. Choose **Approve agent** only when the agent and request are expected. After approval, the page confirms that the agent may request an access token for the selected tenant. ## What approval means [#what-approval-means] Approval does not create a new Whagons user and does not grant tenant-wide administrator access. The agent is linked to the approving user and selected tenant. Every API operation remains subject to: * the issued agent scopes; * the user's current role permissions; * team membership; * workspace and task visibility; * field, status-transition, approval, and lifecycle policy. ## Common errors [#common-errors] | Message or code | Cause | Recovery | | -------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------- | | `authorization_pending` | The user has not completed approval. | Wait for the advertised interval and poll again. | | `Claim expired` | The ten-minute claim window ended. | Start a new identity registration. | | `Invalid code` | The entered code does not match the claim. | Compare the six digits and retry before expiry. | | `This claim was started for …` | The signed-in email differs from `login_hint`. | Sign in with the intended account or restart with the correct email. | | `Choose a tenant before claiming this agent` | The user belongs to multiple matching tenants. | Select one tenant on the approval screen. | | `No Whagons tenant user matched this claim` | No active user matches the email and tenant. | Verify membership or ask a tenant admin. | | `invalid_grant` | A token, assertion, claim, or registration is invalid or no longer active. | Stop retrying the same value and restart discovery or registration. | ## Safety guidance for users [#safety-guidance-for-users] * Do not approve an agent you did not initiate. * Verify the code through the original agent conversation. * Choose the narrowest tenant and scope set. * Revoke agent access when the tool is no longer used. * Report unexpected agent activity to a tenant administrator. For request examples after approval, see [Agent API access](/docs/agents/api-access). # AI and agents (/docs/agents) Whagons supports two related but distinct agent experiences. | Experience | Who runs it? | How it gets access | What it uses | | ----------------- | -------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------ | | External agent | A third-party agent, automation, or agent platform | A user approves a discoverable `auth.md` claim | Short-lived `whg_agent_…` token and the public v1 API | | Whagons assistant | Whagons inside the signed-in product | The current Whagons user session | Curated product actions, navigation, exports, and data tools | Do not treat the built-in assistant's curated action catalog as a public REST API. External agents use the documented `/api/v1/*` endpoints. ## Which path should I use? [#which-path-should-i-use] Use a **Settings-issued API key** when a known server-to-server integration needs durable access and an administrator can manage key rotation. Use **agent access** when an autonomous tool starts the connection and a human Whagons user should explicitly approve that agent for one tenant. Use the **built-in assistant** when the user is already working in Whagons and wants natural-language help with visible work, setup, analysis, files, or navigation. ## Current status [#current-status] The v1 task API and Settings-issued keys are the primary public integration surface. The `auth.md` agent flow is available as a beta while its discovery, credential renewal, and management experience continue to be refined. Start with [auth.md agent access](/docs/agents/auth-md), or go directly to the [API key quickstart](/docs/external-api/quickstart). # Machine-readable docs (/docs/agents/machine-readable) Whagons publishes public documentation in formats that agents can discover and consume without scraping the rendered interface. ## Discovery map [#discovery-map] | Resource | URL | Purpose | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | | Agent guide | [`/agents.md`](/agents.md) | Compact entry point for agents using Whagons. | | Documentation index | [`/llms.txt`](/llms.txt) | Public page list with descriptions. | | Full public docs | [`/llms-full.txt`](/llms-full.txt) | Combined public documentation corpus. | | Page Markdown | `/docs/.md` | Markdown negotiation alias for an individual page. | | Page content route | `/llms.mdx/docs//content.md` | Direct processed Markdown for a page. | | OpenAPI | [`/openapi/whagons-v1.json`](/openapi/whagons-v1.json) | REST contract for v1. | | Agent authentication | [`https://gon.whagons.com/auth.md`](https://gon.whagons.com/auth.md) | Live authentication discovery and implemented scopes. | | OAuth resource metadata | [`https://gon.whagons.com/.well-known/oauth-protected-resource`](https://gon.whagons.com/.well-known/oauth-protected-resource) | Structured protected-resource metadata. | ## Suggested agent sequence [#suggested-agent-sequence] 1. Read `/agents.md` for the service map and safety rules. 2. Read `/openapi/whagons-v1.json` for endpoint shapes. 3. Choose a credential path: a user-supplied Settings key or delegated `auth.md` claim. 4. Resolve the tenant's reference IDs before writing tasks. 5. Apply the same least-privilege and secret-handling rules described in the human docs. ## Public and private content [#public-and-private-content] `llms.txt`, `llms-full.txt`, search, navigation, and the public sitemap exclude internal maintainer documentation. Requests for internal page, Markdown, and social-image routes require separate authentication. Agents should not attempt to bypass that boundary or treat a public link to an internal slug as authorization. # Safety and permissions (/docs/agents/safety) Agents in Whagons are actors within the existing tenant authorization model, not a bypass around it. ## Shared principles [#shared-principles] These principles apply to both delegated external agents and the built-in assistant: 1. **Act as a known user.** Every operation must resolve to an authenticated or approving user. 2. **Stay inside one tenant.** A credential cannot be used to cross tenant boundaries. 3. **Honor current permissions.** Role, team, workspace, task, field, and lifecycle controls still apply. 4. **Minimize scope.** Request only the read or task-write scope the workflow requires. 5. **Confirm consequential changes.** Destructive or high-impact actions need clear user intent. 6. **Verify outcomes.** Never claim a write succeeded without a confirmed response. 7. **Protect secrets.** Credentials must not be placed in chat, logs, screenshots, issue trackers, or documentation. ## External agent safeguards [#external-agent-safeguards] * The user-claimed flow requires a matching email, six-digit code, sign-in, and tenant selection. * Anonymous pre-claim access is disabled. * Access tokens expire after the lifetime returned by the token service. * Token activity is tied to the agent registration and approving user for auditability. * Revoked, expired, wrong-tenant, or under-scoped credentials fail authentication. ## Built-in assistant safeguards [#built-in-assistant-safeguards] * Read operations use only data visible to the signed-in user. * Curated write actions validate their payloads and product rules. * Bulk operations should use preview-and-apply flows. * Destructive actions require explicit intent and `confirm: true` where the action supports it. * Role changes, ownership transfer, user removal, key creation, and similar operations receive additional caution. * Raw backend calls are fallback-only and should never be used to bypass a supported curated action. ## API-key safeguards [#api-key-safeguards] Settings-issued keys are long-lived compared with agent tokens. Use a separate key for each integration and environment, choose an expiration when possible, copy it once into a secret manager, and revoke it during offboarding or rotation. The Settings UI currently issues both external scopes by default. Restrict the key creator's roles, teams, and workspaces to keep the effective access appropriate. ## Incident response [#incident-response] If a key or agent token may be exposed: 1. Disable or revoke the credential immediately. 2. Review the affected integration or agent logs without copying the secret. 3. Review Whagons task logs and agent audit activity for unexpected changes. 4. Rotate any related integration secrets. 5. Correct the user's permissions or team membership if effective access was too broad. 6. Create a fresh credential only after the cause is understood. For the authorization layers behind these rules, see [Permissions and visibility](/docs/product/permissions). # API Keys (/docs/external-api/api-keys) API keys are managed in the Whagons product at Settings > Integrations. API keys act as the user who created them. They inherit that user's current tenant permissions and workspace visibility, so revoking a user's access or changing their role also affects what their keys can do. ## Create a key in Settings [#create-a-key-in-settings] You need the `config.integrations` permission. 1. Open **Settings → Integrations → API Keys**. 2. Choose **Add API Key**. 3. Give the key a name that identifies its system, purpose, and environment. 4. Choose an expiration: 1 hour, 1 day, 7, 30, 90, or 180 days, 1 year, or never. 5. Create the key and copy the plaintext value immediately. 6. Save it in the external system's secret manager. The full value is shown once. Later, Settings shows only the key's name, final four-character hint, creation date, expiration, last-used date, and enabled state. Keys begin with `whg_live_`. Whagons stores a hash rather than the plaintext credential. ## Key Lifecycle [#key-lifecycle] | State | API behavior | | -------- | ----------------------------------------------------------------------- | | Active | Requests can authenticate if the key has the required tenant and scope. | | Inactive | Requests fail with `401`. | | Expired | Requests fail with `401`. | | Revoked | Requests fail with `401` and the key is hidden from active key lists. | Successful authenticated HTTP requests update the key's last-used timestamp. ## Default Scopes [#default-scopes] New keys default to: ```json ["ext:read", "ext:tasks:write"] ``` The current Settings dialog does not expose a scope selector; it issues both external scopes. Keep effective access narrow by using a dedicated key creator with only the required roles, teams, and workspaces. | Scope | Allows | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `ext:read` | Read reference data and visible tasks. | | `ext:tasks:write` | Create, update, delete, comment, assign, tag, approve, or acknowledge visible tasks when the creator has the matching product permission. | | `*` | Compatibility value accepted by the backend for specially provisioned keys; it is not offered by the Settings creation flow. | ## Disable versus revoke [#disable-versus-revoke] * Use the **Enabled** switch for a reversible pause. Disabled keys return `401`. * Use **Delete** to revoke the key permanently. The key disappears from the active list and cannot be restored. ## Rotation Guidance [#rotation-guidance] * Create a replacement key. * Deploy it to the external system. * Confirm successful calls with the new key. * Revoke the old key. Never paste keys into chat, issue trackers, documentation examples, release notes, or PR bodies. ## Create keys through the assistant [#create-keys-through-the-assistant] The built-in Whagons assistant can list keys or create a key after explicit user approval when the user has integration-management permission. Disabling and revoking a key should be done in Settings → Integrations. The assistant must never repeat or log a plaintext key after the one-time creation response. See the [API quickstart](/docs/external-api/quickstart) for the complete first-request flow. # Authentication (/docs/external-api/authentication) Whagons supports API keys, first-party user sessions for a small user-facing surface, and agent credentials discovered through `auth.md`. ## API Keys [#api-keys] Server-to-server integrations should use tenant API keys from Settings > Integrations. Send the key with either header: ```http X-API-Key: whg_live_... ``` or: ```http Authorization: Bearer whg_live_... ``` API keys are tenant-scoped. They are stored hashed and the plaintext value is shown only once when created. Each key acts as its creator. Endpoint responses and writes are constrained by that user's current permissions, team membership, workspace visibility, and task visibility. Do not send API keys in query parameters. ## Agent Auth [#agent-auth] AI agents can discover Whagons authentication from the beta agent-auth service: ```http GET https://gon.whagons.com/auth.md ``` Structured discovery is available at: ```http GET https://gon.whagons.com/.well-known/oauth-protected-resource GET https://gon.whagons.com/.well-known/oauth-authorization-server ``` Agent access tokens use: ```http Authorization: Bearer whg_agent_... ``` Agent tokens have their own registration, expiry, revocation, and audit trail, but requests act on behalf of the Whagons user who approved the agent. Endpoint responses and writes are constrained by that user's current permissions, team membership, workspace visibility, and task visibility. Read [auth.md agent access](/docs/agents/auth-md) for the user-claimed flow and token lifecycle. ## User Session Auth [#user-session-auth] The `/api/v1/me/tenants` endpoint requires an authenticated user session rather than an API key. It is intended for first-party client experiences that already have Whagons/Firebase identity. ## Scopes [#scopes] | Scope | Allows | | ----------------- | ---------------------------------------------------------------------------------------------------------------------- | | `ext:read` | Read external reference data and visible task data. | | `ext:tasks:write` | Create, update, delete, comment on, assign, tag, approve, and acknowledge visible tasks. | | `*` | Backend compatibility value for specially provisioned API keys; not issued by the current Settings flow or agent flow. | ## Required Scope by Endpoint [#required-scope-by-endpoint] | Endpoint | Scope | | ---------------------------------- | ------------------------ | | `GET /api/v1/workspaces` | `ext:read` | | `GET /api/v1/spots` | `ext:read` | | `GET /api/v1/users` | `ext:read` | | `GET /api/v1/categories` | `ext:read` | | `GET /api/v1/statuses` | `ext:read` | | `GET /api/v1/priorities` | `ext:read` | | `GET /api/v1/teams` | `ext:read` | | `GET /api/v1/templates` | `ext:read` | | `GET /api/v1/tags` | `ext:read` | | `GET /api/v1/tasks` | `ext:read` | | `GET /api/v1/task-comments` | `ext:read` | | `GET /api/v1/task-assignments` | `ext:read` | | `GET /api/v1/task-tags` | `ext:read` | | `GET /api/v1/task-logs` | `ext:read` | | `POST /api/v1/tasks` | `ext:tasks:write` | | `PATCH /api/v1/tasks` | `ext:tasks:write` | | `DELETE /api/v1/tasks` | `ext:tasks:write` | | `POST /api/v1/task-comments` | `ext:tasks:write` | | `POST /api/v1/task-assignments` | `ext:tasks:write` | | `POST /api/v1/task-tags` | `ext:tasks:write` | | `POST /api/v1/task-approval` | `ext:tasks:write` | | `POST /api/v1/task-acknowledgment` | `ext:tasks:write` | | `GET /api/v1/me/tenants` | First-party user session | ## Error Shape [#error-shape] Errors currently return JSON with an `error` field: ```json { "error": "Unauthorized" } ``` Common statuses: * `400`: missing required parameter or invalid JSON. * `401`: missing credential, invalid credential, expired credential, inactive key, wrong tenant, or missing required scope. The agent discovery challenge on protected API responses is part of the in-progress gateway alignment. Agent clients should currently start from the published `auth.md` URL rather than depending on a `WWW-Authenticate` header. # API Changelog (/docs/external-api/changelog) ## 2026-06-11 [#2026-06-11] * Added `/api/v1/*` aliases for the current external API surface while preserving `/api/ext/*`. * Documented permission-bound API-key behavior: keys act as the creator and inherit current user visibility. * Expanded docs for task reads, updates, deletes, comments, assignments, tags, logs, approvals, acknowledgments, and reference tables. * Added a checked-in OpenAPI description at `/openapi/whagons-v1.json`. # Concepts (/docs/external-api/concepts) The Whagons API is tenant-scoped and operations-focused. Integrations usually read reference data, map external records to Whagons IDs, then create tasks. ## Tenant [#tenant] A tenant is a Whagons customer or workspace environment. Most API calls require a `tenantId`. API keys belong to one tenant. A key cannot be used against another tenant. ## API Key [#api-key] API keys are long-lived server-to-server credentials created by tenant admins in Settings > Integrations. Keys: * start with `whg_live_`; * are shown only once; * are stored as hashes; * can expire; * can be revoked or deactivated; * carry scopes. An API key acts as the user who created it. Reads and writes still respect that user's current permissions, team membership, workspace visibility, and task visibility. If that user is removed, loses access, or is deleted, the key loses that access too. ## Scope [#scope] Scopes define what a key can do. | Scope | Meaning | | ----------------- | ---------------------------------------------------------------------------------------------------------- | | `ext:read` | Read reference data and visible task data. | | `ext:tasks:write` | Create, update, delete, comment on, assign, tag, approve, and acknowledge visible tasks. | | `*` | Compatibility scope accepted for specially provisioned keys, not offered in the current Settings key flow. | Settings-issued keys currently receive both standard scopes. Use a dedicated, least-privilege Whagons user to bound effective access. ## Reference Data [#reference-data] Reference data is the set of Whagons IDs an integration needs before it writes work. Typical flow: 1. Read workspaces. 2. Read spots or users if needed. 3. Store the relevant Whagons IDs in the external system. 4. Use those IDs when creating tasks. ## Task [#task] A task is operational work inside a workspace. External task creation uses the same task creation policy as Whagons product flows so tasks participate in normal assignment, visibility, and lifecycle rules. ## Convex IDs and Legacy IDs [#convex-ids-and-legacy-ids] Responses may include Convex document IDs and sometimes `pgId` legacy identifiers. Use Convex IDs for new API requests unless a specific endpoint says otherwise. # Errors (/docs/external-api/errors) API errors currently return JSON with an `error` field. ```json { "error": "Unauthorized" } ``` ## Status Codes [#status-codes] | Status | Meaning | Common causes | | ------ | ------------------ | ----------------------------------------------------------------------------------------------------------------------- | | `400` | Bad request | Missing `tenantId`, missing task fields, or invalid JSON body. | | `401` | Unauthorized | Missing key, invalid key, expired key, inactive key, revoked key, wrong tenant, missing scope, or missing user session. | | `405` | Method not allowed | Calling an endpoint with an unsupported HTTP method. | Convex or platform errors may return other status codes if the request fails before the handler completes. ## Client Behavior [#client-behavior] * Treat `401` as non-retryable until credentials or scopes change. * Treat missing IDs as a signal to refresh reference data. * Do not log raw API keys in error messages. * Include request IDs or external correlation IDs in your own logs when possible. ## CORS [#cors] The current external API sends CORS headers for: * `Authorization` * `Content-Type` * `X-API-Key` Browser-based integrations should preflight before relying on a new method or header. # Examples (/docs/external-api/examples) Set common environment variables: ```bash export WHAGONS_API_BASE="https://cvx-share.whagons.com/api/v1" export WHAGONS_TENANT_ID="" export WHAGONS_API_KEY="" ``` This is the production HTTP action gateway. Each example also supplies a `tenantId` that must match the tenant attached to the credential. ## List Workspaces [#list-workspaces] ```bash curl "$WHAGONS_API_BASE/workspaces?tenantId=$WHAGONS_TENANT_ID" \ -H "X-API-Key: $WHAGONS_API_KEY" ``` ## List Spots [#list-spots] ```bash curl "$WHAGONS_API_BASE/spots?tenantId=$WHAGONS_TENANT_ID" \ -H "X-API-Key: $WHAGONS_API_KEY" ``` ## List Users [#list-users] ```bash curl "$WHAGONS_API_BASE/users?tenantId=$WHAGONS_TENANT_ID" \ -H "X-API-Key: $WHAGONS_API_KEY" ``` ## List Statuses for a Category [#list-statuses-for-a-category] ```bash curl "$WHAGONS_API_BASE/statuses?tenantId=$WHAGONS_TENANT_ID&categoryId=" \ -H "X-API-Key: $WHAGONS_API_KEY" ``` ## Create a Minimal Task [#create-a-minimal-task] ```bash curl -X POST "$WHAGONS_API_BASE/tasks" \ -H "Content-Type: application/json" \ -H "X-API-Key: $WHAGONS_API_KEY" \ -d '{ "tenantId": "", "name": "Inspect room 304", "workspaceId": "" }' ``` ## Create a Task With Assignments and Location [#create-a-task-with-assignments-and-location] ```bash curl -X POST "$WHAGONS_API_BASE/tasks" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer '"$WHAGONS_API_KEY"'" \ -d '{ "tenantId": "", "name": "Deliver crib to room 512", "workspaceId": "", "description": "Guest requested delivery before 6 PM.", "spotId": "", "userIds": [""] }' ``` ## List Recent Visible Tasks [#list-recent-visible-tasks] ```bash curl "$WHAGONS_API_BASE/tasks?tenantId=$WHAGONS_TENANT_ID&limit=25" \ -H "X-API-Key: $WHAGONS_API_KEY" ``` ## Fetch One Task [#fetch-one-task] ```bash curl "$WHAGONS_API_BASE/tasks?tenantId=$WHAGONS_TENANT_ID&taskId=" \ -H "X-API-Key: $WHAGONS_API_KEY" ``` Use `pgId=` instead of `taskId` when an integration only stores the legacy numeric task ID. ## Update a Task [#update-a-task] ```bash curl -X PATCH "$WHAGONS_API_BASE/tasks" \ -H "Content-Type: application/json" \ -H "X-API-Key: $WHAGONS_API_KEY" \ -d '{ "tenantId": "", "taskId": "", "updates": { "description": "Guest requested delivery before 5 PM.", "priorityId": "" } }' ``` ## Add a Comment [#add-a-comment] ```bash curl -X POST "$WHAGONS_API_BASE/task-comments" \ -H "Content-Type: application/json" \ -H "X-API-Key: $WHAGONS_API_KEY" \ -d '{ "tenantId": "", "taskId": "", "note": "Confirmed with housekeeping." }' ``` ## Replace Assignees [#replace-assignees] ```bash curl -X POST "$WHAGONS_API_BASE/task-assignments" \ -H "Content-Type: application/json" \ -H "X-API-Key: $WHAGONS_API_KEY" \ -d '{ "tenantId": "", "taskId": "", "mode": "set", "userIds": [""] }' ``` ## Add Tags [#add-tags] ```bash curl -X POST "$WHAGONS_API_BASE/task-tags" \ -H "Content-Type: application/json" \ -H "X-API-Key: $WHAGONS_API_KEY" \ -d '{ "tenantId": "", "taskId": "", "mode": "add", "tagIds": [""] }' ``` ## Delete a Task [#delete-a-task] Only run delete examples in a safe tenant or sandbox. ```bash curl -X DELETE "$WHAGONS_API_BASE/tasks?tenantId=$WHAGONS_TENANT_ID&taskId=" \ -H "X-API-Key: $WHAGONS_API_KEY" ``` ## Handle Unauthorized [#handle-unauthorized] ```bash curl "$WHAGONS_API_BASE/workspaces?tenantId=$WHAGONS_TENANT_ID" \ -H "X-API-Key: bad-key" ``` Expected shape: ```json { "error": "Unauthorized" } ``` # External API (/docs/external-api) The Whagons external API is the programmatic surface connected to API keys created in **Settings → Integrations → API Keys**. Use it to connect a help desk, property system, sensor workflow, automation platform, reporting process, or AI agent to the same permission-aware work users see in Whagons. ## What v1 supports [#what-v1-supports] * Read workspaces, spots, users, task reference data, and visible tasks. * Create, update, delete, comment on, assign, tag, approve, and acknowledge tasks. * Authenticate with a tenant API key or a user-approved agent token. * Apply the current permissions and visibility of the user behind the credential. ## Base URL [#base-url] The current production base URL is: ```txt https://cvx-share.whagons.com/api/v1 ``` The gateway is shared, but access is tenant-specific. Every request supplies the tenant's `tenantId`, and the credential must belong to that same tenant. ## Integration pattern [#integration-pattern] Most integrations follow the same reliable sequence: 1. Create and securely store a dedicated API key. 2. Read workspaces and other reference data. 3. Save the Whagons IDs that map to the external system. 4. Create or operate on tasks with those IDs. 5. Handle permissions and stale reference data explicitly. 6. Rotate the key without interrupting the integration. The API does not provide a second, broader authorization model. If the key creator cannot see or change something in Whagons, the key cannot either. ## OpenAPI [#openapi] The machine-readable OpenAPI 3.1 document is public: ```txt https://docs.whagons.com/openapi/whagons-v1.json ``` Use it for client generation and schema inspection, but read the conceptual guides for tenant visibility, task policy, and safe credential handling. ## Compatibility [#compatibility] The `/api/ext/*` paths still work. New integrations should use `/api/v1/*` so future breaking changes can be handled with normal API versioning. Continue with the [five-minute quickstart](/docs/external-api/quickstart). # Migrate from /api/ext (/docs/external-api/migration-from-ext) The older external API namespace remains available: ```txt /api/ext ``` New integrations should use: ```txt /api/v1 ``` ## What Changed [#what-changed] The documented namespace changed. The current route behavior is otherwise compatible for the existing external surface: | Old | New | | ------------------------------ | ----------------------------- | | `/api/ext/me/tenants` | `/api/v1/me/tenants` | | `/api/ext/workspaces` | `/api/v1/workspaces` | | `/api/ext/spots` | `/api/v1/spots` | | `/api/ext/users` | `/api/v1/users` | | `/api/ext/categories` | `/api/v1/categories` | | `/api/ext/statuses` | `/api/v1/statuses` | | `/api/ext/priorities` | `/api/v1/priorities` | | `/api/ext/teams` | `/api/v1/teams` | | `/api/ext/templates` | `/api/v1/templates` | | `/api/ext/tags` | `/api/v1/tags` | | `/api/ext/tasks` | `/api/v1/tasks` | | `/api/ext/task-comments` | `/api/v1/task-comments` | | `/api/ext/task-assignments` | `/api/v1/task-assignments` | | `/api/ext/task-tags` | `/api/v1/task-tags` | | `/api/ext/task-logs` | `/api/v1/task-logs` | | `/api/ext/task-approval` | `/api/v1/task-approval` | | `/api/ext/task-acknowledgment` | `/api/v1/task-acknowledgment` | HTTP methods, request payloads, response shapes, API-key headers, scopes, and `tenantId` requirements are unchanged by the namespace migration. ## Migration Steps [#migration-steps] 1. Change the base path from `/api/ext` to `/api/v1`. 2. Keep the same authentication header. 3. Keep passing `tenantId` where required. 4. Verify reference-data reads. 5. Verify task reads and writes in a safe tenant or sandbox. 6. Update external system logs and runbooks to use `/api/v1`. ## Compatibility Window [#compatibility-window] `/api/ext` is compatibility-only. Do not build new features against it. Any future removal should be announced in the API changelog. # API quickstart (/docs/external-api/quickstart) This guide uses the API key created in the Whagons Settings experience. You need a role with permission to manage integrations. ## 1. Create an API key [#1-create-an-api-key] In Whagons: 1. Open **Settings**. 2. Choose **Integrations**. 3. Open the **API Keys** tab. 4. Choose **Add API Key**. 5. Enter a descriptive name such as `Guest request sync — production`. 6. Choose an expiration. The current options are one hour, one day, 7, 30, 90, or 180 days, one year, or no expiration. 7. Choose **Create**. 8. Copy the `whg_live_…` value immediately. Whagons will not show the full key again. The Settings flow currently issues both `ext:read` and `ext:tasks:write`. Effective access is still limited by the creator's current user permissions, teams, workspaces, and task visibility. Put the key directly into the integration's secret manager or environment. Do not paste it into a ticket, chat, source file, screenshot, or build log. ## 2. Set local variables [#2-set-local-variables] ```bash export WHAGONS_API_BASE="https://cvx-share.whagons.com/api/v1" export WHAGONS_API_KEY="whg_live_…" export WHAGONS_TENANT_ID="" ``` The key belongs to one tenant, and most endpoints require that tenant's ID explicitly. ## 3. Verify the key [#3-verify-the-key] List visible workspaces: ```bash curl --fail-with-body \ "$WHAGONS_API_BASE/workspaces?tenantId=$WHAGONS_TENANT_ID" \ -H "X-API-Key: $WHAGONS_API_KEY" ``` You should receive a JSON array. Choose a workspace and keep its `_id`: ```json [ { "_id": "", "name": "Guest Requests" } ] ``` If the response is `401`, verify the key, tenant ID, active state, expiration, and the creator's access. ## 4. Create a task [#4-create-a-task] ```bash curl --fail-with-body -X POST "$WHAGONS_API_BASE/tasks" \ -H "X-API-Key: $WHAGONS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tenantId": "", "workspaceId": "", "name": "Deliver extra towels to room 304", "description": "Created by the guest request integration." }' ``` Successful creation returns the document ID and, when present, the numeric task ID: ```json { "id": "", "pgId": 1234 } ``` Store `id` for future API operations. ## 5. Read the task [#5-read-the-task] ```bash curl --fail-with-body \ "$WHAGONS_API_BASE/tasks?tenantId=$WHAGONS_TENANT_ID&taskId=" \ -H "Authorization: Bearer $WHAGONS_API_KEY" ``` Both `X-API-Key` and bearer authentication work for `whg_live_…` keys. Pick one style and use it consistently. ## 6. Add real tenant data [#6-add-real-tenant-data] Before sending richer task payloads, resolve current IDs: * [Spots, users, teams, statuses, priorities, templates, and tags](/docs/external-api/reference-data) * [Task fields, updates, assignments, comments, and approvals](/docs/external-api/tasks) * [Complete endpoint reference](/docs/external-api/reference) ## Production checklist [#production-checklist] * Use a separate key for production and each non-production environment. * Give the key creator only the teams and workspaces the integration needs. * Choose a finite expiration where the external system supports rotation. * Keep the tenant ID and all Whagons reference IDs configurable. * Treat `401` as non-retryable until credentials or scopes change. * Do not retry a write blindly after a timeout; first determine whether it succeeded. * Monitor the key's **Last Used** value in Settings. * Test rotation before the original key expires. Next, read [API concepts](/docs/external-api/concepts) or jump to the [examples](/docs/external-api/examples). # Reference Data (/docs/external-api/reference-data) Reference data endpoints require `ext:read`. Use them before task creation or task updates so the external system can select the right workspace, task type, status, priority, user, tag, or spot. API-key callers only receive rows the key creator is allowed to view. ## Workspaces [#workspaces] ```http GET /api/v1/workspaces?tenantId= ``` Returns active workspaces for the tenant, sorted by name for API-key callers. Typical fields include: | Field | Description | | -------------------- | ---------------------------------------------------------------- | | `_id` | Convex workspace ID. Use this as `workspaceId` in task creation. | | `pgId` | Legacy numeric ID when present. | | `name` | Workspace display name. | | `slug` | Optional route-friendly name. | | `teams` | Team IDs with access when present. | | `allowedCategoryIds` | Task types allowed in the workspace when configured. | ## Spots [#spots] ```http GET /api/v1/spots?tenantId= ``` Returns tenant spots or physical locations. Typical fields include: | Field | Description | | ------------ | ------------------------------------------------------ | | `_id` | Convex spot ID. Use this as `spotId` in task creation. | | `pgId` | Legacy numeric ID when present. | | `name` | Spot display name. | | `spotTypeId` | Type/classification when configured. | | `parentId` | Parent spot for nested location structures. | ## Users [#users] ```http GET /api/v1/users?tenantId= ``` Returns active users for the tenant. Typical fields include: | Field | Description | | ------- | ---------------------------------------------------- | | `_id` | Convex user ID. Use this in task creation `userIds`. | | `pgId` | Legacy numeric ID when present. | | `name` | User display name. | | `email` | User email. | | `apodo` | Optional nickname. | ## Task Types / Categories [#task-types--categories] ```http GET /api/v1/categories?tenantId= ``` Optional filters: | Query | Description | | ------------- | -------------------------------------------------------------------------------------- | | `workspaceId` | Return categories linked to a workspace when the category row carries workspace scope. | Use `_id` as `categoryId` when creating or updating tasks. ## Statuses [#statuses] ```http GET /api/v1/statuses?tenantId=&categoryId= ``` Use `_id` as `statusId`. Statuses may carry fields such as `action`, `initial`, and `final`; integrations should not assume status names are stable across tenants. ## Priorities [#priorities] ```http GET /api/v1/priorities?tenantId=&categoryId= ``` Use `_id` as `priorityId`. ## Teams [#teams] ```http GET /api/v1/teams?tenantId= ``` Use `_id` as `teamId` when an integration needs to set or update task ownership. ## Templates [#templates] ```http GET /api/v1/templates?tenantId=&workspaceId=&categoryId= ``` Use `_id` as `templateId`. Template and task-type policy can affect allowed task creation fields. ## Tags [#tags] ```http GET /api/v1/tags?tenantId= ``` Use `_id` values with `/api/v1/task-tags`. ## Caching Guidance [#caching-guidance] Reference data can be cached by the external system, but integrations should refresh when an ID is missing, a task write fails because a referenced object no longer exists, or tenant admins change workspace/team structure. # API Reference (/docs/external-api/reference) The External API is the API exposed by keys created in **Settings → Integrations → API Keys**. ```txt Base URL: https://cvx-share.whagons.com/api/v1 OpenAPI: https://docs.whagons.com/openapi/whagons-v1.json ``` New integrations should use `/api/v1/*`. The production gateway also serves `/api/ext/*` as compatibility aliases for existing integrations. ## Authentication and scopes [#authentication-and-scopes] Send a Settings-issued key in either header form: ```http X-API-Key: whg_live_... ``` ```http 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 [#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 [#request-conventions] * `tenantId` is required on every API-key request. On reads it is a query parameter; on writes it is in the JSON body. * `tenantId` must 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 `dueDate` and `startDate` are Unix timestamps in **milliseconds**. * Request bodies use `Content-Type: application/json`. * List endpoints currently return JSON arrays directly; responses are not wrapped in a `data` envelope. * There is not yet a cursor-pagination contract. `GET /tasks` instead accepts a bounded `limit`. ## Session [#session] ### `GET /me/tenants` [#get-metenants] 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 [#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: ```bash curl --request GET \ --url 'https://cvx-share.whagons.com/api/v1/workspaces?tenantId=hotel-1' \ --header 'X-API-Key: whg_live_REPLACE_ME' ``` ## Tasks [#tasks] ### `GET /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` [#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: ```json { "tenantId": "hotel-1", "name": "Inspect room 304", "workspaceId": "j57..." } ``` Response: ```json { "id": "j97...", "pgId": 1234 } ``` `pgId` can be `null` or absent when no legacy numeric identity exists. ### `PATCH /tasks` [#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. ```json { "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` [#delete-tasks] Soft-deletes a task. Send both identifiers as query parameters: ```http DELETE /tasks?tenantId=hotel-1&taskId=j97... ``` The handler also accepts the identifiers in a JSON body for compatibility. A successful response is: ```json { "ok": true, "taskId": "j97..." } ``` ## Task subresources [#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 [#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 [#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. Use `add` or `remove` when another person or integration may be changing assignments concurrently. An assignment request cannot use an empty `userIds` array. ### Tags [#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 [#logs] `GET /task-logs` returns task log rows newest first. Logs reflect changes made in both Whagons and the External API. ### Approval decisions [#approval-decisions] `POST /task-approval` requires `decision: "approved" | "rejected"` and accepts optional `contextId`, `comment`, and `signatureStorageId`. ```json { "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 [#acknowledgments] `POST /task-acknowledgment` accepts optional `contextId` and `comment`: ```json { "tenantId": "hotel-1", "taskId": "j97...", "contextId": "workspace-context-id", "comment": "Acknowledged" } ``` ## OpenAPI [#openapi] The versioned, machine-readable description is available at [`/openapi/whagons-v1.json`](/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](/docs/external-api/changelog). ## Compatibility routes [#compatibility-routes] The same handlers remain available at `/api/ext/*`. New clients should use `/api/v1/*`, and existing clients should follow the [migration guide](/docs/external-api/migration-from-ext). # Tasks (/docs/external-api/tasks) External task operations use the same visibility, permission, and workflow policy as product workflows. API keys act as the user who created the key. ## Minimal Task [#minimal-task] ```json { "tenantId": "hotel-1", "name": "Inspect room 304", "workspaceId": "j57..." } ``` Required fields: | Field | Description | | ------------- | -------------------------------------------------- | | `tenantId` | Tenant identifier for the task. | | `name` | Human-readable task title. | | `workspaceId` | Convex workspace ID from `GET /api/v1/workspaces`. | ## Optional Assignments [#optional-assignments] Add `userIds` to assign users at creation time: ```json { "tenantId": "hotel-1", "name": "Deliver crib to room 512", "workspaceId": "j57...", "userIds": ["k97...", "n42..."] } ``` ## Optional Location [#optional-location] Add `spotId` to attach a physical location: ```json { "tenantId": "hotel-1", "name": "Check pool towels", "workspaceId": "j57...", "spotId": "m22..." } ``` ## Optional Task Metadata [#optional-task-metadata] Task creation also accepts optional Convex IDs returned from reference endpoints: | Field | Source | | --------------------------------------- | ------------------------------------------------------------ | | `categoryId` | `GET /api/v1/categories` | | `teamId` | `GET /api/v1/teams` | | `templateId` | `GET /api/v1/templates` | | `statusId` | `GET /api/v1/statuses` | | `priorityId` | `GET /api/v1/priorities` | | `slaId` | Internal SLA configuration, when exposed to the integration. | | `dueDate` | Unix timestamp in milliseconds. | | `startDate` | Unix timestamp in milliseconds. | | `latitude` / `longitude` | Optional coordinates. | | `reportedByTeamId` / `reportedByUserId` | Reporting context, when allowed by task policy. | ## Response [#response] ```json { "id": "j97...", "pgId": 1234 } ``` Use `id` for future Convex-native references. `pgId` is returned when a legacy numeric identifier exists. ## Read Tasks [#read-tasks] ```http GET /api/v1/tasks?tenantId=&limit=100 ``` Supported filters: | Query | Description | | --------------------- | ------------------------------------------------------------------------------- | | `taskId` | Fetch one visible task by Convex ID. | | `pgId` | Fetch one visible task by legacy numeric ID. | | `workspaceId` | Filter by workspace. | | `statusId` | Filter by status. | | `priorityId` | Filter by priority. | | `categoryId` | Filter by category/task type. | | `teamId` | Filter by team. | | `spotId` | Filter by spot/location. | | `templateId` | Filter by template. | | `assignedTo=me` | Tasks assigned to the API-key creator. | | `assignedTo=` | Tasks assigned to a specific user. | | `search` | Case-insensitive match against task name and description. | | `limit` | Maximum rows from `1` to `500`; defaults to `100` and is clamped by the server. | Only tasks visible to the key creator are returned. ## Update a Task [#update-a-task] ```http PATCH /api/v1/tasks ``` ```json { "tenantId": "hotel-1", "taskId": "j97...", "updates": { "description": "Updated from automation", "statusId": "s12...", "priorityId": "p34..." } } ``` Allowed update fields are `name`, `description`, `statusId`, `priorityId`, `teamId`, `spotId`, `categoryId`, `templateId`, `dueDate`, `startDate`, `latitude`, and `longitude`. Status changes require normal status-change permission, owning-team access, and workflow validity. Fields can also be restricted by field-permission policy. ## Delete a Task [#delete-a-task] ```http DELETE /api/v1/tasks?tenantId=&taskId= ``` This soft-deletes a visible task and requires delete-task permission. ## Comments and Attachments [#comments-and-attachments] List comments: ```http GET /api/v1/task-comments?tenantId=&taskId= ``` Create a comment: ```http POST /api/v1/task-comments ``` ```json { "tenantId": "hotel-1", "taskId": "j97...", "note": "Comment from automation" } ``` The same endpoint accepts `source: "task_attachment"` and an `attachments` array when the integration already has valid storage IDs. ## Assignments [#assignments] ```http GET /api/v1/task-assignments?tenantId=&taskId= POST /api/v1/task-assignments ``` ```json { "tenantId": "hotel-1", "taskId": "j97...", "mode": "add", "userIds": ["u12..."] } ``` `mode` can be `set`, `add`, or `remove`. ## Tags [#tags] ```http GET /api/v1/task-tags?tenantId=&taskId= POST /api/v1/task-tags ``` ```json { "tenantId": "hotel-1", "taskId": "j97...", "mode": "add", "tagIds": ["t12..."] } ``` `mode` can be `set`, `add`, or `remove`. ## Logs [#logs] ```http GET /api/v1/task-logs?tenantId=&taskId= ``` Returns task logs visible to the key creator. ## Approval and Acknowledgment Actions [#approval-and-acknowledgment-actions] Approve or reject a visible approval context: ```http POST /api/v1/task-approval ``` ```json { "tenantId": "hotel-1", "taskId": "j97...", "contextId": "optional-context-id", "decision": "approved", "comment": "Looks good" } ``` Acknowledge a visible acknowledgment context: ```http POST /api/v1/task-acknowledgment ``` ```json { "tenantId": "hotel-1", "taskId": "j97...", "contextId": "optional-context-id", "comment": "Acknowledged" } ``` ## Implementation Notes [#implementation-notes] * API-key task creation records the key creator as the acting user. * Task reads and writes are permission-checked as that creator. * Optional fields can be added in `v1` when they are backward compatible. * Invalid JSON or missing required fields returns `400`. * Missing, invalid, expired, inactive, wrong-tenant, or under-scoped credentials return `401`. # Versioning (/docs/external-api/versioning) The documented external API namespace is: ```txt /api/v1 ``` The older namespace remains available for compatibility: ```txt /api/ext ``` ## Policy [#policy] * New integrations use `/api/v1/*`. * `/api/ext/*` is compatibility-only and should not be used for new docs or examples. * Backward-compatible additions can ship inside `v1`. * Breaking changes require a new namespace such as `/api/v2`. * API documentation and OpenAPI specs must be updated in the same PR as route, scope, payload, response, or error changes. ## What Counts as Breaking [#what-counts-as-breaking] * Removing a field from a response. * Changing a field type. * Renaming a required request field. * Changing authentication or scope requirements. * Returning a materially different status code for an existing case. ## What Is Backward Compatible [#what-is-backward-compatible] * Adding optional request fields. * Adding response fields. * Adding new endpoints. * Adding new enum values when clients are expected to ignore unknown values. ## Documentation Requirements [#documentation-requirements] Every API change should update: * endpoint docs under External API; * `apps/docs/public/openapi/whagons-v1.json`; * [API Changelog](/docs/external-api/changelog); * internal implementation notes when the Convex auth, scope, or route model changes. # Core concepts (/docs/product/concepts) These concepts appear throughout the product, API, and agent documentation. ## Tenant [#tenant] A **tenant** is one customer's isolated Whagons environment. It owns its branding, users, teams, settings, workspaces, tasks, and enabled powerups. A person may belong to more than one tenant. Permissions, API keys, and agent approvals always apply within a selected tenant. ## User, role, and team [#user-role-and-team] * A **user** is a person with access to the tenant. * A **role** grants product permissions, such as viewing tasks or managing integrations. * A **team** groups users around an operating responsibility, such as Housekeeping, Maintenance, Front Desk, or Store Operations. Teams matter for task ownership, assignment, visibility, and status changes. A broad role does not automatically make every operational task visible. ## Spot [#spot] A **spot** is a physical or logical location. Spots can be nested. Examples include a property, building, floor, room, store, production line, vehicle, or equipment area. Tasks can point to a spot so work is tied to the place where it occurs. ## Workspace [#workspace] A **workspace** is an operating view where a team sees and manages related tasks. It can represent a department queue, project, shift, review lane, or cross-team control room. A workspace can combine a task grid with filters, saved views, calendar or board views, chat, resources, whiteboards, and KPI cards. ## Task [#task] A **task** is the canonical record of operational work. It owns the title, description, location, status, priority, dates, comments, attachments, assignments, tags, forms, approvals, acknowledgments, and history associated with that work. Whagons keeps one source task even when that task needs to appear in another workspace for approval or acknowledgment. ## Task type [#task-type] A **task type**—also called a **category** in the API—defines the policy around a class of work. It can determine the owning team, allowed templates, forms, approval behavior, statuses, priorities, and where tasks may be created. Do not assume task type names are identical between tenants. ## Template [#template] A **template** is a reusable starting point for a task. It can provide instructions, default priority, expected duration, a form, default assignees, signature requirements, and other repeatable values. Task types define the broad policy; templates define specific repeatable jobs within that policy. ## Status and priority [#status-and-priority] * A **status** describes the task's lifecycle position, such as New, In Progress, Waiting, or Completed. * A **priority** communicates operational urgency. Both are tenant-configurable and can be limited by task type. Integrations should resolve their IDs instead of relying on a hard-coded English name. ## Form and custom field [#form-and-custom-field] * A **form** collects structured responses and may be versioned, reviewed, scored, or shared publicly. * A **custom field** adds tenant-defined data directly to tasks, task types, templates, or spots. Use a form for a guided collection experience. Use custom fields when the value should behave like durable metadata on the task. ## Approval and acknowledgment [#approval-and-acknowledgment] * An **approval** asks an authorized person or group to accept or reject work. * An **acknowledgment** asks a recipient to confirm they have read or received it. Both can place the original task into an action-specific workspace context without creating a copied task. ## SLA and workflow [#sla-and-workflow] * An **SLA** measures and escalates time commitments. * A **workflow** reacts to events and conditions with automated actions. Together they turn an ordinary task list into a controlled operating process. ## Powerup [#powerup] A **powerup** is an optional Whagons module layered on the shared tenant, user, workspace, and task foundation. Enabled powerups vary by tenant. Continue with [Workspaces and tasks](/docs/product/workspaces-and-tasks), or use the [Glossary](/docs/product/glossary) as a quick reference. # Glossary (/docs/product/glossary) | Term | Meaning | | -------------- | ---------------------------------------------------------------------------------------------------- | | Acknowledgment | Confirmation that a user or audience has read or received a task or communication. | | Agent token | A short-lived `whg_agent_…` credential issued after a user approves an agent. | | API key | A `whg_live_…` credential created in Settings → Integrations for programmatic access. | | Approval | A policy and decision process that accepts or rejects work. | | Assignee | A user currently responsible for a task. | | Category | API and data-model name for a task type. | | Custom field | Tenant-defined metadata attached to tasks or related configuration. | | Form | A structured, versioned collection of inputs or evidence. | | `pgId` | Optional legacy numeric identifier present on some records. | | Powerup | Optional operational module enabled for a tenant. | | Priority | Tenant-defined urgency level. | | Reporter | The user or team that originated or reported a task. | | SLA | Service-level timing and escalation policy. | | Spot | Physical or logical location, optionally nested. | | Status | Tenant-defined point in a task lifecycle. | | Task | Canonical record of operational work. | | Task context | An action-specific view of a source task in another workspace, often for approval or acknowledgment. | | Task type | Policy and classification for a class of work; called a category in the API. | | Team | Group of users responsible for an operating area. | | Template | Reusable starting configuration for a task. | | Tenant | One customer's isolated Whagons environment. | | Workflow | Event-and-condition automation that performs actions. | | Workspace | Operating surface where a team sees and manages tasks. | If a tenant uses different labels, the underlying API field names remain stable unless the endpoint documentation says otherwise. # What is Whagons? (/docs/product) Whagons is an operations platform for teams that coordinate real-world work. It gives each organization a shared system for receiving work, routing it to the right people and places, following it through a controlled lifecycle, and learning from the result. The simplest mental model is: ```txt People + places + operating rules ↓ Workspaces ↓ Tasks ↓ Forms · approvals · SLAs · automations · reporting ``` ## The core loop [#the-core-loop] 1. An administrator models the organization with teams, users, roles, and spots. 2. Task types, templates, forms, statuses, and priorities define how work should look. 3. Work arrives in a workspace as a task. 4. People assign, discuss, update, approve, acknowledge, or complete that task. 5. Logs, timing, KPI cards, and analytics make the operation measurable. ## Product layers [#product-layers] | Layer | What it answers | Examples | | --------------- | ---------------------------------------------- | ------------------------------------------------------------------------------- | | Organization | Who does the work, and where? | Users, teams, roles, job positions, spots. | | Work management | What needs to happen? | Workspaces, tasks, task types, templates, assignments. | | Process control | How should it happen? | Forms, statuses, priorities, SLAs, approvals, acknowledgments, workflows. | | Collaboration | How do people coordinate? | Comments, attachments, messages, broadcasts, boards, shared resources. | | Intelligence | What can we learn or automate? | KPI cards, analytics, exports, AI assistant. | | Powerups | Which specialized tools does this tenant need? | Scheduling, training, assets, purchasing, standards, cleaning, costs, and more. | ## Built for different operations [#built-for-different-operations] Every Whagons tenant can have its own branding, language, terminology, permissions, workflow, and enabled modules. A hotel may organize work by room and department. A facilities team may use buildings, assets, and maintenance queues. A retailer may use stores, shifts, purchasing, and audits. The shared foundation remains the same: one tenant, permission-aware users, visible workspaces, and canonical tasks. ## Where to go next [#where-to-go-next] * If you are setting up a tenant, start with [Core concepts](/docs/product/concepts) and [Workflow controls](/docs/product/workflows-and-controls). * If you are building an integration, go to the [API quickstart](/docs/external-api/quickstart). * If you are connecting an autonomous tool, read [Agents](/docs/agents). # Permissions and visibility (/docs/product/permissions) Whagons combines role permissions with operational context. Authentication answers who is acting; authorization decides what that actor may see or change right now. ## Authorization layers [#authorization-layers] | Layer | Examples | | ------------------- | ---------------------------------------------------------------------------------------------------------- | | Tenant | The user, key, or agent must belong to the requested tenant. | | Role | Permissions allow actions such as viewing tasks, assigning work, deleting tasks, or managing integrations. | | Team | Membership affects ownership, creation, visibility, and status changes. | | Workspace | Users may only see workspaces granted by their role and team structure. | | Task | Reporter, assignee, team, workspace, and action context can affect visibility. | | Field and lifecycle | A user may see a task but be unable to edit a protected field or make an invalid status move. | ## Built-in roles [#built-in-roles] Whagons includes protected system roles such as tenant owner, administrator, leader, member, and viewer, with a system-administrator role for platform operations. Tenants can also use custom roles and permission sets. Role names are only one part of the decision. An administrator may manage configuration while still being limited by operational team membership for certain task actions. ## API keys [#api-keys] An API key created in Settings → Integrations acts as the user who created it. The key adds API scopes, but it does not bypass that user's current product permissions. If the creator loses a role, team, workspace, or tenant membership, the key loses the corresponding access. Disabling, expiring, or revoking the key blocks it entirely. ## Agent tokens [#agent-tokens] A user-claimed agent token acts on behalf of the user who approved the agent for the selected tenant. It is short-lived, scoped, revocable, and auditable. The token does not grant the agent more access than the approving user has. ## The built-in assistant [#the-built-in-assistant] The Whagons assistant uses the signed-in user's context. Read operations remain permission-bound. Write operations use curated actions, and sensitive or destructive changes require explicit user intent and, where supported, a confirmation step. ## Integration design guidance [#integration-design-guidance] * Create integration users with only the teams and workspaces the integration needs. * Create separate API keys for separate systems or environments. * Prefer expirations and rotate keys regularly. * Test visibility with the same user who will own the key. * Treat a `401` as an authentication or scope problem; treat a denied operation as a product-permission or policy problem. See [API keys](/docs/external-api/api-keys) and [Agent safety](/docs/agents/safety) for operational guidance. # Powerups (/docs/product/powerups) Powerups extend Whagons beyond the core workspace and task system. Each tenant enables only the modules relevant to its operation, so two customers may have a very different navigation menu while sharing the same task foundation. ## Common powerup families [#common-powerup-families] | Family | Examples | Typical use | | ------------------------ | ------------------------------------------------------- | ---------------------------------------------------------------- | | Planning | Scheduling, workplans, working hours, time off | Coordinate shifts, capacity, and planned work. | | Knowledge and compliance | Standards, SOPs, documents, training | Publish procedures, train teams, and review compliance. | | Assets and inventory | Assets, tools, QR codes, NFC | Track equipment, custody, location, and scan-driven actions. | | Commercial operations | Purchasing, suppliers, costs, budgets, CRM | Connect operational work to vendors, requests, and spend. | | Communication | Broadcasts, boards, messages | Coordinate teams outside a single task thread. | | Insight | Activity, analytics, KPI cards, gamification, goals | Measure throughput, outcomes, and engagement. | | Vertical operations | Cleaning, operations manager, industry-specific modules | Support specialized frontline workflows. | | Workbench | Write, Grid, Present | Create collaborative documents, spreadsheets, and presentations. | ## How powerups connect to core work [#how-powerups-connect-to-core-work] Powerups can introduce their own pages and records, but they normally reuse tenant identity, teams, spots, permissions, and tasks. A purchasing request might create approval work. A training module can use teams and assignments. An asset scan can open a task tied to a location. ## Availability [#availability] A powerup may be: * disabled for the tenant; * available only to certain roles; * enabled but not yet configured; * white-labeled or renamed for the organization; * in a staged rollout. If a page described here is not visible, check with a tenant administrator before assuming it is missing. ## API coverage [#api-coverage] The current public v1 API focuses on tenant reference data and tasks. Powerup-specific REST endpoints are not implied by the presence of a product module. Check the [API reference](/docs/external-api/reference) for the supported external surface. # Workflows and controls (/docs/product/workflows-and-controls) Whagons separates the task itself from the policies that shape it. This lets teams change an operating rule without rebuilding every task screen. ## Recommended setup order [#recommended-setup-order] For a new operating process, configure in this order: 1. **Teams and spots** — decide who owns the work and where it happens. 2. **Task type** — define the broad class of work and its owning team. 3. **Workspace** — decide where that work is visible and managed. 4. **Statuses and priorities** — define lifecycle and urgency. 5. **Templates** — create the repeatable jobs users should choose. 6. **Forms and custom fields** — collect the required evidence and metadata. 7. **SLAs and transitions** — add timing commitments and legal status moves. 8. **Approvals and acknowledgments** — add human decisions or receipt confirmation. 9. **Workflows** — automate reactions once the underlying model is stable. ## Templates [#templates] Templates reduce variation at task creation. A template can carry instructions, expected duration, form association, default priority, default users, signature requirements, and location behavior. Use clear, action-oriented template names. “Inspect guest room” is more useful than “Inspection.” ## Forms [#forms] Forms support guided, structured collection. Current form designs can include short and long text, numbers, selection controls, lists, dates and times, images, signatures, barcodes, sections, fixed content, tables, timers, and GPS capture. Forms are versioned so existing submissions keep the structure they were completed against. ## Custom fields [#custom-fields] Custom fields are useful for values that should be filterable or visible directly on task records, such as cost center, asset number, guest impact, inspection score, or external reference. Fields can be assigned through task types or templates and may have formulas or validation rules. ## Status transitions [#status-transitions] Status-transition groups define which lifecycle moves are valid. A user or integration may have permission to change status and still be blocked from making an invalid transition. Status changes can also be constrained by owning-team membership, pending approvals, and field-level policy. ## SLAs [#slas] SLAs add service timing and escalation. They can measure response or resolution commitments and notify or escalate when thresholds are approached or missed. ## Approvals [#approvals] Approval policies can support sequential or parallel review, minimum approval counts, required comments or signatures, deadlines, conditional triggers, and outcome actions. An approval is a decision about the source task. It is not a separate copy of the work. ## Acknowledgments [#acknowledgments] Acknowledgments are suited to broadcasts, handoffs, safety notices, and tasks that require confirmed receipt rather than an accept/reject decision. Audiences may target users, teams, roles, or location-based groups. ## Workflows [#workflows] Workflows listen for events such as task creation, updates, status changes, assignment, completion, approval, rejection, or acknowledgment. Conditions can narrow the trigger by workspace, task type, template, team, status, priority, assignee, creator, form, SLA, or tag. Actions can update work, create follow-up tasks, assign users, send messages or email, share to teams, request acknowledgment, or call an integration webhook when configured. Start with the smallest rule that solves the operational need. Add branches only after the basic path is observable and reliable. # Workspaces and tasks (/docs/product/workspaces-and-tasks) Workspaces are where teams operate. Tasks are the work moving through them. ## What a workspace provides [#what-a-workspace-provides] Depending on tenant configuration and enabled features, a workspace can include: * a sortable and filterable task grid; * saved views and search; * calendar, board, map, or timeline views; * workspace chat and shared resources; * KPI cards and operational summaries; * creation controls limited to allowed task types and templates; * task dialogs for details, forms, comments, attachments, approvals, and history. The **All Workspaces** view brings together tasks a user can see across their normal and action-specific contexts. ## Anatomy of a task [#anatomy-of-a-task] Common task data includes: | Area | Examples | | --------------- | --------------------------------------------------------------------------- | | Identity | Human title, description, stable document ID, optional numeric task number. | | Classification | Workspace, task type, template, team. | | Location | Spot and optional coordinates. | | Lifecycle | Status, priority, start date, due date, completion time. | | People | Creator, reporter, assignees, mentioned users. | | Structured work | Form responses and custom fields. | | Collaboration | Comments, attachments, tags, messages. | | Control | Approval, acknowledgment, SLA, transition rules. | | History | Task log and status-transition timing. | ## Typical task lifecycle [#typical-task-lifecycle] 1. A user, workflow, import, API integration, or agent creates the task. 2. Whagons validates the workspace and task-type policy. 3. Defaults from templates, statuses, priorities, and assignments are applied. 4. Users work the task, add evidence, complete forms, and change allowed fields. 5. Approval or acknowledgment steps appear when configured. 6. A valid final status completes the task and records its history. ## Visibility is contextual [#visibility-is-contextual] Users do not automatically see every task in a tenant. Visibility can depend on: * role permissions; * team membership; * workspace access; * task ownership or assignment; * reporter visibility; * an approval or acknowledgment context; * tenant-specific policy. This same visibility model applies to Settings-issued API keys and delegated agent tokens because both act on behalf of a user. ## One task, multiple action contexts [#one-task-multiple-action-contexts] When another team needs to approve or acknowledge work, Whagons keeps the original task as the source of truth. The task can appear in an additional workspace with an action context, but its content, comments, attachments, approval state, and audit history stay connected to the same task. This prevents conflicting copies and gives integrations one stable task to reference. ## Finding a task [#finding-a-task] In the product, users can search and filter workspace grids. In the API, clients can fetch by the task's document `taskId`, by its numeric `pgId` when present, or list tasks using workspace, status, priority, team, spot, template, assignment, and text filters. See [Task API operations](/docs/external-api/tasks) for technical details.