Download OpenAPI specification:Download
The public REST API for the OutDo platform: authentication, the workspace model (workspaces, modules, rails, features, columns, views), row data, aggregates, and files.
Sign in with POST /v1/auth/token to obtain a bearer token, then click Authorize and paste the access_token. Every request runs with the signed-in user's own permissions — the API enforces the platform's row-level security and never widens access.
Machines authenticate with an organization API key (outdo_sk_…) in the same Authorization: Bearer header. A key belongs to one organization and carries scopes: read for safe methods, write for row writes, and structure for changing the model itself (features, columns, views, automations). structure is additive — it is only granted together with write.
application/problem+json); 422 responses carry an actionable detail. Every error also carries a stable code (e.g. rate_limited, quota_exceeded, no_seats_available); branch on code, not on the English detail text.next_cursor from the previous page back as cursor.Idempotency-Key header on any POST to make retries safe. POST /v1/auth/* and POST /v1/api-keys are excluded: their responses carry credential material, which is never cached; retrying key creation mints a new key.429 responses carry a Retry-After header./v1; breaking changes ship under a new prefix.Machine-readable structure: GET /v1/schema (the caller's visible model) and GET /v1/schema/definitions (what each entity's config accepts).
The guides live at docs.out-do.app: the REST reference, automations (the definition envelope, the validator, and the draft/apply cycle), the generated catalogs of steps and triggers, and the MCP server.
Exchanges a refresh token for a new session; the previous refresh token is rotated.
| refresh_token required | string (Refresh Token) |
{- "refresh_token": "string"
}{- "access_token": "string",
- "expires_in": 0,
- "refresh_token": "string"
}Exchanges OutDo credentials for a bearer session. Authentication failures return a generic 401 (no cause disclosed) and the endpoint is strictly rate-limited.
| email required | string (Email) |
| password required | string (Password) |
{- "email": "string",
- "password": "string"
}{- "access_token": "string",
- "expires_in": 0,
- "refresh_token": "string"
}Cursor-paginated. Returns the organizations the caller owns or belongs to.
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "config": { },
- "id": "string",
- "label": "string",
- "name": "string"
}
], - "next_cursor": "string"
}Returns 404 when the organization does not exist or is not visible to the caller.
| organization_id required | string <uuid> (Organization Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "config": { },
- "id": "string",
- "label": "string",
- "name": "string"
}Partial update of label and/or config. config is REPLACED whole, not merged: read it first and send the complete object. Requires an organization-level admin role; a write the data store refuses comes back as 403, never a silent 200. API keys need the write scope (not structure: this is not model structure).
| organization_id required | string <uuid> (Organization Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Config (object) or Config (null) (Config) | |
Label (string) or Label (null) (Label) |
{- "config": { },
- "label": "string"
}{- "config": { },
- "id": "string",
- "label": "string",
- "name": "string"
}Cursor-paginated. Returns only what row-level security lets the caller see.
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "config": { },
- "default_module_id": "string",
- "id": "string",
- "label": "string",
- "module_order_config": { },
- "name": "string",
- "organization_id": "string",
- "timezone": "string",
- "visibility_policy": "string"
}
], - "next_cursor": "string"
}The caller must be a member of the target organization.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Config (object) or Config (null) (Config) | |
| label required | string (Label) [ 1 .. 120 ] characters |
| name required | string (Name) [ 1 .. 120 ] characters |
| organization_id required | string (Organization Id) |
Timezone (string) or Timezone (null) (Timezone) | |
Visibility Policy (string) or Visibility Policy (null) (Visibility Policy) |
{- "config": { },
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "timezone": "string",
- "visibility_policy": "string"
}{- "config": { },
- "default_module_id": "string",
- "id": "string",
- "label": "string",
- "module_order_config": { },
- "name": "string",
- "organization_id": "string",
- "timezone": "string",
- "visibility_policy": "string"
}Destructive: the database cascades to every module, rail, feature, row, and view inside. A non-empty workspace returns 409 unless force=true.
| workspace_id required | string <uuid> (Workspace Id) |
| force | boolean (Force) Default: false Confirm deleting a NON-EMPTY workspace. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Returns 404 when the workspace does not exist or is not visible to the caller.
| workspace_id required | string <uuid> (Workspace Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "config": { },
- "default_module_id": "string",
- "id": "string",
- "label": "string",
- "module_order_config": { },
- "name": "string",
- "organization_id": "string",
- "timezone": "string",
- "visibility_policy": "string"
}Partial update — only the fields present in the request body are changed.
| workspace_id required | string <uuid> (Workspace Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Config (object) or Config (null) (Config) | |
Default Module Id (string) or Default Module Id (null) (Default Module Id) | |
Label (string) or Label (null) (Label) | |
Module Order Config (object) or Module Order Config (null) (Module Order Config) | |
Name (string) or Name (null) (Name) | |
Timezone (string) or Timezone (null) (Timezone) | |
Visibility Policy (string) or Visibility Policy (null) (Visibility Policy) |
{- "config": { },
- "default_module_id": "string",
- "label": "string",
- "module_order_config": { },
- "name": "string",
- "timezone": "string",
- "visibility_policy": "string"
}{- "config": { },
- "default_module_id": "string",
- "id": "string",
- "label": "string",
- "module_order_config": { },
- "name": "string",
- "organization_id": "string",
- "timezone": "string",
- "visibility_policy": "string"
}Cursor-paginated. Optionally filtered to a single workspace.
Workspace Id (string) or Workspace Id (null) (Workspace Id) Only modules of this workspace. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "default_rail_id": "string",
- "icon": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "rail_order_config": { },
- "workspace_id": "string"
}
], - "next_cursor": "string"
}The organization is derived from the parent workspace — it is never accepted from the client.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Icon (string) or Icon (null) (Icon) | |
| label required | string (Label) [ 1 .. 120 ] characters |
| name required | string (Name) [ 1 .. 120 ] characters |
| workspace_id required | string (Workspace Id) |
{- "icon": "string",
- "label": "string",
- "name": "string",
- "workspace_id": "string"
}{- "default_rail_id": "string",
- "icon": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "rail_order_config": { },
- "workspace_id": "string"
}A module that still has rails returns 409 unless force=true (rails cascade).
| module_id required | string <uuid> (Module Id) |
| force | boolean (Force) Default: false Confirm deleting a module that still has rails. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Returns 404 when the module does not exist or is not visible to the caller.
| module_id required | string <uuid> (Module Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "default_rail_id": "string",
- "icon": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "rail_order_config": { },
- "workspace_id": "string"
}Partial update — only the fields present in the request body are changed.
| module_id required | string <uuid> (Module Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Default Rail Id (string) or Default Rail Id (null) (Default Rail Id) | |
Icon (string) or Icon (null) (Icon) | |
Label (string) or Label (null) (Label) | |
Name (string) or Name (null) (Name) | |
Rail Order Config (object) or Rail Order Config (null) (Rail Order Config) |
{- "default_rail_id": "string",
- "icon": "string",
- "label": "string",
- "name": "string",
- "rail_order_config": { }
}{- "default_rail_id": "string",
- "icon": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "rail_order_config": { },
- "workspace_id": "string"
}Cursor-paginated. Optionally filtered to a single module.
Module Id (string) or Module Id (null) (Module Id) Only rails of this module. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "config": [
- null
], - "id": "string",
- "label": "string",
- "module_id": "string",
- "organization_id": "string",
- "path": "string"
}
], - "next_cursor": "string"
}The organization is derived from the parent module. config lists the views the rail shows; an object is accepted and normalized to the platform's single-item-list shape.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Array of Config (any) or Config (object) or Config (null) (Config) | |
| label required | string (Label) [ 1 .. 120 ] characters |
| module_id required | string (Module Id) |
| path | string (Path) Default: "" |
{- "config": [
- null
], - "label": "string",
- "module_id": "string",
- "path": ""
}{- "config": [
- null
], - "id": "string",
- "label": "string",
- "module_id": "string",
- "organization_id": "string",
- "path": "string"
}Returns 404 when the rail does not exist or is not visible to the caller.
| rail_id required | string <uuid> (Rail Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "config": [
- null
], - "id": "string",
- "label": "string",
- "module_id": "string",
- "organization_id": "string",
- "path": "string"
}Partial update — only the fields present in the request body are changed.
| rail_id required | string <uuid> (Rail Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Array of Config (any) or Config (object) or Config (null) (Config) | |
Label (string) or Label (null) (Label) | |
Path (string) or Path (null) (Path) |
{- "config": [
- null
], - "label": "string",
- "path": "string"
}{- "config": [
- null
], - "id": "string",
- "label": "string",
- "module_id": "string",
- "organization_id": "string",
- "path": "string"
}Cursor-paginated. Optionally filtered to a single workspace.
Workspace Id (string) or Workspace Id (null) (Workspace Id) Only features of this workspace. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "config": { },
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "workspace_id": "string"
}
], - "next_cursor": "string"
}The organization is derived from the parent workspace — it is never accepted from the client.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Config (object) or Config (null) (Config) | |
Label (string) or Label (null) (Label) | |
| name required | string (Name) [ 1 .. 120 ] characters |
| workspace_id required | string (Workspace Id) |
{- "config": { },
- "label": "string",
- "name": "string",
- "workspace_id": "string"
}{- "config": { },
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "workspace_id": "string"
}Destructive: the database cascades to the feature's rows, columns, and views. A feature that still has rows returns 409 unless force=true.
| feature_id required | string <uuid> (Feature Id) |
| force | boolean (Force) Default: false Confirm deleting a feature that still has rows. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Returns 404 when the feature does not exist or is not visible to the caller.
| feature_id required | string <uuid> (Feature Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "config": { },
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "workspace_id": "string"
}Partial update — only the fields present in the request body are changed.
| feature_id required | string <uuid> (Feature Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Config (object) or Config (null) (Config) | |
Label (string) or Label (null) (Label) | |
Name (string) or Name (null) (Name) |
{- "config": { },
- "label": "string",
- "name": "string"
}{- "config": { },
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "workspace_id": "string"
}All column definitions of the feature, in display order.
| feature_id required | string <uuid> (Feature Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
[- {
- "config": { },
- "default_component": "string",
- "externally_visible": false,
- "feature_id": "string",
- "hidden": true,
- "id": "string",
- "initial_value": "string",
- "inline_editable": false,
- "label": "string",
- "name": "string",
- "order": 0,
- "read_only": true,
- "required": true,
- "type": "string"
}
]type and default_component are validated against the platform registries — see GET /v1/schema/definitions for the allowed values.
| feature_id required | string <uuid> (Feature Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
object (Config) | |
| default_component | string (Default Component) Default: "textfield" |
| externally_visible | boolean (Externally Visible) Default: false |
| hidden | boolean (Hidden) Default: false |
Initial Value (string) or Initial Value (null) (Initial Value) | |
| inline_editable | boolean (Inline Editable) Default: false |
| label required | string (Label) [ 1 .. 120 ] characters |
| name required | string (Name) [ 1 .. 64 ] characters |
Order (integer) or Order (null) (Order) | |
| read_only | boolean (Read Only) Default: false |
| required | boolean (Required) Default: false |
| type | string (Type) Default: "text" |
{- "config": { },
- "default_component": "textfield",
- "externally_visible": false,
- "hidden": false,
- "initial_value": "string",
- "inline_editable": false,
- "label": "string",
- "name": "string",
- "order": 0,
- "read_only": false,
- "required": false,
- "type": "text"
}{- "config": { },
- "default_component": "string",
- "externally_visible": false,
- "feature_id": "string",
- "hidden": true,
- "id": "string",
- "initial_value": "string",
- "inline_editable": false,
- "label": "string",
- "name": "string",
- "order": 0,
- "read_only": true,
- "required": true,
- "type": "string"
}Removes the column DEFINITION. Row data keeps the orphaned key — it simply stops being displayed and validated.
| feature_id required | string <uuid> (Feature Id) |
| column_id required | string <uuid> (Column Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Partial update — only the fields present in the request body are changed.
| feature_id required | string <uuid> (Feature Id) |
| column_id required | string <uuid> (Column Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Config (object) or Config (null) (Config) | |
Default Component (string) or Default Component (null) (Default Component) | |
Externally Visible (boolean) or Externally Visible (null) (Externally Visible) | |
Hidden (boolean) or Hidden (null) (Hidden) | |
Initial Value (string) or Initial Value (null) (Initial Value) | |
Inline Editable (boolean) or Inline Editable (null) (Inline Editable) | |
Label (string) or Label (null) (Label) | |
Name (string) or Name (null) (Name) | |
Order (integer) or Order (null) (Order) | |
Read Only (boolean) or Read Only (null) (Read Only) | |
Required (boolean) or Required (null) (Required) | |
Type (string) or Type (null) (Type) |
{- "config": { },
- "default_component": "string",
- "externally_visible": true,
- "hidden": true,
- "initial_value": "string",
- "inline_editable": true,
- "label": "string",
- "name": "string",
- "order": 0,
- "read_only": true,
- "required": true,
- "type": "string"
}{- "config": { },
- "default_component": "string",
- "externally_visible": false,
- "feature_id": "string",
- "hidden": true,
- "id": "string",
- "initial_value": "string",
- "inline_editable": false,
- "label": "string",
- "name": "string",
- "order": 0,
- "read_only": true,
- "required": true,
- "type": "string"
}Cursor-paginated. Supports filtering (filter, match), sorting (sort), and response-side projection (fields) — see each parameter for the grammar.
| feature_id required | string <uuid> (Feature Id) |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
Array of Filter (strings) or Filter (null) (Filter) Repeatable | |
Match (string) or Match (null) (Match) How the filters combine: | |
Sort (string) or Sort (null) (Sort) Sort key: | |
Fields (string) or Fields (null) (Fields) Comma-separated projection of the row |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "created_at": "string",
- "created_by": "string",
- "data": { },
- "feature_id": "string",
- "id": "string",
- "organization_id": "string",
- "updated_at": "string",
- "updated_by": "string"
}
], - "next_cursor": "string"
}data is validated against the feature's column definitions by default — see the validate parameter. Send an Idempotency-Key header to make retries safe.
| feature_id required | string <uuid> (Feature Id) |
Validate (string) or Validate (null) (Validate) Write validation against the feature's columns: |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
required | object (Data) | ||
| |||
{- "data": { }
}{- "created_at": "string",
- "created_by": "string",
- "data": { },
- "feature_id": "string",
- "id": "string",
- "organization_id": "string",
- "updated_at": "string",
- "updated_by": "string"
}Returns 204 on success; 404 when the row does not exist, is not visible, or the caller may not delete it.
| feature_id required | string <uuid> (Feature Id) |
| row_id required | string <uuid> (Row Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Returns 404 when the row does not exist or is not visible to the caller.
| feature_id required | string <uuid> (Feature Id) |
| row_id required | string <uuid> (Row Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "created_at": "string",
- "created_by": "string",
- "data": { },
- "feature_id": "string",
- "id": "string",
- "organization_id": "string",
- "updated_at": "string",
- "updated_by": "string"
}Replaces the whole data object by default; with merge=true the payload is shallow-merged over the current data and a null value removes the key.
| feature_id required | string <uuid> (Feature Id) |
| row_id required | string <uuid> (Row Id) |
Validate (string) or Validate (null) (Validate) Write validation against the feature's columns: | |
| merge | boolean (Merge) Default: false true → shallow-merge the payload over the current data (a null value removes the key); false (default) → replace the whole data object. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
required | object (Data) | ||
| |||
{- "data": { }
}{- "created_at": "string",
- "created_by": "string",
- "data": { },
- "feature_id": "string",
- "id": "string",
- "organization_id": "string",
- "updated_at": "string",
- "updated_by": "string"
}count is exact and accepts the same filters as the list endpoint. sum/avg compute over a capped sample (10,000 rows — narrow with filters beyond that); non-numeric values are skipped and reported via rows_considered.
| feature_id required | string <uuid> (Feature Id) |
| op required | string (Op) Enum: "count" "sum" "avg" |
Column (string) or Column (null) (Column) Row data key (required for sum/avg). | |
Array of Filter (strings) or Filter (null) (Filter) Repeatable | |
Match (string) or Match (null) (Match) How the filters combine: |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "column": "string",
- "op": "string",
- "rows_considered": 0,
- "value": 0
}Up to 500 rows in one atomic insert — if any row is rejected, the whole batch rolls back. Validation errors name the offending row (rows[i]: …).
| feature_id required | string <uuid> (Feature Id) |
Validate (string) or Validate (null) (Validate) Write validation against the feature's columns: |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
required | Array of objects (Rows) [ 1 .. 500 ] items | ||||||
Array ([ 1 .. 500 ] items)
| |||||||
{- "rows": [
- {
- "data": { }
}
]
}{- "count": 0,
- "items": [
- {
- "created_at": "string",
- "created_by": "string",
- "data": { },
- "feature_id": "string",
- "id": "string",
- "organization_id": "string",
- "updated_at": "string",
- "updated_by": "string"
}
]
}Cursor-paginated. Optionally filtered to a single feature.
Feature Id (string) or Feature Id (null) (Feature Id) Only views of this feature. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "config": [
- null
], - "feature_id": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "type": "string"
}
], - "next_cursor": "string"
}type is validated against the view registry (see GET /v1/schema/definitions). config accepts an object or a list and is normalized to the platform's single-item-list shape. API keys need the structure scope.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Array of Config (any) or Config (object) or Config (null) (Config) | |
| feature_id required | string (Feature Id) |
| label required | string (Label) [ 1 .. 120 ] characters |
| name required | string (Name) [ 1 .. 120 ] characters |
| type required | string (Type) |
{- "config": [
- null
], - "feature_id": "string",
- "label": "string",
- "name": "string",
- "type": "string"
}{- "config": [
- null
], - "feature_id": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "type": "string"
}Returns 404 when the view does not exist or is not visible to the caller.
| view_id required | string <uuid> (View Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "config": [
- null
], - "feature_id": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "type": "string"
}Partial update — only the fields present in the request body are changed.
| view_id required | string <uuid> (View Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Array of Config (any) or Config (object) or Config (null) (Config) | |
Label (string) or Label (null) (Label) | |
Name (string) or Name (null) (Name) |
{- "config": [
- null
], - "label": "string",
- "name": "string"
}{- "config": [
- null
], - "feature_id": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "type": "string"
}Workspaces → features → columns + views, nested. Structure only (no rows). truncated: true means a size cap was hit — narrow with workspace_id.
Workspace Id (string) or Workspace Id (null) (Workspace Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "counts": {
- "columns": 0,
- "features": 0,
- "modules": 0,
- "rails": 0,
- "views": 0,
- "workspaces": 0
}, - "truncated": true,
- "workspaces": [
- {
- "default_module_id": "string",
- "features": [
- {
- "columns": [
- {
- "config": { },
- "default_component": "string",
- "externally_visible": false,
- "feature_id": "string",
- "hidden": true,
- "id": "string",
- "initial_value": "string",
- "inline_editable": false,
- "label": "string",
- "name": "string",
- "order": 0,
- "read_only": true,
- "required": true,
- "type": "string"
}
], - "config": { },
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "views": [
- {
- "config": [
- null
], - "feature_id": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "type": "string"
}
], - "workspace_id": "string"
}
], - "id": "string",
- "label": "string",
- "modules": [
- {
- "default_rail_id": "string",
- "icon": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "rails": [
- {
- "config": [
- null
], - "id": "string",
- "label": "string",
- "module_id": "string",
- "organization_id": "string",
- "path": "string"
}
], - "workspace_id": "string"
}
], - "name": "string",
- "organization_id": "string"
}
]
}Static, versioned reference for programmatic builders (the AI MCP): allowed column types and components, view types and their config shapes, feature/workspace/rail/module config keys, row-data and file-metadata conventions. The write endpoints validate against these same allow-lists. source tells you where the reference came from: generated (emitted from the platform's field declarations) or legacy (the hand-maintained fallback, which may lag the code). format=legacy forces the older hand-maintained SHAPE (top-level column, view, components, view_config, ...): kept for one release so existing callers can migrate, and then removed. Build new clients on the default.
| format | string (Format) Deprecated Default: "generated" Enum: "generated" "legacy" DEPRECATED: |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{ }Multipart upload. The object path is built server-side as feature_{feature_id}/column_{column_id}/{timestamp}_{fileName}; the response is the exact metadata object a file component stores in row data.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
| column_id required | string <uuid> (Column Id) |
| feature_id required | string <uuid> (Feature Id) |
| file required | string <application/octet-stream> (File) |
{- "fileName": "string",
- "fileSize": 0,
- "mimeType": "string",
- "path": "string",
- "syncStatus": "synced"
}Returns a time-limited URL (1 minute to 7 days, default 1 hour) for a stored object. Visibility follows the same permissions as the file's feature.
| path required | string (Path) The stored object path (FileOut.path). |
Expires In (integer) or Expires In (null) (Expires In) Lifetime in seconds, 60 to 604800. Defaults to 3600. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "expires_in": 0,
- "url": "string"
}Cursor-paginated. Optionally filtered to a single workspace.
Workspace Id (string) or Workspace Id (null) (Workspace Id) Only workflows of this workspace. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "description": "string",
- "id": "string",
- "is_active": true,
- "name": "string",
- "organization_id": "string",
- "trigger_config": { },
- "workspace_id": "string"
}
], - "next_cursor": "string"
}Returns 404 when the workflow does not exist or is not visible to the caller.
| workflow_id required | string <uuid> (Workflow Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "description": "string",
- "id": "string",
- "is_active": true,
- "name": "string",
- "organization_id": "string",
- "trigger_config": { },
- "workspace_id": "string"
}Newest first. Cursor-paginated.
| workflow_id required | string <uuid> (Workflow Id) |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "completed_at": "string",
- "error_message": "string",
- "id": "string",
- "input_data": { },
- "is_dry_run": true,
- "output_data": { },
- "started_at": "string",
- "status": "string",
- "steps_executed": 0,
- "total_steps": 0,
- "trigger_type": "string",
- "triggered_by": "string",
- "workflow_id": "string",
- "workspace_id": "string"
}
], - "next_cursor": "string"
}Returns 404 when the run does not exist or is not visible to the caller.
| workflow_id required | string <uuid> (Workflow Id) |
| run_id required | string <uuid> (Run Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "completed_at": "string",
- "error_message": "string",
- "id": "string",
- "input_data": { },
- "is_dry_run": true,
- "output_data": { },
- "started_at": "string",
- "status": "string",
- "steps_executed": 0,
- "total_steps": 0,
- "trigger_type": "string",
- "triggered_by": "string",
- "workflow_id": "string",
- "workspace_id": "string"
}Queues one run of the workflow with the given input and returns it immediately (202 — execution is asynchronous). Poll the run's status until it reaches success, failed, or cancelled. Inactive workflows return 409. Send an Idempotency-Key header to make retries safe.
| workflow_id required | string <uuid> (Workflow Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
| dry_run | boolean (Dry Run) Default: false |
object (Input Data) |
{- "dry_run": false,
- "input_data": { }
}{- "completed_at": "string",
- "error_message": "string",
- "id": "string",
- "input_data": { },
- "is_dry_run": true,
- "output_data": { },
- "started_at": "string",
- "status": "string",
- "steps_executed": 0,
- "total_steps": 0,
- "trigger_type": "string",
- "triggered_by": "string",
- "workflow_id": "string",
- "workspace_id": "string"
}Post a message to a scope — a channel, feature, feature row, workspace, or organization. The organization is derived from the scope and the sender is the authenticated caller; neither is accepted from the body. Authorization is decided by the Message INSERT policy (organization membership): a caller who cannot see the scope gets 404.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
| content required | string (Content) non-empty |
Metadata (object) or Metadata (null) (Metadata) | |
Parent Id (string) or Parent Id (null) (Parent Id) | |
| scope_id required | string (Scope Id) |
| scope_type required | string (Scope Type) |
| type | string (Type) Default: "chat" |
{- "content": "string",
- "metadata": { },
- "parent_id": "string",
- "scope_id": "string",
- "scope_type": "string",
- "type": "chat"
}{- "content": "string",
- "created_at": "string",
- "id": "string",
- "metadata": { },
- "organization_id": "string",
- "parent_id": "string",
- "scope_id": "string",
- "scope_type": "string",
- "sender_id": "string",
- "type": "string",
- "updated_at": "string"
}Cursor-paginated. Returns key metadata (never the secret). Optionally filtered to one organization.
Organization Id (string) or Organization Id (null) (Organization Id) Only keys of this organization. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "created_at": "string",
- "created_by": "string",
- "expires_at": "string",
- "id": "string",
- "key_prefix": "string",
- "last_used_at": "string",
- "name": "string",
- "organization_id": "string",
- "revoked_at": "string",
- "role": "string",
- "scopes": [
- "string"
], - "workspace_id": "string"
}
], - "next_cursor": "string"
}Mints a scoped API key backed by a machine user. The response carries the plaintext secret once — store it now, it cannot be retrieved again. The key acts as a member of the organization with the given role and scopes; requires permission to manage the organization's keys. Set expires_at (ISO-8601) or expires_in_days for a time-limited key; omit both for a non-expiring key.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Expires At (string) or Expires At (null) (Expires At) Absolute expiry as ISO-8601 UTC. Mutually exclusive with expires_in_days. | |
Expires In Days (integer) or Expires In Days (null) (Expires In Days) Relative expiry in days from creation. Mutually exclusive with expires_at. | |
| name required | string (Name) [ 1 .. 120 ] characters |
| organization_id required | string (Organization Id) |
| role | string (Role) Default: "user" Enum: "admin" "dev" "user" "view" |
| scopes | Array of strings (Scopes) non-empty Items Enum: "read" "write" "structure" |
Workspace Id (string) or Workspace Id (null) (Workspace Id) |
{- "expires_at": "string",
- "expires_in_days": 1,
- "name": "string",
- "organization_id": "string",
- "role": "admin",
- "scopes": [
- "read"
], - "workspace_id": "string"
}{- "created_at": "string",
- "created_by": "string",
- "expires_at": "string",
- "id": "string",
- "key_prefix": "string",
- "last_used_at": "string",
- "name": "string",
- "organization_id": "string",
- "revoked_at": "string",
- "role": "string",
- "scopes": [
- "string"
], - "secret": "string",
- "workspace_id": "string"
}Revokes the key and tears down its machine user's membership immediately — the key can no longer authenticate. Idempotent.
| key_id required | string <uuid> (Key Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "code": "error",
- "detail": "string",
- "instance": "string",
- "status": 0,
- "title": "string",
- "type": "about:blank"
}Returns key metadata (never the secret). 404 when not visible to the caller.
| key_id required | string <uuid> (Key Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "created_at": "string",
- "created_by": "string",
- "expires_at": "string",
- "id": "string",
- "key_prefix": "string",
- "last_used_at": "string",
- "name": "string",
- "organization_id": "string",
- "revoked_at": "string",
- "role": "string",
- "scopes": [
- "string"
], - "workspace_id": "string"
}WorkflowV2 automations: list and read definitions, validate a graph, create a workflow as a draft, add a version, and apply a draft. Writes need the structure scope. Activation is never an API call — a person turns the automation on in the app. The envelope of a definition and the full vocabulary are documented at docs.out-do.app/reference/workflows-v2.
Cursor-paginated. Each item is ONE VERSION of a workflow; workflow_id groups the versions of a logical workflow. Pass active=true for the versions that are currently firing. active=false is not a filter: a superseded version is also inactive, so it would list live workflows as if they were stopped.
Workspace Id (string) or Workspace Id (null) (Workspace Id) Only workflows of this workspace. | |
Active (boolean) or Active (null) (Active) Only the currently firing versions. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "archived_at": "string",
- "created_at": "string",
- "created_by": "string",
- "deactivation_reason": "string",
- "description": "string",
- "graph_config": { },
- "id": "string",
- "is_active": false,
- "is_draft": false,
- "label": "",
- "name": "",
- "organization_id": "string",
- "trigger_config": { },
- "updated_at": "string",
- "version": 1,
- "workflow_id": "string",
- "workspace_id": "string"
}
], - "next_cursor": "string"
}Creates the automation as a DRAFT (a draft never fires). The definition is validated first: errors are a 422 and nothing is written. organization_id and workflow_id are not accepted: the first is derived from the workspace, the second is minted server-side. Pass is_draft: false to create AND apply it in one call; the result is an applied but INACTIVE version, which you then activate in the app. Send an Idempotency-Key header to make retries safe. API keys need the structure scope. The envelope is documented at docs.out-do.app/reference/workflows-v2.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Description (string) or Description (null) (Description) | |
object (Graph Config) What happens next: | |
| is_draft | boolean (Is Draft) Default: true Create as a draft, which never fires, and publish it later with |
Label (string) or Label (null) (Label) | |
| name required | string (Name) [ 1 .. 120 ] characters |
object (Trigger Config) What fires the automation: | |
| workspace_id required | string <uuid> (Workspace Id) |
{- "graph_config": {
- "steps": [
- {
- "config": {
- "condition": {
- "op": "eq",
- "subject": "var",
- "value": "Validado",
- "var": "{{vars.trigger.estado}}"
}, - "else": [ ],
- "then": [
- {
- "config": {
- "bindings": [
- {
- "targetColumn": "notas",
- "type": "text",
- "value": "Validado em {{sys.today}}"
}
], - "mode": "updateTrigger",
- "targetFeatureId": "d174bd26-c7f0-46ed-a2e3-7bad133b28ce"
}, - "id": "stp_escrever0001",
- "key": "feature.write"
}
]
}, - "id": "stp_ifestado0001",
- "key": "ifElse"
}
]
}, - "name": "Note validated purchases",
- "trigger_config": {
- "config": {
- "featureId": "d174bd26-c7f0-46ed-a2e3-7bad133b28ce",
- "modes": [
- "updated"
], - "watchedColumns": [
- "estado"
]
}, - "type": "record.event"
}, - "workspace_id": "a5a50556-ef07-449d-a556-077a2a310461"
}{- "archived_at": "string",
- "created_at": "string",
- "created_by": "string",
- "deactivation_reason": "string",
- "description": "string",
- "graph_config": { },
- "id": "string",
- "is_active": false,
- "is_draft": false,
- "label": "",
- "name": "",
- "organization_id": "string",
- "trigger_config": { },
- "updated_at": "string",
- "version": 1,
- "workflow_id": "string",
- "workspace_id": "string"
}Runs the platform's graph validator over {trigger_config, graph_config} and returns {ok, issues}. Writes NOTHING: a definition with errors is a 200 with ok: false, not a rejection. ok means no ERRORS; warnings never block. Each issue carries a stable code to branch on, and target tells you where it is fixed (trigger or the path inside the graph). Pass workspace_id (or call with an API key, which carries its organization) so the validator can authorize. It writes nothing, so an API key only needs the read scope.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
object (Graph Config) What happens next: | |
object (Trigger Config) What fires the automation: | |
Workflow Id (string) or Workflow Id (null) (Workflow Id) The workflow this graph belongs to, so self-recursion is detected. | |
Workspace Id (string) or Workspace Id (null) (Workspace Id) |
{- "graph_config": {
- "steps": [
- {
- "config": {
- "condition": {
- "op": "eq",
- "subject": "var",
- "value": "Validado",
- "var": "{{vars.trigger.estado}}"
}, - "else": [ ],
- "then": [
- {
- "config": {
- "bindings": [
- {
- "targetColumn": "notas",
- "type": "text",
- "value": "Validado em {{sys.today}}"
}
], - "mode": "updateTrigger",
- "targetFeatureId": "d174bd26-c7f0-46ed-a2e3-7bad133b28ce"
}, - "id": "stp_escrever0001",
- "key": "feature.write"
}
]
}, - "id": "stp_ifestado0001",
- "key": "ifElse"
}
]
}, - "trigger_config": {
- "config": {
- "featureId": "d174bd26-c7f0-46ed-a2e3-7bad133b28ce",
- "modes": [
- "updated"
], - "watchedColumns": [
- "estado"
]
}, - "type": "record.event"
}, - "workspace_id": "a5a50556-ef07-449d-a556-077a2a310461"
}{- "issues": [
- {
- "code": "string",
- "field_path": "string",
- "message": "string",
- "path": "",
- "severity": "string",
- "target": "graph"
}
], - "ok": true
}By default returns the version that represents the workflow: the active one, or the latest APPLIED one when the workflow is paused. Never the unapplied draft, unless the workflow has nothing else. Pass version for an exact snapshot.
| workflow_id required | string <uuid> (Workflow Id) |
Version (integer) or Version (null) (Version) An exact version of this workflow. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "archived_at": "string",
- "created_at": "string",
- "created_by": "string",
- "deactivation_reason": "string",
- "description": "string",
- "graph_config": { },
- "id": "string",
- "is_active": false,
- "is_draft": false,
- "label": "",
- "name": "",
- "organization_id": "string",
- "trigger_config": { },
- "updated_at": "string",
- "version": 1,
- "workflow_id": "string",
- "workspace_id": "string"
}Promotes the draft to a version, PRESERVING the activation state: a paused workflow stays paused and a brand-new one is born inactive. Validated first; the data store also re-checks, under a lock, that neither the draft nor its base moved (409 if they did, which means reload and reconcile, never retry). API keys need the structure scope.
| workflow_id required | string <uuid> (Workflow Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "archived_at": "string",
- "created_at": "string",
- "created_by": "string",
- "deactivation_reason": "string",
- "description": "string",
- "graph_config": { },
- "id": "string",
- "is_active": false,
- "is_draft": false,
- "label": "",
- "name": "",
- "organization_id": "string",
- "trigger_config": { },
- "updated_at": "string",
- "version": 1,
- "workflow_id": "string",
- "workspace_id": "string"
}Atomically deactivates the current active version and inserts the next one as active. Validated first. Requires the workflow to HAVE an active version: a paused one, or one that only has a draft, is a 409 telling you to apply first. Fields you omit keep their previous value. API keys need the structure scope.
| workflow_id required | string <uuid> (Workflow Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
Description (string) or Description (null) (Description) | |
Graph Config (object) or Graph Config (null) (Graph Config) What happens next: | |
Label (string) or Label (null) (Label) | |
Name (string) or Name (null) (Name) | |
Trigger Config (object) or Trigger Config (null) (Trigger Config) What fires the automation: |
{- "description": "string",
- "graph_config": { },
- "label": "string",
- "name": "string",
- "trigger_config": { }
}{- "archived_at": "string",
- "created_at": "string",
- "created_by": "string",
- "deactivation_reason": "string",
- "description": "string",
- "graph_config": { },
- "id": "string",
- "is_active": false,
- "is_draft": false,
- "label": "",
- "name": "",
- "organization_id": "string",
- "trigger_config": { },
- "updated_at": "string",
- "version": 1,
- "workflow_id": "string",
- "workspace_id": "string"
}The template catalog (system, public, and the caller's own organization). Read-only here: publishing and promotion are human actions in the app.
Cursor-paginated, newest state included: every apply job the caller can see, optionally narrowed to one workspace and one status. This is how a workspace finds the job that brought its sample rows in, since the job row itself never syncs to the app. API keys need the structure scope.
Workspace Id (string) or Workspace Id (null) (Workspace Id) Only jobs applied to this workspace. | |
Status (string) or Status (null) (Status) Only jobs in this state. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "created_at": "string",
- "error": "string",
- "id": "string",
- "include_rows": true,
- "locked_until": "string",
- "report": { },
- "status": "string",
- "template_id": "string",
- "updated_at": "string",
- "workspace_id": "string"
}
], - "next_cursor": "string"
}Poll this after POST /v1/templates/{id}/apply. status is queued (not started), structure (creating tables, columns and views), rows (loading data in batches), done, failed or cancelled. report counts what was created, skipped and inserted, plus published — how many automations came out published instead of draft — and is only complete once the job is done; error says what stopped a failed one. Returns 404 when the job does not exist or is not visible to the caller.
| job_id required | string <uuid> (Job Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "created_at": "string",
- "error": "string",
- "id": "string",
- "include_rows": true,
- "locked_until": "string",
- "report": { },
- "status": "string",
- "template_id": "string",
- "updated_at": "string",
- "workspace_id": "string"
}Fills the user columns of the rows this job inserted with the caller, and only where they are empty: a row that already has someone keeps them. The structure is not touched, and neither are tables without a user column. Idempotent: a second run fills nothing and reports zero. A job that has not finished is a 409; one applied before the executor started recording what it inserted is a 422 naming ledger_without_row_ids. API keys need the structure scope.
| job_id required | string <uuid> (Job Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "job_id": "string",
- "tables": [ ],
- "total": 0
}Deletes the rows this job inserted, and nothing else: the tables, columns, views and workflows the package created stay exactly as they are, because work of your own may already live in them. Rows added after the apply are untouched too — only the ones the job itself created are named in its ledger. Idempotent: running it a second time removes nothing and reports zero. A job that has not finished is a 409; one applied before the executor started recording what it inserted is a 422 naming ledger_without_row_ids. API keys need the structure scope.
| job_id required | string <uuid> (Job Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "job_id": "string",
- "tables": [ ],
- "total": 0
}Cursor-paginated catalog: platform templates (system), shared ones (public), and the caller's own organization's. The package itself (manifest) is NOT included here, because it can be large; read one template to get it.
Scope (string) or Scope (null) (Scope) Only this scope: organization|workspace|module|feature. | |
Visibility (string) or Visibility (null) (Visibility) Only this visibility: system|org|public. | |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "category": "string",
- "description": "string",
- "icon": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "organization_id": "string",
- "published_at": "string",
- "published_by": "string",
- "scope": "string",
- "semver": "string",
- "source_workspace_id": "string",
- "tags": [ ],
- "visibility": "string"
}
], - "next_cursor": "string"
}The catalog row plus the package itself (manifest). Returns 404 when the template does not exist or is not visible to the caller.
| template_id required | string <uuid> (Template Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "category": "string",
- "description": "string",
- "icon": "string",
- "id": "string",
- "label": "string",
- "manifest": { },
- "name": "string",
- "organization_id": "string",
- "published_at": "string",
- "published_by": "string",
- "scope": "string",
- "semver": "string",
- "source_workspace_id": "string",
- "tags": [ ],
- "visibility": "string"
}Starts a background job that applies the template's package to the target workspace: structure in one transaction, rows in batches. Returns the job id immediately — poll GET /v1/template-jobs/{id} for progress and the final report. Applying the SAME template to the SAME workspace twice creates nothing the second time and says so in the report. A second call while a job is still running is a 409 naming the job that is running. API keys need the structure scope.
| template_id required | string <uuid> (Template Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
| include_rows | boolean (Include Rows) Default: true |
Job Id (string) or Job Id (null) (Job Id) Resume this job instead of starting a new one. Omit it and the server decides: it resumes the last unfinished job for this template and workspace, and starts a fresh one when the last apply finished. | |
object (Resolutions) What to do with each dependency the package names, one entry per ref. | |
object (Rows Modes) What to do with the rows of each table the package carries, one entry per feature ref. | |
| workspace_id required | string <uuid> (Workspace Id) |
{- "include_rows": true,
- "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
- "resolutions": { },
- "rows_modes": {
- "property1": "string",
- "property2": "string"
}, - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}{- "job_id": "string",
- "status": "string"
}For each dependency the package declares, the destination tables that look like it, ranked by confidence (0 to 1) from name/label similarity and the overlap of the columns the package actually uses, each with its column candidates. proposed is what a wizard would pre-select: map above 0.8, import when the package carries a blueprint, decide otherwise. Read-only: it changes nothing. Feed the answer straight into resolutions of apply_template. API keys need the structure scope.
| template_id required | string <uuid> (Template Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
| workspace_id required | string <uuid> (Workspace Id) |
{- "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}{- "suggestions": [ ]
}The organization's features that carry an external_user column — adding that column IS publishing the feature — each with the columns marked externally visible.
A published feature with no visible columns is listed with an empty columns: it is a real state (rows marked, nothing chosen to show yet), not an error. The external_user column itself is never listed.
| organization_id required | string (Organization Id) non-empty The organization whose area is being read. Must be one of the organizations returned by |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "columns": [
- {
- "default_component": "string",
- "id": "string",
- "label": "string",
- "name": "string",
- "type": "string"
}
], - "id": "string",
- "label": "string"
}
]
}Resolves the signed-in identity to its client accounts — one per organization that invited it — and is the call the portal makes first. An identity with no account, or with only revoked ones, is refused with 403 and a body that does not say which of the two it was.
First call activates. An account still invited becomes active here: signing in to the portal IS the acceptance of the invite. Until then it can read no data, and after a revocation it cannot again.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "accounts": [
- {
- "account_id": "string",
- "email": "string",
- "name": "string",
- "organization_id": "string",
- "organization_label": "string",
- "status": "string"
}
], - "user_id": "string"
}Cursor-paginated. Returns ONLY the rows whose external_user column contains the caller's client account, projected to the columns the organization marked externally visible — both imposed server-side, neither expressible by the caller.
A feature without an external_user column answers 404, and so does one whose column was removed a moment ago: the configuration is re-read on every request, so unpublishing takes effect immediately. An account with nothing marked gets an empty page, not an error.
| feature_id required | string <uuid> (Feature Id) A feature listed by |
Cursor (string) or Cursor (null) (Cursor) Opaque cursor taken from | |
| limit | integer (Limit) >= 1 Default: 25 Page size, 1 to 200. Defaults to 25. |
Fields (string) or Fields (null) (Fields) Comma-separated subset of the row | |
| organization_id required | string (Organization Id) non-empty The organization whose area is being read. Must be one of the organizations returned by |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "items": [
- {
- "created_at": "string",
- "data": { },
- "feature_id": "string",
- "id": "string",
- "updated_at": "string"
}
], - "next_cursor": "string"
}Provisions a client account for the organization: reuses the identity when one already exists for the email, otherwise creates it and sends the invite. The account is never duplicated — inviting the same email again returns the same account, and what else happens follows its status: active is returned untouched (the person already has a login), invited sends the mail again, and revoked reactivates the account and mails. The account never becomes a member of the organization. Requires organization administrator.
Which mail goes out depends on the identity: a person who has no login yet gets the invite, a person who already has one gets an access link (a sign-in link — they have no password to set, and the identity provider refuses to invite them at all). Except for no_action, every outcome means a mail left.
outcome reports which of those happened (created, access_link_sent, reactivated, invite_resent, no_action) — the returned account does not show it, since all paths answer 200 with status='invited'. Do not infer the outcome from the account's previous status.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
| email required | string (Email) [ 3 .. 320 ] characters |
Name (string) or Name (null) (Name) | |
| organization_id required | string (Organization Id) non-empty |
{- "email": "string",
- "name": "string",
- "organization_id": "string"
}{- "created_at": "string",
- "email": "string",
- "id": "string",
- "invited_at": "string",
- "name": "string",
- "organization_id": "string",
- "outcome": "created",
- "status": "string",
- "updated_at": "string",
- "user_id": "string"
}Sets the account to revoked — access stops on the caller's next request — and closes the identity's way back in when this was its last external account and it holds no OutDo membership. Idempotent. Requires organization administrator.
| account_id required | string (Account Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "created_at": "string",
- "email": "string",
- "id": "string",
- "invited_at": "string",
- "name": "string",
- "organization_id": "string",
- "status": "string",
- "updated_at": "string",
- "user_id": "string"
}AI control plane: per-organization model configuration, credit balance, usage records, and provider secrets. Not an inference endpoint.
Organization Id (string) or Organization Id (null) (Organization Id) Filter the catalog to the models this org's tier may use. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
[- {
- "allowed_tier_names": [
- "string"
], - "api_type": "string",
- "base_url": "string",
- "cache_write_price_eur": 0,
- "cached_input_price_eur": 0,
- "capability": "string",
- "credit_multiplier": 0,
- "input_price_eur": 0,
- "is_active": true,
- "key": "string",
- "label": "string",
- "mask_sensitive": true,
- "model": "string",
- "output_price_eur": 0,
- "provider_secret": "string",
- "sort_order": 0,
- "unit_price_eur": 0
}
]| organization_id required | string <uuid> (Organization Id) Organization id. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "allowance_remaining": 0,
- "organization_id": "string",
- "period_start": "string",
- "tier_name": "string",
- "topup_balance": 0
}| organization_id required | string <uuid> (Organization Id) |
| provider required | string (Provider) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
| secret required | string (Secret) non-empty |
{- "secret": "string"
}| organization_id required | string <uuid> (Organization Id) |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
[- {
- "is_set": true,
- "provider": "string"
}
]X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "defaults": {
- "property1": "string",
- "property2": "string"
}
}| organization_id required | string <uuid> (Organization Id) Organization id. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "mode_models": {
- "property1": "string",
- "property2": "string"
}, - "organization_id": "string"
}X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
required | object (Mode Models) |
| organization_id required | string <uuid> (Organization Id) |
{- "mode_models": {
- "property1": "string",
- "property2": "string"
}, - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6"
}| organization_id required | string <uuid> (Organization Id) Organization id. |
Since (string) or Since (null) (Since) ISO-8601 timestamp; only events after this point are included. |
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "organization_id": "string",
- "rows": [
- {
- "event_count": 0,
- "mode": "string",
- "model_key": "string",
- "total_quantity": 0,
- "unit": "string"
}
]
}Version and uptime of the outdo_api_data service. Superadmin session only.
X-Outdo-Service-Key (string) or X-Outdo-Service-Key (null) (X-Outdo-Service-Key) |
{- "service": "outdo_api_data",
- "started_at": "string",
- "uptime_s": 0,
- "version": "string"
}