Naming conventions & compatibility
The canonical naming conventions for the Well API, and the alias policy that keeps legacy forms working with no breaking change.
This page defines one canonical convention per naming dimension. Where the current API differs, the legacy form remains an accepted alias (deprecated, never removed inside /v1), so adopting the canon is non-breaking.
/v1, no name is ever removed. Legacy params, type values, pagination shapes, and enum casings keep working as aliases. The canonical form is preferred for new integrations; the legacy form is marked deprecated.Path parameters — {resource_id} (applied)
Every id path parameter is the resource it identifies, snake_case: {task_id}, {skill_id}, {workspace_group_id}, {field_key}. Non-id keys stay as themselves ({slug}, {root}, {code}). This is already applied across the reference — and it is non-breaking because a path parameter name is a placeholder, not part of the URL (/v1/skills/{skill_id} and /v1/skills/{x} address the same endpoint). It also resolves the prior {workspaceId} vs {workspace_id} duplicate and aligns the field_key attribute with its {field_key} path param.
Resource type discriminator — plural-kebab
The JSON:API data.type canon is plural, kebab-case: tasks, skills, custom-columns, field-rules, workspace-groups, connector-combinations, providers.
| Canonical | Accepted legacy aliases |
|---|---|
skills | skill |
custom-columns | custom_column |
field-rules | field_rule |
workspace-groups | workspace-group |
connector-combinations | connector-combination |
On write, the server accepts either the canonical or the legacy type. On read, responses currently emit the legacy value; the canonical value is what new clients should send. (The RPC-style types like custom_column_infer belong to action endpoints — see the conventions page; they are request envelopes, not resources.)
Query parameters — snake_case
All query parameters are snake_case. Legacy camelCase params remain accepted as aliases.
| Canonical | Accepted legacy alias |
|---|---|
workspace_id | workspaceId |
include_coming_soon | includeComingSoon |
order_by | orderBy |
The workspace identifier is always workspace_id (query) — the prior five spellings collapse to one, with the others accepted as aliases.
Pagination — cursor-based
The canon is keyset cursor pagination, everywhere:
| Canonical | Accepted legacy aliases | |
|---|---|---|
| Request | cursor + limit | page + limit; page[cursor]/page[limit]; page[number]/page[size] |
| Response | meta { count } + links.next (opaque cursor) | meta.pagination { page, limit, total, total_pages } |
links.next is null on the last page. Offset params (page, page[number]) keep working but are deprecated; new clients page with cursor. See Conventions → Pagination.
Date-range filters — filter[<field>][gte|lte]
The canon aligns with the records whereClause operators:
| Canonical | Accepted legacy aliases |
|---|---|
filter[created_at][gte] / filter[created_at][lte] | created_at_from / created_at_to; filter[created_at_from]; filter[created_at][from] / [to] |
Per the API Reference Standard (§6.3 operator alignment), bounded ranges use gte/lte; the four legacy forms remain accepted.
Enum value casing — lower_snake for application status
Application status/lifecycle enums are lower_snake (open, in_progress, done). Some enums keep their domain-standard casing as an explicit, documented exception — they are not "inconsistent", they follow an external standard:
| Casing | Enums | Why |
|---|---|---|
lower_snake (canon) | task_status, blueprint_run_status, document_processing_status, collect_status, connector_sync_status, … (39 enums) | application convention |
| UPPER (exception) | journal_entry_status (DRAFT/VALIDATED/LOCKED), ledger_account_type, journal_type, accounting_framework (PCG/IFRS), tax_scheme, tax_type, transaction_scheme | accounting / ledger domain standard |
| External code (exception) | currency_code (ISO 4217), country_code (ISO 3166), invoice_line_unit (UN/ECE) | the value IS the external standard |
New application enums use lower_snake. Existing values are never re-cased inside /v1; where a status enum will migrate, the server accepts both casings during the deprecation window.
How this is enforced going forward
These conventions become a lint on the generated spec (see the OpenAPI generator design): the build fails on a non-canonical type, a non-snake query param, a non-cursor pagination shape, or an application status enum that is not lower_snake — while the alias table keeps every legacy form working. That turns this page from a recommendation into an enforced, non-breaking contract.