{"openapi": "3.1.0", "info": {"title": "External API", "version": "1.0.0", "description": ""}, "paths": {"/external/v1/user/me": {"get": {"operationId": "external_api_routers_user_me", "summary": "Get user info", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserOut"}}}}}, "tags": ["User"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/enrichments": {"get": {"operationId": "external_api_routers_enrichment_get_enrichments", "summary": "Get available enrichments", "parameters": [{"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "page", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Page"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "authorized_only", "schema": {"default": true, "title": "Authorized Only", "type": "boolean"}, "required": false}, {"in": "query", "name": "category", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Category"}, "required": false}], "responses": {"200": {"description": "OK"}}, "tags": ["Enrichment"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/enrichments/{enrichment_id}": {"get": {"operationId": "external_api_routers_enrichment_get_enrichment", "summary": "Get a specific enrichment", "parameters": [{"in": "path", "name": "enrichment_id", "schema": {"title": "Enrichment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnrichmentParams"}}}}}, "tags": ["Enrichment"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/enrichments/{enrichment_id}/run": {"post": {"operationId": "external_api_routers_enrichment_run_enrichment", "summary": "Run an enrichment", "parameters": [{"in": "path", "name": "enrichment_id", "schema": {"title": "Enrichment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "tags": ["Enrichment"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunEnrichmentIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/enrichments/{enrichment_id}/bulk-run": {"post": {"operationId": "external_api_routers_enrichment_bulk_run_enrichment", "summary": "Bulk run an enrichment", "parameters": [{"in": "path", "name": "enrichment_id", "schema": {"title": "Enrichment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "tags": ["Enrichment"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkRunEnrichmentIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/enrichments/{enrichment_id}/params/{param_slug}/choices": {"get": {"operationId": "external_api_routers_enrichment_get_param_choices", "summary": "Get choices for a parameter", "parameters": [{"in": "path", "name": "enrichment_id", "schema": {"title": "Enrichment Id", "type": "integer"}, "required": true}, {"in": "path", "name": "param_slug", "schema": {"title": "Param Slug", "type": "string"}, "required": true}, {"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 100, "title": "Limit", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChoicesResponse"}}}}}, "tags": ["Enrichment"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/waterfalls": {"get": {"operationId": "external_api_routers_waterfall_list_waterfalls", "summary": "Get available waterfalls", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WaterfallOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Waterfall"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/waterfalls/{waterfall_identifier}": {"get": {"operationId": "external_api_routers_waterfall_get_waterfall", "summary": "Get a specific waterfall", "parameters": [{"in": "path", "name": "waterfall_identifier", "schema": {"title": "Waterfall Identifier", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WaterfallOut"}}}}}, "tags": ["Waterfall"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/waterfalls/{waterfall_identifier}/run": {"post": {"operationId": "external_api_routers_waterfall_run_waterfall", "summary": "Run a waterfall", "parameters": [{"in": "path", "name": "waterfall_identifier", "schema": {"title": "Waterfall Identifier", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "tags": ["Waterfall"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunWaterfallIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/waterfalls/{waterfall_identifier}/bulk-run": {"post": {"operationId": "external_api_routers_waterfall_bulk_run_waterfall", "summary": "Bulk run a waterfall", "parameters": [{"in": "path", "name": "waterfall_identifier", "schema": {"title": "Waterfall Identifier", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "tags": ["Waterfall"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkRunWaterfallIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/create": {"post": {"operationId": "external_api_routers_table_create_table", "summary": "Create a table", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TableOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/CreateTableIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table": {"get": {"operationId": "external_api_routers_table_list_tables", "summary": "Get all workspace tables", "parameters": [{"in": "query", "name": "order_by", "schema": {"default": "-created_at", "title": "Order By", "type": "string"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TableOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/duplicate": {"post": {"operationId": "external_api_routers_table_duplicate_table_endpoint", "summary": "Duplicate a table", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TableOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DuplicateTableIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}": {"patch": {"operationId": "external_api_routers_table_rename_table", "summary": "Rename a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TableOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RenameTableIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "delete": {"operationId": "external_api_routers_table_delete_table", "summary": "Delete a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Removes this table from its workbook. The table goes to Trash for 30 days and can be restored into its workbook. If it is the only table, the whole workbook goes to Trash instead.", "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/move": {"post": {"operationId": "external_api_routers_table_move_table_endpoint", "summary": "Move a table into another workbook", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/MoveTableToWorkbookIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/clear": {"post": {"operationId": "external_api_routers_table_clear_table", "summary": "Clear all rows from a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/export": {"post": {"operationId": "external_api_routers_table_export_table", "summary": "Start a table export", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExportTableOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/ExportTableIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"UserTokenAuth": []}]}, "get": {"operationId": "external_api_routers_table_get_table_export", "summary": "Get the latest table export status", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExportTableOut"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/rows/dedupe": {"post": {"operationId": "external_api_routers_table_dedupe_rows", "summary": "Delete duplicate rows", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DedupeRowsOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/DedupeRowsIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/rows": {"get": {"operationId": "external_api_routers_table_list_rows_endpoint", "summary": "Get table rows", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "per_page", "schema": {"default": 100, "title": "Per Page", "type": "integer"}, "required": false}, {"in": "query", "name": "filter", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Filter"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ListRowsOut"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}, "post": {"operationId": "external_api_routers_table_batch_insert_rows_endpoint", "summary": "Batch insert rows", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BatchInsertOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BatchInsertIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "patch": {"operationId": "external_api_routers_table_batch_update_rows_endpoint", "summary": "Batch update rows", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BatchUpdateOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BatchUpdateIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/rows/delete": {"post": {"operationId": "external_api_routers_table_delete_rows", "summary": "Delete rows from a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeleteRowsIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/rows/upsert": {"post": {"operationId": "external_api_routers_table_upsert_rows_endpoint", "summary": "Upsert rows", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpsertOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpsertIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/columns": {"get": {"operationId": "external_api_routers_table_list_columns", "summary": "Get table columns", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ColumnOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}, "post": {"operationId": "external_api_routers_table_create_column", "summary": "Add a column to a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateColumnOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateColumnIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/columns/{column_id}": {"patch": {"operationId": "external_api_routers_table_rename_column", "summary": "Rename a column", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "column_id", "schema": {"format": "uuid", "title": "Column Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateColumnOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RenameColumnIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "delete": {"operationId": "external_api_routers_table_delete_column", "summary": "Delete a column", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "column_id", "schema": {"format": "uuid", "title": "Column Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/columns/{column_id}/reorder": {"post": {"operationId": "external_api_routers_table_reorder_column", "summary": "Reorder a column", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "column_id", "schema": {"format": "uuid", "title": "Column Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReorderColumnIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/add-enrichment": {"post": {"operationId": "external_api_routers_table_add_enrichment", "summary": "Add enrichment to table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddEnrichmentOut"}}}}}, "description": "Attach an enrichment to a table and map its parameters to columns.\n\n``mapping`` maps each enrichment parameter name to a value source:\n\n* ``{\"type\": \"mapping\", \"value\": \"<column_name>\"}`` \u2014 read the value from a\n  table column, per row. ``value`` is the column name, its\n  ``additional_intenal_name`` or its UUID.\n* ``{\"type\": \"simple\", \"value\": \"<constant>\"}`` \u2014 a static value for every\n  row. ``value`` may embed ``{column_name}`` placeholders (replaced with the\n  column value per row) and ``{?column_name}`` for optional references.\n\nExample body::\n\n    {\"enrichment\": 7, \"mapping\": {\"id\": {\"type\": \"mapping\", \"value\": \"hn_id\"}}}", "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddEnrichmentIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/enrichments": {"get": {"operationId": "external_api_routers_table_list_enrichments", "summary": "Get table enrichments", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TableEnrichmentOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/run-enrichment/{enrichment_id}": {"post": {"operationId": "external_api_routers_table_run_enrichment", "summary": "Run enrichment, waterfall, or function on a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "enrichment_id", "schema": {"title": "Enrichment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunEnrichmentOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/RunEnrichmentIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/enrichments/{enrichment_id}": {"delete": {"operationId": "external_api_routers_table_delete_enrichment", "summary": "Remove an enrichment, waterfall, or function from a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "enrichment_id", "schema": {"title": "Enrichment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}, "patch": {"operationId": "external_api_routers_table_update_enrichment", "summary": "Update an attached enrichment mapping", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "enrichment_id", "schema": {"title": "Enrichment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddEnrichmentOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateEnrichmentIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/add-waterfall": {"post": {"operationId": "external_api_routers_table_add_waterfall", "summary": "Add waterfall to table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddWaterfallOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddWaterfallIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/waterfalls": {"get": {"operationId": "external_api_routers_table_list_waterfalls", "summary": "Get table waterfalls", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/InstalledWaterfallOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/add-exporter": {"post": {"operationId": "external_api_routers_table_add_exporter", "summary": "Add exporter to table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddExporterOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddExporterIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/exporters": {"get": {"operationId": "external_api_routers_table_list_exporters", "summary": "Get table exporters", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/InstalledExporterOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/add-flow": {"post": {"operationId": "external_api_routers_table_add_flow", "summary": "Add a flow to a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddFlowOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddFlowIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/flows": {"get": {"operationId": "external_api_routers_table_list_table_flows", "summary": "List flows attached to a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/InstalledFlowOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources": {"get": {"operationId": "external_api_routers_table_list_data_sources", "summary": "List a table's data sources", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DataSourceOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}, "post": {"operationId": "external_api_routers_table_attach_data_source", "summary": "Attach a data source to a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DataSourceOut"}}}}}, "description": "Attach a CSV, webhook, or CRM/API data source to a table.\n\n* ``crm`` requires ``dataset_id`` and optionally a ``schedule`` for recurring syncs.\n* ``webhook`` creates a webhook handler (+ raw JSON column) when ``webhook_id`` is omitted.\n* ``csv`` records a CSV source; rows are added via the row endpoints.", "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachSourceIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources/csv": {"post": {"operationId": "external_api_routers_table_append_csv_to_table", "summary": "Append CSV rows to a table", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CsvAppendIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources/{source_id}": {"put": {"operationId": "external_api_routers_table_update_data_source_schedule", "summary": "Update a data source's sync schedule", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "source_id", "schema": {"title": "Source Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DataSourceOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateScheduleIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "delete": {"operationId": "external_api_routers_table_disconnect_data_source", "summary": "Disconnect a data source", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "source_id", "schema": {"title": "Source Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources/{source_id}/pause": {"post": {"operationId": "external_api_routers_table_pause_data_source", "summary": "Pause a data source", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "source_id", "schema": {"title": "Source Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DataSourceOut"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources/{source_id}/resume": {"post": {"operationId": "external_api_routers_table_resume_data_source", "summary": "Resume a paused data source", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "source_id", "schema": {"title": "Source Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DataSourceOut"}}}}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources/{source_id}/sync-now": {"post": {"operationId": "external_api_routers_table_sync_data_source_now", "summary": "Trigger an immediate sync for a data source", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "source_id", "schema": {"title": "Source Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/SyncNowIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources/{source_id}/run": {"post": {"operationId": "external_api_routers_table_run_data_source", "summary": "Run a one-off pull from a CRM data source", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "source_id", "schema": {"title": "Source Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunSourceIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources/{source_id}/webhook-fields": {"get": {"operationId": "external_api_routers_table_get_webhook_fields", "summary": "JSONPath field tree of a webhook source's last test payload", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "source_id", "schema": {"title": "Source Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Table"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/table/{table_uuid}/sources/{source_id}/webhook-mapping": {"post": {"operationId": "external_api_routers_table_set_webhook_mapping_endpoint", "summary": "Map webhook JSONPath fields to table columns", "parameters": [{"in": "path", "name": "table_uuid", "schema": {"format": "uuid", "title": "Table Uuid", "type": "string"}, "required": true}, {"in": "path", "name": "source_id", "schema": {"title": "Source Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DataSourceOut"}}}}}, "tags": ["Table"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookMappingIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/tasks/{task_id}": {"get": {"operationId": "external_api_routers_task_get_task", "summary": "Get task data or status", "parameters": [{"in": "path", "name": "task_id", "schema": {"title": "Task Id", "type": "string"}, "required": true}, {"in": "query", "name": "include_partial", "schema": {"default": false, "title": "Include Partial", "type": "boolean"}, "required": false}, {"in": "query", "name": "include_trace", "schema": {"default": false, "title": "Include Trace", "type": "boolean"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskDetailOut"}}}}, "410": {"description": "Gone", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskGoneOut"}}}}}, "description": "``include_partial``: while a bulk run is still going, return the rows that have\nalready finished. Off by default \u2014 it turns every poll into a full read of the\nresult hash, which a client polling every few minutes pays for and rarely wants.\n\n``include_trace``: for a flow task, also return what each step of the run did \u2014\nwhich node ran, what it produced, why it stopped, what it cost. Off by default, so\nthe response is unchanged for callers that don't ask. Use it when a run comes back\n``completed`` with nothing in ``data``: the trace says whether every step missed,\na condition halted the run, or a provider errored. Other task types return no\n``trace``. For a bulk flow task ``trace`` is a list aligned to the inputs, like\n``data`` \u2014 a list or nothing, never a single run.\n\nResults expire after 24 hours and the poll then answers 410. The record of the\nrun is kept, though, so with ``include_trace`` that 410 still carries the trace.", "tags": ["Task"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/tasks/{task_id}/cancel": {"post": {"operationId": "external_api_routers_task_cancel_task", "summary": "Cancel a running task", "parameters": [{"in": "path", "name": "task_id", "schema": {"title": "Task Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskDetailOut"}}}}}, "description": "Stop a running task and refund what its unfinished requests had reserved.\n\nRows that already finished keep their results: poll the task afterwards to collect them.", "tags": ["Task"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/folders": {"post": {"operationId": "external_api_routers_folder_create_folder", "summary": "Create a folder", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FolderOut"}}}}}, "tags": ["Folder"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateFolderIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "get": {"operationId": "external_api_routers_folder_list_folders", "summary": "List all folders", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FolderOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Folder"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/folders/move-table": {"post": {"operationId": "external_api_routers_folder_move_table_to_folder", "summary": "Move a table's workbook into or out of a folder", "parameters": [], "responses": {"200": {"description": "OK"}}, "tags": ["Folder"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/MoveTableIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/folders/{folder_id}": {"patch": {"operationId": "external_api_routers_folder_rename_folder", "summary": "Rename a folder", "parameters": [{"in": "path", "name": "folder_id", "schema": {"title": "Folder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FolderOut"}}}}}, "tags": ["Folder"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RenameFolderIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "delete": {"operationId": "external_api_routers_folder_delete_folder", "summary": "Delete a folder", "parameters": [{"in": "path", "name": "folder_id", "schema": {"title": "Folder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Folder"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/exporters": {"get": {"operationId": "external_api_routers_exporter_get_exporters", "summary": "Get available exporters", "parameters": [{"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "page", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Page"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK"}}, "tags": ["Exporter"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/exporters/{exporter_id}": {"get": {"operationId": "external_api_routers_exporter_get_exporter", "summary": "Get a specific exporter", "parameters": [{"in": "path", "name": "exporter_id", "schema": {"title": "Exporter Id", "type": "integer"}, "required": true}, {"in": "query", "name": "authorization", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Authorization"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExporterParams"}}}}}, "tags": ["Exporter"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/connectors": {"get": {"operationId": "external_api_routers_connector_list_connectors", "summary": "List custom API connectors", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ConnectorOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Connector"], "security": [{"UserTokenAuth": []}]}, "post": {"operationId": "external_api_routers_connector_create_connector", "summary": "Create a custom API connector", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConnectorOut"}}}}}, "tags": ["Connector"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConnectorCreate"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/connectors/{connector_id}": {"get": {"operationId": "external_api_routers_connector_get_connector", "summary": "Get a connector", "parameters": [{"in": "path", "name": "connector_id", "schema": {"title": "Connector Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConnectorOut"}}}}}, "tags": ["Connector"], "security": [{"UserTokenAuth": []}]}, "put": {"operationId": "external_api_routers_connector_update_connector", "summary": "Update a connector", "parameters": [{"in": "path", "name": "connector_id", "schema": {"title": "Connector Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConnectorOut"}}}}}, "tags": ["Connector"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConnectorCreate"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "delete": {"operationId": "external_api_routers_connector_delete_connector", "summary": "Delete a connector", "parameters": [{"in": "path", "name": "connector_id", "schema": {"title": "Connector Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Connector"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows": {"get": {"operationId": "external_api_routers_flow_list_flows", "summary": "List workspace flows", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FlowOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Flows"], "security": [{"UserTokenAuth": []}]}, "post": {"operationId": "external_api_routers_flow_create_flow", "summary": "Create a flow", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowDetailOut"}}}}}, "description": "Create a workspace flow from a config.\n\nThe config is validated exactly as the editor validates it: an invalid graph\nis rejected here rather than failing later on every run.", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowCreateIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/validate-config": {"post": {"operationId": "external_api_routers_flow_validate_flow_config", "summary": "Check a flow config without saving", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowValidateOut"}}}}}, "description": "Check a (possibly unsaved) ``config`` without persisting anything.\n\nRuns the same checks a save runs, including the normalisation a save\napplies first. Always 200: an invalid config is a valid answer to\n\"would this be accepted?\".", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowConfigIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/config-schema": {"get": {"operationId": "external_api_routers_flow_get_flow_config_schema", "summary": "JSON Schema of a flow config", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "The JSON Schema of the ``config`` every flow endpoint takes and returns.\n\nGenerated from the model the server validates against, so it is exact for\nshape and types. Cross-node rules (refs resolve, no cycles, enrichment\nparams exist and required ones are bound) are not expressible in JSON\nSchema \u2014 ``POST /flows/validate-config`` checks those.", "tags": ["Flows"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/cost-estimate": {"post": {"operationId": "external_api_routers_flow_estimate_flow_cost", "summary": "Estimate the credit cost of one flow run", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowCostEstimateOut"}}}}}, "description": "Credit-cost range of one run of the given (possibly unsaved) config.\n\n``min``/``max`` because waterfalls stop at the first success and\nconditions skip branches. Call this before ``POST /flows/{id}/run``.", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowConfigIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/{flow_id}": {"get": {"operationId": "external_api_routers_flow_get_flow", "summary": "Get a workspace flow", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowDetailOut"}}}}}, "tags": ["Flows"], "security": [{"UserTokenAuth": []}]}, "put": {"operationId": "external_api_routers_flow_replace_flow", "summary": "Replace a flow", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowDetailOut"}}}}}, "description": "Replace the whole flow.\n\nTo change one node without resending the graph \u2014 and without risking the\nrest of it \u2014 use ``PATCH /flows/{flow_id}/config`` instead.", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowReplaceIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "patch": {"operationId": "external_api_routers_flow_update_flow", "summary": "Update flow fields", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowDetailOut"}}}}}, "description": "Update only the fields you send. ``internal_version`` is required\nalongside ``config``; a rename needs neither a config nor a version.", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowUpdateIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "delete": {"operationId": "external_api_routers_flow_remove_flow", "summary": "Delete a flow", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Delete a flow. Refused while table columns still run it \u2014 the column\nwould survive with nothing behind it and fail on every run.", "tags": ["Flows"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/{flow_id}/config": {"patch": {"operationId": "external_api_routers_flow_patch_flow_config", "summary": "Apply targeted edits to a flow config", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowConfigOpsOut"}}}}}, "description": "Change part of a flow without resending the whole graph.\n\nReplacing the entire config to fix one word means every other node rides\nalong with the request, so a small fix carries the risk of a large one. The\nbatch is atomic \u2014 one bad op writes nothing \u2014 and the result is validated by\nthe same rules a full replace runs.", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowConfigOpsIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/{flow_id}/versions": {"get": {"operationId": "external_api_routers_flow_list_flow_versions", "summary": "List a flow's edit history", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FlowVersionOut"}, "title": "Response", "type": "array"}}}}}, "description": "Every save of this flow, newest first: what changed, who changed it and\nfrom which surface.", "tags": ["Flows"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/{flow_id}/versions/{number}": {"get": {"operationId": "external_api_routers_flow_get_flow_version", "summary": "Get one version, with its config", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}, {"in": "path", "name": "number", "schema": {"title": "Number", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowVersionDetailOut"}}}}}, "tags": ["Flows"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/{flow_id}/versions/{number}/restore": {"post": {"operationId": "external_api_routers_flow_restore_version", "summary": "Roll a flow back to an earlier version", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}, {"in": "path", "name": "number", "schema": {"title": "Number", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RestoreFlowVersionOut"}}}}}, "description": "Make an older version current.\n\nNothing is overwritten: the old config is written as a new version, so the\nrollback is itself revertible. A version that no longer validates \u2014 its\nenrichment was deleted, its dataset changed \u2014 is refused with the reasons.", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/RestoreFlowVersionIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/{flow_id}/run": {"post": {"operationId": "external_api_routers_flow_run_flow", "summary": "Run a flow with parameters (no table required)", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "description": "Start a flow execution and return a ``task_id``.\n\nPoll ``GET /tasks/{task_id}`` to check status and retrieve outputs.\nInputs are passed as ``{input_id: value}`` \u2014 see\n``GET /flows/{flow_id}`` for the list of declared inputs.\n\nA run that produced nothing still finishes as ``completed`` with an empty\n``data``: poll with ``?include_trace=true`` to get the per-step account of\nwhat each node did and why the run ended where it did.", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunFlowIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/flows/{flow_id}/bulk-run": {"post": {"operationId": "external_api_routers_flow_bulk_run_flow", "summary": "Bulk run a flow (no table required)", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "description": "Start a flow over many input sets and return one ``task_id``.\n\nPoll ``GET /tasks/{task_id}``. Results are aligned to ``inputs``: one\nelement per input, in the same order, with ``null`` for misses \u2014 same\ncontract as ``POST /enrichments/{id}/bulk-run``.\n\nPoll with ``?include_trace=true`` to also get ``trace`` in the same alignment:\n``trace[i]`` is what the run for ``inputs[i]`` did.", "tags": ["Flows"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkRunFlowIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/data-sources": {"get": {"operationId": "external_api_routers_data_source_catalog_list_catalogue_data_sources", "summary": "Search catalogue data sources", "parameters": [{"in": "query", "name": "query", "schema": {"default": "", "title": "Query", "type": "string"}, "required": false}, {"in": "query", "name": "category", "schema": {"default": "", "title": "Category", "type": "string"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 10, "title": "Limit", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DataSourceCatalogItem"}, "title": "Response", "type": "array"}}}}}, "tags": ["Data sources"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/data-sources/{dataset_id}": {"get": {"operationId": "external_api_routers_data_source_catalog_get_catalogue_data_source", "summary": "Get a catalogue data source's params and auth", "parameters": [{"in": "path", "name": "dataset_id", "schema": {"title": "Dataset Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DataSourceCatalogDetails"}}}}}, "tags": ["Data sources"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/data-sources/{dataset_id}/params/{param_slug}/choices": {"get": {"operationId": "external_api_routers_data_source_catalog_get_data_source_param_choices", "summary": "Get choices for a data-source parameter", "parameters": [{"in": "path", "name": "dataset_id", "schema": {"title": "Dataset Id", "type": "integer"}, "required": true}, {"in": "path", "name": "param_slug", "schema": {"title": "Param Slug", "type": "string"}, "required": true}, {"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 100, "title": "Limit", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChoicesResponse"}}}}}, "tags": ["Data sources"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/workbooks": {"get": {"operationId": "external_api_routers_workbook_list_workbooks_endpoint", "summary": "List workbooks", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkbookOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Workbook"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/workbooks/merge": {"post": {"operationId": "external_api_routers_workbook_merge_workbooks_endpoint", "summary": "Merge workbooks into a target", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkbookOut"}}}}}, "tags": ["Workbook"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/MergeWorkbooksIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/workbooks/{workbook_id}": {"get": {"operationId": "external_api_routers_workbook_get_workbook_endpoint", "summary": "Get a workbook", "parameters": [{"in": "path", "name": "workbook_id", "schema": {"title": "Workbook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkbookOut"}}}}}, "tags": ["Workbook"], "security": [{"UserTokenAuth": []}]}, "patch": {"operationId": "external_api_routers_workbook_rename_workbook_endpoint", "summary": "Rename a workbook", "parameters": [{"in": "path", "name": "workbook_id", "schema": {"title": "Workbook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkbookOut"}}}}}, "tags": ["Workbook"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RenameWorkbookIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "delete": {"operationId": "external_api_routers_workbook_delete_workbook_endpoint", "summary": "Delete a workbook (trash)", "parameters": [{"in": "path", "name": "workbook_id", "schema": {"title": "Workbook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["Workbook"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/workbooks/{workbook_id}/duplicate": {"post": {"operationId": "external_api_routers_workbook_duplicate_workbook_endpoint", "summary": "Duplicate a workbook", "parameters": [{"in": "path", "name": "workbook_id", "schema": {"title": "Workbook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkbookOut"}}}}}, "tags": ["Workbook"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/workbooks/{workbook_id}/tables": {"post": {"operationId": "external_api_routers_workbook_add_workbook_table", "summary": "Add an empty sheet to a workbook", "parameters": [{"in": "path", "name": "workbook_id", "schema": {"title": "Workbook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkbookTableOut"}}}}}, "tags": ["Workbook"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/AddWorkbookTableIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/workbooks/{workbook_id}/tables/reorder": {"post": {"operationId": "external_api_routers_workbook_reorder_workbook_tables", "summary": "Reorder sheets in a workbook", "parameters": [{"in": "path", "name": "workbook_id", "schema": {"title": "Workbook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkbookOut"}}}}}, "tags": ["Workbook"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReorderWorkbookTablesIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/trash": {"get": {"operationId": "external_api_routers_workbook_list_trash", "summary": "List trash", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TrashItemOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Trash"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/trash/restore": {"post": {"operationId": "external_api_routers_workbook_restore_trash", "summary": "Restore from trash", "parameters": [], "responses": {"200": {"description": "OK"}}, "tags": ["Trash"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TrashActionIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/trash/delete-forever": {"post": {"operationId": "external_api_routers_workbook_purge_trash", "summary": "Permanently delete from trash", "parameters": [], "responses": {"200": {"description": "OK"}}, "tags": ["Trash"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TrashActionIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions": {"get": {"operationId": "external_api_routers_flow_list_flows", "summary": "List workspace flows", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FlowOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["Flows (deprecated, use /flows)"], "security": [{"UserTokenAuth": []}]}, "post": {"operationId": "external_api_routers_flow_create_flow", "summary": "Create a flow", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowDetailOut"}}}}}, "description": "Create a workspace flow from a config.\n\nThe config is validated exactly as the editor validates it: an invalid graph\nis rejected here rather than failing later on every run.", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowCreateIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/validate-config": {"post": {"operationId": "external_api_routers_flow_validate_flow_config", "summary": "Check a flow config without saving", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowValidateOut"}}}}}, "description": "Check a (possibly unsaved) ``config`` without persisting anything.\n\nRuns the same checks a save runs, including the normalisation a save\napplies first. Always 200: an invalid config is a valid answer to\n\"would this be accepted?\".", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowConfigIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/config-schema": {"get": {"operationId": "external_api_routers_flow_get_flow_config_schema", "summary": "JSON Schema of a flow config", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "The JSON Schema of the ``config`` every flow endpoint takes and returns.\n\nGenerated from the model the server validates against, so it is exact for\nshape and types. Cross-node rules (refs resolve, no cycles, enrichment\nparams exist and required ones are bound) are not expressible in JSON\nSchema \u2014 ``POST /flows/validate-config`` checks those.", "tags": ["Flows (deprecated, use /flows)"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/cost-estimate": {"post": {"operationId": "external_api_routers_flow_estimate_flow_cost", "summary": "Estimate the credit cost of one flow run", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowCostEstimateOut"}}}}}, "description": "Credit-cost range of one run of the given (possibly unsaved) config.\n\n``min``/``max`` because waterfalls stop at the first success and\nconditions skip branches. Call this before ``POST /flows/{id}/run``.", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowConfigIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/{flow_id}": {"get": {"operationId": "external_api_routers_flow_get_flow", "summary": "Get a workspace flow", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowDetailOut"}}}}}, "tags": ["Flows (deprecated, use /flows)"], "security": [{"UserTokenAuth": []}]}, "put": {"operationId": "external_api_routers_flow_replace_flow", "summary": "Replace a flow", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowDetailOut"}}}}}, "description": "Replace the whole flow.\n\nTo change one node without resending the graph \u2014 and without risking the\nrest of it \u2014 use ``PATCH /flows/{flow_id}/config`` instead.", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowReplaceIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "patch": {"operationId": "external_api_routers_flow_update_flow", "summary": "Update flow fields", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowDetailOut"}}}}}, "description": "Update only the fields you send. ``internal_version`` is required\nalongside ``config``; a rename needs neither a config nor a version.", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowUpdateIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}, "delete": {"operationId": "external_api_routers_flow_remove_flow", "summary": "Delete a flow", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Delete a flow. Refused while table columns still run it \u2014 the column\nwould survive with nothing behind it and fail on every run.", "tags": ["Flows (deprecated, use /flows)"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/{flow_id}/config": {"patch": {"operationId": "external_api_routers_flow_patch_flow_config", "summary": "Apply targeted edits to a flow config", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowConfigOpsOut"}}}}}, "description": "Change part of a flow without resending the whole graph.\n\nReplacing the entire config to fix one word means every other node rides\nalong with the request, so a small fix carries the risk of a large one. The\nbatch is atomic \u2014 one bad op writes nothing \u2014 and the result is validated by\nthe same rules a full replace runs.", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowConfigOpsIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/{flow_id}/versions": {"get": {"operationId": "external_api_routers_flow_list_flow_versions", "summary": "List a flow's edit history", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FlowVersionOut"}, "title": "Response", "type": "array"}}}}}, "description": "Every save of this flow, newest first: what changed, who changed it and\nfrom which surface.", "tags": ["Flows (deprecated, use /flows)"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/{flow_id}/versions/{number}": {"get": {"operationId": "external_api_routers_flow_get_flow_version", "summary": "Get one version, with its config", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}, {"in": "path", "name": "number", "schema": {"title": "Number", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FlowVersionDetailOut"}}}}}, "tags": ["Flows (deprecated, use /flows)"], "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/{flow_id}/versions/{number}/restore": {"post": {"operationId": "external_api_routers_flow_restore_version", "summary": "Roll a flow back to an earlier version", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}, {"in": "path", "name": "number", "schema": {"title": "Number", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RestoreFlowVersionOut"}}}}}, "description": "Make an older version current.\n\nNothing is overwritten: the old config is written as a new version, so the\nrollback is itself revertible. A version that no longer validates \u2014 its\nenrichment was deleted, its dataset changed \u2014 is refused with the reasons.", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/RestoreFlowVersionIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/{flow_id}/run": {"post": {"operationId": "external_api_routers_flow_run_flow", "summary": "Run a flow with parameters (no table required)", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "description": "Start a flow execution and return a ``task_id``.\n\nPoll ``GET /tasks/{task_id}`` to check status and retrieve outputs.\nInputs are passed as ``{input_id: value}`` \u2014 see\n``GET /flows/{flow_id}`` for the list of declared inputs.\n\nA run that produced nothing still finishes as ``completed`` with an empty\n``data``: poll with ``?include_trace=true`` to get the per-step account of\nwhat each node did and why the run ended where it did.", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunFlowIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}, "/external/v1/functions/{flow_id}/bulk-run": {"post": {"operationId": "external_api_routers_flow_bulk_run_flow", "summary": "Bulk run a flow (no table required)", "parameters": [{"in": "path", "name": "flow_id", "schema": {"title": "Flow Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskOut"}}}}}, "description": "Start a flow over many input sets and return one ``task_id``.\n\nPoll ``GET /tasks/{task_id}``. Results are aligned to ``inputs``: one\nelement per input, in the same order, with ``null`` for misses \u2014 same\ncontract as ``POST /enrichments/{id}/bulk-run``.\n\nPoll with ``?include_trace=true`` to also get ``trace`` in the same alignment:\n``trace[i]`` is what the run for ``inputs[i]`` did.", "tags": ["Flows (deprecated, use /flows)"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkRunFlowIn"}}}, "required": true}, "security": [{"UserTokenAuth": []}]}}}, "components": {"schemas": {"UserOut": {"properties": {"first_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "First Name"}, "email": {"title": "Email", "type": "string"}, "balance": {"title": "Balance", "type": "number"}, "plan": {"title": "Plan", "type": "string"}, "workspace": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workspace"}}, "required": ["first_name", "email", "balance", "plan"], "title": "UserOut", "type": "object"}, "CategoryInfo": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "CategoryInfo", "type": "object"}, "ChoiceItem": {"properties": {"id": {"title": "Id", "type": "string"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "ChoiceItem", "type": "object"}, "Choices": {"properties": {"mode": {"title": "Mode", "type": "string"}, "items": {"anyOf": [{"items": {"$ref": "#/components/schemas/ChoiceItem"}, "type": "array"}, {"type": "null"}], "title": "Items"}, "endpoint": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Endpoint"}}, "required": ["mode"], "title": "Choices", "type": "object"}, "EnrichmentParam": {"properties": {"name": {"title": "Name", "type": "string"}, "slug": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Id a flow node binds this param under (`inputs[].id`). `name` may be an alias.", "title": "Slug"}, "is_required": {"title": "Is Required", "type": "boolean"}, "type_field": {"title": "Type Field", "type": "string"}, "description": {"title": "Description", "type": "string"}, "choices": {"anyOf": [{"$ref": "#/components/schemas/Choices"}, {"type": "null"}]}}, "required": ["name", "is_required", "type_field", "description"], "title": "EnrichmentParam", "type": "object"}, "EnrichmentParams": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "data_source": {"title": "Data Source", "type": "string"}, "price": {"title": "Price", "type": "number"}, "pricing": {"$ref": "#/components/schemas/PricingInfo"}, "auth_method": {"title": "Auth Method", "type": "string"}, "category": {"default": [], "items": {"$ref": "#/components/schemas/CategoryInfo"}, "title": "Category", "type": "array"}, "params": {"items": {"$ref": "#/components/schemas/EnrichmentParam"}, "title": "Params", "type": "array"}, "response_fields": {"items": {"$ref": "#/components/schemas/EnrichmentResponseField"}, "title": "Response Fields", "type": "array"}, "pagination": {"anyOf": [{"$ref": "#/components/schemas/PaginationInfo"}, {"type": "null"}]}}, "required": ["id", "name", "description", "data_source", "price", "pricing", "auth_method", "params", "response_fields"], "title": "EnrichmentParams", "type": "object"}, "EnrichmentResponseField": {"properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Use as `response_field_id` of a flow node output.", "title": "Id"}, "name": {"title": "Name", "type": "string"}, "display_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Display Name"}, "type_field": {"title": "Type Field", "type": "string"}}, "required": ["name", "type_field"], "title": "EnrichmentResponseField", "type": "object"}, "PaginationInfo": {"properties": {"supported": {"title": "Supported", "type": "boolean"}, "per_page": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Per Page"}}, "required": ["supported"], "title": "PaginationInfo", "type": "object"}, "PricingInfo": {"properties": {"type": {"description": "\"fixed\" or \"per_parameter\"", "title": "Type", "type": "string"}, "parameter": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Parameter"}}, "required": ["type"], "title": "PricingInfo", "type": "object"}, "TaskOut": {"properties": {"task_id": {"title": "Task Id", "type": "string"}, "status": {"title": "Status", "type": "string"}}, "required": ["task_id", "status"], "title": "TaskOut", "type": "object"}, "PaginationOptions": {"properties": {"pages": {"maximum": 100, "minimum": 1, "title": "Pages", "type": "integer"}}, "required": ["pages"], "title": "PaginationOptions", "type": "object"}, "RunEnrichmentIn": {"properties": {"run_strategy": {"default": "run_all", "enum": ["run_all", "run_empty", "run_errors"], "title": "Run Strategy", "type": "string"}, "row_ids": {"anyOf": [{"items": {"format": "uuid", "type": "string"}, "type": "array"}, {"type": "null"}], "title": "Row Ids"}}, "title": "RunEnrichmentIn", "type": "object"}, "BulkRunEnrichmentIn": {"properties": {"params": {"items": {"additionalProperties": true, "type": "object"}, "title": "Params", "type": "array"}, "pagination": {"anyOf": [{"$ref": "#/components/schemas/PaginationOptions"}, {"type": "null"}]}}, "required": ["params"], "title": "BulkRunEnrichmentIn", "type": "object"}, "ChoicesResponse": {"properties": {"items": {"items": {"$ref": "#/components/schemas/ChoiceItem"}, "title": "Items", "type": "array"}, "page": {"title": "Page", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "has_next_page": {"title": "Has Next Page", "type": "boolean"}, "total_count": {"title": "Total Count", "type": "integer"}}, "required": ["items", "page", "limit", "has_next_page", "total_count"], "title": "ChoicesResponse", "type": "object"}, "WaterfallOut": {"properties": {"identifier": {"title": "Identifier", "type": "string"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "input_params": {"items": {"additionalProperties": true, "type": "object"}, "title": "Input Params", "type": "array"}, "output_fields": {"items": {"additionalProperties": true, "type": "object"}, "title": "Output Fields", "type": "array"}, "available_enrichments": {"items": {"additionalProperties": true, "type": "object"}, "title": "Available Enrichments", "type": "array"}, "is_email_verifying": {"title": "Is Email Verifying", "type": "boolean"}, "email_verifiers": {"items": {"additionalProperties": true, "type": "object"}, "title": "Email Verifiers", "type": "array"}}, "required": ["identifier", "name", "description", "input_params", "output_fields", "available_enrichments", "is_email_verifying", "email_verifiers"], "title": "WaterfallOut", "type": "object"}, "RunWaterfallIn": {"properties": {"params": {"additionalProperties": true, "title": "Params", "type": "object"}, "enrichments": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Provider ids to run, in order. Omit or pass [] to run the waterfall's default cascade (providers with enabled_by_default=true).", "title": "Enrichments"}, "email_verifier": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Email Verifier"}, "per_enrichment_authorization": {"anyOf": [{"additionalProperties": {"type": "integer"}, "type": "object"}, {"type": "null"}], "description": "Map of enrichment_id (str) to user_key_id (int). Use your own API keys per provider step or for the email verifier (key it by the verifier's id).", "title": "Per Enrichment Authorization"}}, "required": ["params"], "title": "RunWaterfallIn", "type": "object"}, "BulkRunWaterfallIn": {"properties": {"params": {"items": {"additionalProperties": true, "type": "object"}, "title": "Params", "type": "array"}, "enrichments": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Provider ids to run, in order. Omit or pass [] to run the waterfall's default cascade (providers with enabled_by_default=true).", "title": "Enrichments"}, "email_verifier": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Email Verifier"}, "per_enrichment_authorization": {"anyOf": [{"additionalProperties": {"type": "integer"}, "type": "object"}, {"type": "null"}], "description": "Map of enrichment_id (str) to user_key_id (int). Use your own API keys per provider step or for the email verifier (key it by the verifier's id).", "title": "Per Enrichment Authorization"}}, "required": ["params"], "title": "BulkRunWaterfallIn", "type": "object"}, "TableOut": {"properties": {"identifier": {"title": "Identifier", "type": "string"}, "name": {"title": "Name", "type": "string"}, "created_at": {"title": "Created At", "type": "string"}, "updated_at": {"title": "Updated At", "type": "string"}, "workspace_identifier": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workspace Identifier"}, "workbook": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workbook"}, "table_url": {"readOnly": true, "title": "Table Url", "type": "string"}}, "required": ["identifier", "name", "created_at", "updated_at", "table_url"], "title": "TableOut", "type": "object"}, "CreateTableIn": {"properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "columns": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Columns"}, "rows": {"default": 0, "title": "Rows", "type": "integer"}}, "title": "CreateTableIn", "type": "object"}, "DuplicateTableIn": {"properties": {"table": {"description": "UUID of the table to duplicate.", "format": "uuid", "title": "Table", "type": "string"}}, "required": ["table"], "title": "DuplicateTableIn", "type": "object"}, "RenameTableIn": {"properties": {"name": {"description": "New table name.", "title": "Name", "type": "string"}}, "required": ["name"], "title": "RenameTableIn", "type": "object"}, "MoveTableToWorkbookIn": {"properties": {"workbook": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workbook"}, "new_workbook": {"default": false, "title": "New Workbook", "type": "boolean"}, "name": {"anyOf": [{"maxLength": 128, "type": "string"}, {"type": "null"}], "title": "Name"}}, "title": "MoveTableToWorkbookIn", "type": "object"}, "ExportTableOut": {"properties": {"status": {"title": "Status", "type": "string"}, "file_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "File Id"}, "file": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "File"}, "message": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Message"}}, "required": ["status"], "title": "ExportTableOut", "type": "object"}, "ExportTableIn": {"properties": {"format": {"default": "csv", "description": "One of: csv, xlsx, sheets.", "title": "Format", "type": "string"}, "kwargs": {"additionalProperties": true, "title": "Kwargs", "type": "object"}}, "title": "ExportTableIn", "type": "object"}, "DedupeRowsOut": {"properties": {"count_all_rows": {"title": "Count All Rows", "type": "integer"}, "count_rows_delete": {"title": "Count Rows Delete", "type": "integer"}}, "required": ["count_all_rows", "count_rows_delete"], "title": "DedupeRowsOut", "type": "object"}, "DedupeRowsIn": {"properties": {"columns": {"anyOf": [{"items": {"format": "uuid", "type": "string"}, "type": "array"}, {"type": "null"}], "description": "Column UUIDs to compare. Omit to compare every main column.", "title": "Columns"}}, "title": "DedupeRowsIn", "type": "object"}, "ListRowsOut": {"properties": {"has_next_page": {"title": "Has Next Page", "type": "boolean"}, "total_count": {"title": "Total Count", "type": "integer"}, "page": {"title": "Page", "type": "integer"}, "data": {"items": {"additionalProperties": true, "type": "object"}, "title": "Data", "type": "array"}}, "required": ["has_next_page", "total_count", "page", "data"], "title": "ListRowsOut", "type": "object"}, "BatchInsertOut": {"properties": {"results": {"items": {"$ref": "#/components/schemas/BatchInsertResult"}, "title": "Results", "type": "array"}}, "required": ["results"], "title": "BatchInsertOut", "type": "object"}, "BatchInsertResult": {"properties": {"index": {"title": "Index", "type": "integer"}, "id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Id"}, "action": {"title": "Action", "type": "string"}, "row_data": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Row Data"}}, "required": ["index", "action"], "title": "BatchInsertResult", "type": "object"}, "BatchInsertIn": {"properties": {"rows": {"items": {"$ref": "#/components/schemas/BatchInsertRowIn"}, "minItems": 1, "title": "Rows", "type": "array"}, "options": {"anyOf": [{"$ref": "#/components/schemas/InsertOptions"}, {"type": "null"}]}, "return_rows": {"default": false, "title": "Return Rows", "type": "boolean"}}, "required": ["rows"], "title": "BatchInsertIn", "type": "object"}, "BatchInsertRowIn": {"properties": {"fields": {"additionalProperties": true, "description": "Column values keyed by human-readable name.", "title": "Fields", "type": "object"}}, "required": ["fields"], "title": "BatchInsertRowIn", "type": "object"}, "DedupeOptions": {"properties": {"enabled": {"default": false, "title": "Enabled", "type": "boolean"}, "keys": {"items": {"type": "string"}, "title": "Keys", "type": "array"}}, "title": "DedupeOptions", "type": "object"}, "InsertOptions": {"properties": {"allow_new_columns": {"default": false, "title": "Allow New Columns", "type": "boolean"}, "dedupe": {"anyOf": [{"$ref": "#/components/schemas/DedupeOptions"}, {"type": "null"}]}}, "title": "InsertOptions", "type": "object"}, "BatchUpdateOut": {"properties": {"results": {"items": {"$ref": "#/components/schemas/BatchUpdateResult"}, "title": "Results", "type": "array"}}, "required": ["results"], "title": "BatchUpdateOut", "type": "object"}, "BatchUpdateResult": {"properties": {"id": {"title": "Id", "type": "string"}, "ok": {"title": "Ok", "type": "boolean"}, "error": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Error"}, "row_data": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Row Data"}}, "required": ["id", "ok"], "title": "BatchUpdateResult", "type": "object"}, "BatchUpdateIn": {"properties": {"rows": {"items": {"$ref": "#/components/schemas/BatchUpdateRowIn"}, "minItems": 1, "title": "Rows", "type": "array"}, "overwrite": {"default": true, "description": "If false, only empty fields are updated.", "title": "Overwrite", "type": "boolean"}, "return_rows": {"default": false, "description": "If true, each result includes full row_data.", "title": "Return Rows", "type": "boolean"}}, "required": ["rows"], "title": "BatchUpdateIn", "type": "object"}, "BatchUpdateRowIn": {"properties": {"id": {"description": "UUID of the row to update.", "title": "Id", "type": "string"}, "fields": {"additionalProperties": true, "description": "Column values keyed by human-readable name.", "title": "Fields", "type": "object"}}, "required": ["id", "fields"], "title": "BatchUpdateRowIn", "type": "object"}, "DeleteRowsIn": {"properties": {"row_ids": {"items": {"format": "uuid", "type": "string"}, "minItems": 1, "title": "Row Ids", "type": "array"}}, "required": ["row_ids"], "title": "DeleteRowsIn", "type": "object"}, "UpsertOut": {"properties": {"results": {"items": {"$ref": "#/components/schemas/UpsertResult"}, "title": "Results", "type": "array"}}, "required": ["results"], "title": "UpsertOut", "type": "object"}, "UpsertResult": {"properties": {"index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Index"}, "id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Id"}, "action": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Action"}, "error": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Error"}, "row_data": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Row Data"}}, "title": "UpsertResult", "type": "object"}, "UpsertIn": {"properties": {"rows": {"items": {"$ref": "#/components/schemas/UpsertRowIn"}, "minItems": 1, "title": "Rows", "type": "array"}, "return_rows": {"default": false, "title": "Return Rows", "type": "boolean"}}, "required": ["rows"], "title": "UpsertIn", "type": "object"}, "UpsertRowIn": {"properties": {"key": {"additionalProperties": true, "description": "Exactly one column to match on: {column_name: value}.", "title": "Key", "type": "object"}, "fields": {"additionalProperties": true, "description": "Column values to set/update.", "title": "Fields", "type": "object"}}, "required": ["key", "fields"], "title": "UpsertRowIn", "type": "object"}, "ColumnOut": {"properties": {"identifier": {"title": "Identifier", "type": "string"}, "internal_name": {"title": "Internal Name", "type": "string"}, "additional_intenal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Additional Intenal Name"}, "name": {"title": "Name", "type": "string"}, "type_of_value": {"title": "Type Of Value", "type": "string"}, "data_processor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Data Processor Id"}}, "required": ["identifier", "internal_name", "name", "type_of_value"], "title": "ColumnOut", "type": "object"}, "CreateColumnOut": {"properties": {"identifier": {"title": "Identifier", "type": "string"}, "name": {"title": "Name", "type": "string"}, "type_of_value": {"title": "Type Of Value", "type": "string"}}, "required": ["identifier", "name", "type_of_value"], "title": "CreateColumnOut", "type": "object"}, "CreateColumnIn": {"properties": {"name": {"description": "Column display name.", "title": "Name", "type": "string"}, "type": {"default": "text", "description": "Column type (default: 'text'). One of: text, longtext, number, currency, bool, date, datetime, json, link, email, phone, image, linkedin, choice, multiplechoice, waterfall.", "title": "Type", "type": "string"}, "config": {"additionalProperties": true, "title": "Config", "type": "object"}}, "required": ["name"], "title": "CreateColumnIn", "type": "object"}, "RenameColumnIn": {"properties": {"name": {"description": "New column display name.", "title": "Name", "type": "string"}}, "required": ["name"], "title": "RenameColumnIn", "type": "object"}, "ReorderColumnIn": {"properties": {"index": {"description": "0-based index among non-system columns.", "minimum": 0, "title": "Index", "type": "integer"}}, "required": ["index"], "title": "ReorderColumnIn", "type": "object"}, "AddEnrichmentOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "enrichment_name": {"title": "Enrichment Name", "type": "string"}}, "required": ["id", "enrichment_name"], "title": "AddEnrichmentOut", "type": "object"}, "AddEnrichmentIn": {"properties": {"enrichment": {"description": "The enrichment ID to add.", "title": "Enrichment", "type": "integer"}, "mapping": {"additionalProperties": {"$ref": "#/components/schemas/MappingEntry"}, "description": "Maps each enrichment parameter name to a value source. Each value is {\"type\": \"mapping\"|\"simple\", \"value\": ...}. Use type=\"mapping\" to pull from a table column per row (value = column name), or type=\"simple\" for a static value (value may contain {column} placeholders). See GET /{table_uuid}/columns for valid column names.", "examples": [{"email": {"type": "mapping", "value": "email"}}], "title": "Mapping", "type": "object"}, "launch_strategy": {"default": "run_on_click", "enum": ["run_on_click", "run_on_update"], "title": "Launch Strategy", "type": "string"}}, "required": ["enrichment", "mapping"], "title": "AddEnrichmentIn", "type": "object"}, "MappingEntry": {"description": "One entry of a parameter\u2192column mapping.\n\n``type`` selects where the parameter value comes from:\n\n* ``\"mapping\"`` \u2014 read the value from a table column, per row. ``value`` is\n  the column name, its ``additional_intenal_name`` or its UUID\n  (see ``GET /{table_uuid}/columns``).\n* ``\"simple\"`` \u2014 a static value used for every row. ``value`` may embed\n  column placeholders: ``{column_name}`` is replaced with that column's\n  value per row, and ``{?column_name}`` marks the reference as optional\n  (row is still processed if the column is empty).", "examples": [{"type": "mapping", "value": "email"}, {"type": "simple", "value": "Find the industry of {company}"}], "properties": {"type": {"description": "\"mapping\" reads from a table column per row (value = column name); \"simple\" is a static value for every row (value may contain {column} placeholders); \"json_path\" reads one nested field of a json column (value = column, json_path = $.field).", "enum": ["mapping", "simple", "json_path"], "title": "Type", "type": "string"}, "value": {"description": "Column name/UUID when type=\"mapping\" or type=\"json_path\", or a constant (with optional {column} placeholders) when type=\"simple\".", "title": "Value", "type": "string"}, "json_path": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Nested field path when type=\"json_path\", e.g. \"$.company.name\".", "title": "Json Path"}}, "required": ["type", "value"], "title": "MappingEntry", "type": "object"}, "TableEnrichmentOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "TableEnrichmentOut", "type": "object"}, "RunEnrichmentOut": {"properties": {"status": {"title": "Status", "type": "string"}, "processing_rows": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Processing Rows"}}, "required": ["status"], "title": "RunEnrichmentOut", "type": "object"}, "UpdateEnrichmentIn": {"properties": {"mapping": {"anyOf": [{"additionalProperties": {"$ref": "#/components/schemas/MappingEntry"}, "type": "object"}, {"type": "null"}], "description": "Same shape as add-enrichment: {\"param\": {\"type\": \"mapping\"|\"simple\", \"value\": \"...\"}}.", "title": "Mapping"}, "launch_strategy": {"anyOf": [{"enum": ["run_on_click", "run_on_update"], "type": "string"}, {"type": "null"}], "title": "Launch Strategy"}}, "title": "UpdateEnrichmentIn", "type": "object"}, "AddWaterfallOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "waterfall_name": {"title": "Waterfall Name", "type": "string"}}, "required": ["id", "waterfall_name"], "title": "AddWaterfallOut", "type": "object"}, "AddWaterfallIn": {"properties": {"waterfall": {"title": "Waterfall", "type": "string"}, "enrichments": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Provider ids, in order. Omit or pass [] to attach the waterfall's default cascade (providers with enabled_by_default=true).", "title": "Enrichments"}, "mapping": {"additionalProperties": {"type": "string"}, "title": "Mapping", "type": "object"}, "email_verifier": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Email Verifier"}}, "required": ["waterfall", "mapping"], "title": "AddWaterfallIn", "type": "object"}, "InstalledWaterfallOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "waterfall_name": {"title": "Waterfall Name", "type": "string"}}, "required": ["id", "waterfall_name"], "title": "InstalledWaterfallOut", "type": "object"}, "AddExporterOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "exporter_name": {"title": "Exporter Name", "type": "string"}}, "required": ["id", "exporter_name"], "title": "AddExporterOut", "type": "object"}, "AddExporterIn": {"properties": {"exporter": {"title": "Exporter", "type": "integer"}, "mapping": {"additionalProperties": {"$ref": "#/components/schemas/MappingEntry"}, "description": "Maps each static exporter parameter name to a value source. Each value is {\"type\": \"mapping\"|\"simple\", \"value\": ...} \u2014 same format as add-enrichment. Use type=\"mapping\" for a table column (value = column name) or type=\"simple\" for a static value. For HubSpot/Pipedrive dynamic properties use additional_mapping instead.", "examples": [{"email": {"type": "mapping", "value": "email"}}], "title": "Mapping", "type": "object"}, "additional_mapping": {"anyOf": [{"additionalProperties": {"$ref": "#/components/schemas/MappingEntry"}, "type": "object"}, {"type": "null"}], "description": "Maps provider-fetched dynamic field names (from GET /exporters/{id} additional_params, e.g. HubSpot domain/name/city) to value sources. Same entry format as mapping. Do NOT put these keys in mapping.", "title": "Additional Mapping"}, "launch_strategy": {"default": "run_on_click", "enum": ["run_on_click", "run_on_update"], "title": "Launch Strategy", "type": "string"}, "authorization": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Authorization"}, "custom_body_template": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Custom Body Template"}}, "required": ["exporter"], "title": "AddExporterIn", "type": "object"}, "InstalledExporterOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "InstalledExporterOut", "type": "object"}, "AddFlowOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "flow_id": {"title": "Flow Id", "type": "string"}, "flow_name": {"title": "Flow Name", "type": "string"}, "result_column": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Result Column"}, "column_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Column Name"}}, "required": ["id", "flow_id", "flow_name"], "title": "AddFlowOut", "type": "object"}, "AddFlowIn": {"properties": {"flow_id": {"description": "Workspace Flow ID to attach (e.g. 'fl_a3k2p9m7').", "title": "Flow Id", "type": "string"}, "input_bindings": {"additionalProperties": {"type": "string"}, "description": "Maps flow input id \u2192 table column UUID.", "title": "Input Bindings", "type": "object"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display name for the result column (defaults to flow name).", "title": "Name"}, "automation": {"anyOf": [{"$ref": "#/components/schemas/AutomationIn"}, {"type": "null"}]}, "condition": {"anyOf": [{"$ref": "#/components/schemas/ConditionIn"}, {"type": "null"}]}}, "required": ["flow_id"], "title": "AddFlowIn", "type": "object"}, "AutomationIn": {"properties": {"launch_strategy": {"default": "run_on_click", "enum": ["run_on_click", "run_on_update"], "title": "Launch Strategy", "type": "string"}}, "title": "AutomationIn", "type": "object"}, "ConditionIn": {"properties": {"formula": {"description": "CEL formula, e.g. '{{col_uuid}} != \"\"'.", "title": "Formula", "type": "string"}}, "required": ["formula"], "title": "ConditionIn", "type": "object"}, "InstalledFlowOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "flow_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Flow Id"}, "flow_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Flow Name"}, "result_column": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Result Column"}, "column_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Column Name"}, "launch_strategy": {"title": "Launch Strategy", "type": "string"}, "input_bindings": {"additionalProperties": {"type": "string"}, "title": "Input Bindings", "type": "object"}}, "required": ["id", "flow_id", "flow_name", "result_column", "column_name", "launch_strategy", "input_bindings"], "title": "InstalledFlowOut", "type": "object"}, "DataSourceOut": {"description": "Read shape for a table data source returned by the External API.\n\nThe field set matches ``tables.services.table_source.serialize_source``\n(the shared plain serializer the MCP also returns). The internal app has its\nown DRF ``TableSourceSerializer`` for the UI and is deliberately NOT coupled\nto this schema \u2014 the UI and API/MCP can diverge if their needs differ.", "properties": {"id": {"title": "Id", "type": "integer"}, "source_type": {"title": "Source Type", "type": "string"}, "source_type_display": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Source Type Display"}, "status": {"title": "Status", "type": "string"}, "status_display": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Display"}, "dataset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Dataset Id"}, "webhook_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Webhook Id"}, "webhook_identifier": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Webhook Identifier"}, "webhook_based_integration": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Webhook Based Integration"}, "webhook_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Webhook Url"}, "webhook_mode": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Webhook Mode"}, "schedule_task_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Schedule Task Id"}, "error_message": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error Message"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "logo": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Logo"}, "records_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Records Count"}, "last_synced_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Synced At"}, "created_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created At"}, "updated_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Updated At"}}, "required": ["id", "source_type", "status"], "title": "DataSourceOut", "type": "object"}, "AttachSourceIn": {"description": "Attach a new data source to a table.\n\n* ``crm`` requires ``dataset_id`` (the catalogue Dataset to pull from) and\n  may pass a ``schedule`` for recurring syncs.\n* ``webhook`` creates a webhook handler in the ``webhook_mode`` mode when\n  ``webhook_id`` is omitted.\n* ``csv`` records a CSV source; rows are added via the row endpoints.", "properties": {"source_type": {"$ref": "#/components/schemas/SourceType", "description": "One of: csv, webhook, crm."}, "dataset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Catalogue Dataset id \u2014 required for crm sources.", "title": "Dataset Id"}, "webhook_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing WebhookTable id to link (webhook sources only).", "title": "Webhook Id"}, "webhook_mode": {"default": "raw_json", "description": "How a new webhook stores payloads, fixed at creation time. \"raw_json\" dumps each payload into a single JSON column and works with no further setup; \"mapping\" leaves the webhook unmapped so the first payload is kept as a sample \u2014 then call the webhook-fields and webhook-mapping endpoints to spread fields across columns.", "enum": ["raw_json", "mapping"], "title": "Webhook Mode", "type": "string"}, "schedule": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "Optional recurring-sync config for crm sources. Omit to connect the source with NO scheduler (no recurring pulls); only set it to enable scheduled syncs, e.g. {\"cron_string\": \"0 0 * * *\", \"rows\": 100, \"overwrite\": false}. WARNING: \"overwrite\": true clears the entire table before each sync.", "title": "Schedule"}}, "required": ["source_type"], "title": "AttachSourceIn", "type": "object"}, "SourceType": {"enum": ["csv", "webhook", "crm"], "title": "SourceType", "type": "string"}, "CsvAppendIn": {"properties": {"csv_content": {"description": "CSV text including a header row.", "title": "Csv Content", "type": "string"}, "columns_mapping": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"type": "null"}], "description": "Optional {csv_header: column_uuid | \"-\"}. \"-\" creates a new column.", "title": "Columns Mapping"}}, "required": ["csv_content"], "title": "CsvAppendIn", "type": "object"}, "UpdateScheduleIn": {"description": "Update a connected crm source's sync schedule.", "properties": {"schedule": {"additionalProperties": true, "description": "Sync config, e.g. {\"cron_string\": \"0 12 * * *\", \"rows\": 200, \"overwrite\": true}.", "title": "Schedule", "type": "object"}}, "required": ["schedule"], "title": "UpdateScheduleIn", "type": "object"}, "SyncNowIn": {"properties": {"refresh": {"default": false, "description": "When true, delete this source's existing rows before re-pulling.", "title": "Refresh", "type": "boolean"}}, "title": "SyncNowIn", "type": "object"}, "RunSourceIn": {"properties": {"params": {"additionalProperties": true, "description": "Dataset request parameters for this pull.", "title": "Params", "type": "object"}, "rows_or_pages": {"default": 0, "description": "Rows or pages to pull. Required when the dataset is paginated.", "title": "Rows Or Pages", "type": "integer"}, "check_duplicates_columns": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Column UUIDs used for dedup.", "title": "Check Duplicates Columns"}, "use_cache": {"default": false, "title": "Use Cache", "type": "boolean"}}, "required": ["params"], "title": "RunSourceIn", "type": "object"}, "WebhookMappingIn": {"properties": {"mapping": {"additionalProperties": {"type": "string"}, "description": "JSONPath \u2192 column UUID or \"-\". Keys come from GET .../webhook-fields.", "title": "Mapping", "type": "object"}, "use_datetime_field": {"default": false, "description": "Also add a Created_at datetime column.", "title": "Use Datetime Field", "type": "boolean"}}, "required": ["mapping"], "title": "WebhookMappingIn", "type": "object"}, "RunTraceOut": {"description": "What a flow run actually did, step by step. Returned on ``include_trace=true``.", "properties": {"run_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Id of the recorded run. Null for a trace recovered from the short-lived cache.", "title": "Run Id"}, "flow_version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version of the flow graph this run executed, so a stretch of empty results can be tied to the edit that started it.", "title": "Flow Version"}, "run_status": {"default": "", "description": "The run's own verdict: 'completed', 'no_data', 'aborted', 'failed' or 'running'. Finer-grained than the task `status`, which only distinguishes completed from failed: a run where every step returned nothing reports task status 'completed' and run_status 'no_data'.", "title": "Run Status", "type": "string"}, "termination_reason": {"default": "", "description": "Machine-readable code for why the run stopped short, e.g. 'no_data' or 'condition_not_met'. Empty when nothing halted it.", "title": "Termination Reason", "type": "string"}, "error_message": {"default": "", "description": "Human-readable form of `termination_reason`.", "title": "Error Message", "type": "string"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "finished_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Finished At"}, "duration_seconds": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Duration Seconds"}, "total_cost": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Credits the run's steps summed to.", "title": "Total Cost"}, "steps": {"description": "One entry per node the graph executed, in execution order: `node_id`, `type` ('enrichment', 'transform', 'condition', 'skipped', 'failed'), `result`, `details` and `cost`. A node pruned by a condition appears as type 'skipped'. Provider response bodies are not included \u2014 those come back in `data`.", "items": {"additionalProperties": true, "type": "object"}, "title": "Steps", "type": "array"}}, "title": "RunTraceOut", "type": "object"}, "TaskDetailOut": {"properties": {"task_id": {"description": "Unique identifier of the task.", "title": "Task Id", "type": "string"}, "request_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "deprecated": true, "description": "Deprecated: use task_id instead. Same value as task_id.", "title": "Request Id"}, "status": {"description": "Current status: 'processing', 'completed', 'failed', or 'cancelled'.", "title": "Status", "type": "string"}, "progress": {"anyOf": [{"additionalProperties": {"type": "integer"}, "type": "object"}, {"type": "null"}], "description": "How far a bulk run has got: `total`, `completed`, `no_data`, `failed` and `processing` counts of inputs. `no_data` is a clean miss. `failed` is a real error on that input. Omitted for single (non-bulk) runs.", "title": "Progress"}, "data": {"anyOf": [{"items": {}, "type": "array"}, {"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "Resulting data once completed. For bulk runs this is an array aligned to the inputs: one element per input, in the same order they were submitted, with null for inputs that returned no data (len(data) equals the number of inputs, and data[i] is the result for input i). A single (non-bulk) run returns the result object directly.", "title": "Data"}, "input": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "Echo of the submitted inputs, aligned to `data` so you can attribute results back to what was searched. Shape mirrors the run body: {\"params\": {...}} for a single run and {\"params\": [{...}, ...]} for a bulk run, where params[i] corresponds to data[i] (same order, misses included). Omitted for waterfall tasks and for flow tasks whose input echo has expired.", "title": "Input"}, "error": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "string"}, {"type": "null"}], "description": "Why the task returned no data. A clean miss reads \"No matching data found for this input.\" \u2014 for waterfalls followed by the providers that were tried. A bulk run returns one message per input, in input order.", "title": "Error"}, "credits_spent": {"default": 0, "title": "Credits Spent", "type": "number"}, "trace": {"anyOf": [{"$ref": "#/components/schemas/RunTraceOut"}, {"items": {"anyOf": [{"$ref": "#/components/schemas/RunTraceOut"}, {"type": "null"}]}, "type": "array"}, {"type": "null"}], "description": "Per-step account of a flow run, returned only when the request asks for it with `include_trace=true`. Shaped like `data`: one object for a single run, and for a bulk run a list aligned to the inputs, where trace[i] is the run for input i (null if no run can be attributed to that input). A bulk trace is always a list, never a single object. Omitted for enrichment and waterfall tasks, which have no steps to report, and for bulk runs started before per-input traces were recorded, whose runs can't be matched to their inputs.", "title": "Trace"}}, "required": ["task_id", "status"], "title": "TaskDetailOut", "type": "object"}, "TaskGoneOut": {"description": "410 body: a bare ``{\"detail\": ...}`` unless the poll asked for ``include_trace``.", "properties": {"detail": {"description": "Why the task's data is no longer available.", "title": "Detail", "type": "string"}, "task_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Returned together with `trace`.", "title": "Task Id"}, "credits_spent": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Returned together with `trace`.", "title": "Credits Spent"}, "trace": {"anyOf": [{"$ref": "#/components/schemas/RunTraceOut"}, {"items": {"anyOf": [{"$ref": "#/components/schemas/RunTraceOut"}, {"type": "null"}]}, "type": "array"}, {"type": "null"}], "description": "Returned with `include_trace=true` for a flow task. Results expire after 24 hours, but the record of what the run did is kept, so it still answers once the data is gone. Same shape as `trace` on a successful poll.", "title": "Trace"}}, "required": ["detail"], "title": "TaskGoneOut", "type": "object"}, "FolderOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "created_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created At"}, "updated_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Updated At"}, "table_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Table Count"}}, "required": ["id", "name"], "title": "FolderOut", "type": "object"}, "CreateFolderIn": {"properties": {"name": {"description": "Folder name.", "title": "Name", "type": "string"}}, "required": ["name"], "title": "CreateFolderIn", "type": "object"}, "MoveTableIn": {"properties": {"table_uuid": {"description": "UUID of the table to move.", "format": "uuid", "title": "Table Uuid", "type": "string"}, "folder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of the target folder. Pass null to remove from folder.", "title": "Folder Id"}}, "required": ["table_uuid"], "title": "MoveTableIn", "type": "object"}, "RenameFolderIn": {"properties": {"name": {"description": "New folder name.", "title": "Name", "type": "string"}}, "required": ["name"], "title": "RenameFolderIn", "type": "object"}, "AuthorizationInfo": {"properties": {"required": {"title": "Required", "type": "boolean"}, "connections": {"items": {"$ref": "#/components/schemas/Connection"}, "title": "Connections", "type": "array"}}, "required": ["required", "connections"], "title": "AuthorizationInfo", "type": "object"}, "Connection": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "type": {"title": "Type", "type": "string"}}, "required": ["id", "name", "type"], "title": "Connection", "type": "object"}, "ExporterAdditionalParam": {"description": "Provider-fetched dynamic field (e.g. a HubSpot company property).\n\nPass via ``additional_mapping`` on add-exporter \u2014 not via ``mapping``.", "properties": {"name": {"title": "Name", "type": "string"}, "label": {"title": "Label", "type": "string"}}, "required": ["name", "label"], "title": "ExporterAdditionalParam", "type": "object"}, "ExporterParam": {"properties": {"name": {"title": "Name", "type": "string"}, "is_required": {"title": "Is Required", "type": "boolean"}, "type_field": {"title": "Type Field", "type": "string"}, "description": {"title": "Description", "type": "string"}, "choices": {"anyOf": [{"$ref": "#/components/schemas/Choices"}, {"type": "null"}]}}, "required": ["name", "is_required", "type_field", "description"], "title": "ExporterParam", "type": "object"}, "ExporterParams": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "dataset": {"title": "Dataset", "type": "integer"}, "params": {"items": {"$ref": "#/components/schemas/ExporterParam"}, "title": "Params", "type": "array"}, "additional_params": {"default": [], "items": {"$ref": "#/components/schemas/ExporterAdditionalParam"}, "title": "Additional Params", "type": "array"}, "response_fields": {"items": {"$ref": "#/components/schemas/ExporterResponseField"}, "title": "Response Fields", "type": "array"}, "authorization": {"$ref": "#/components/schemas/AuthorizationInfo"}}, "required": ["id", "name", "description", "dataset", "params", "response_fields", "authorization"], "title": "ExporterParams", "type": "object"}, "ExporterResponseField": {"properties": {"name": {"title": "Name", "type": "string"}, "display_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Display Name"}, "type_field": {"title": "Type Field", "type": "string"}}, "required": ["name", "type_field"], "title": "ExporterResponseField", "type": "object"}, "ConnectorOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "type": {"title": "Type", "type": "string"}, "method": {"title": "Method", "type": "string"}, "url": {"title": "Url", "type": "string"}, "headers": {"default": [], "items": {"$ref": "#/components/schemas/NameValue"}, "title": "Headers", "type": "array"}, "parameters": {"default": [], "items": {"$ref": "#/components/schemas/NameValue"}, "title": "Parameters", "type": "array"}, "body": {"default": [], "items": {"$ref": "#/components/schemas/NameValue"}, "title": "Body", "type": "array"}, "body_template": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Body Template"}, "rate_limit": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Rate Limit"}, "max_concurrency": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Concurrency"}, "created_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created At"}}, "required": ["id", "name", "type", "method", "url"], "title": "ConnectorOut", "type": "object"}, "NameValue": {"properties": {"name": {"title": "Name", "type": "string"}, "value": {"default": "", "title": "Value", "type": "string"}}, "required": ["name"], "title": "NameValue", "type": "object"}, "ConnectorCreate": {"properties": {"name": {"description": "Display name for the connector", "maxLength": 256, "title": "Name", "type": "string"}, "type": {"default": "enrichment", "description": "Connector type: simple, enrichment, or exporter", "title": "Type", "type": "string"}, "method": {"description": "HTTP method: get, post, put, or patch", "title": "Method", "type": "string"}, "url": {"description": "Full API endpoint URL", "maxLength": 512, "title": "Url", "type": "string"}, "headers": {"items": {"$ref": "#/components/schemas/NameValue"}, "title": "Headers", "type": "array"}, "parameters": {"items": {"$ref": "#/components/schemas/NameValue"}, "title": "Parameters", "type": "array"}, "body": {"items": {"$ref": "#/components/schemas/NameValue"}, "title": "Body", "type": "array"}, "body_template": {"anyOf": [{"maxLength": 2048, "type": "string"}, {"type": "null"}], "description": "Jinja body template.", "title": "Body Template"}, "rate_limit": {"anyOf": [{"minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Rate Limit"}, "max_concurrency": {"anyOf": [{"minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Max Concurrency"}}, "required": ["name", "method", "url"], "title": "ConnectorCreate", "type": "object"}, "FlowInputOut": {"properties": {"id": {"title": "Id", "type": "string"}, "description": {"title": "Description", "type": "string"}, "type": {"title": "Type", "type": "string"}, "required": {"title": "Required", "type": "boolean"}}, "required": ["id", "description", "type", "required"], "title": "FlowInputOut", "type": "object"}, "FlowOut": {"properties": {"id": {"title": "Id", "type": "string"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "inputs": {"items": {"$ref": "#/components/schemas/FlowInputOut"}, "title": "Inputs", "type": "array"}, "outputs": {"items": {"$ref": "#/components/schemas/FlowOutputOut"}, "title": "Outputs", "type": "array"}, "created_at": {"title": "Created At", "type": "string"}, "updated_at": {"title": "Updated At", "type": "string"}}, "required": ["id", "name", "description", "inputs", "outputs", "created_at", "updated_at"], "title": "FlowOut", "type": "object"}, "FlowOutputOut": {"properties": {"id": {"title": "Id", "type": "string"}, "key": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Key"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "response_field_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Response Field Id"}}, "required": ["id"], "title": "FlowOutputOut", "type": "object"}, "FlowDetailOut": {"description": "``FlowOut`` plus the pieces an editing client needs.\n\nWithout ``config`` and ``internal_version`` a caller cannot do a\nread-modify-write at all, which is why the API could only run flows.", "properties": {"id": {"title": "Id", "type": "string"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "inputs": {"items": {"$ref": "#/components/schemas/FlowInputOut"}, "title": "Inputs", "type": "array"}, "outputs": {"items": {"$ref": "#/components/schemas/FlowOutputOut"}, "title": "Outputs", "type": "array"}, "created_at": {"title": "Created At", "type": "string"}, "updated_at": {"title": "Updated At", "type": "string"}, "config": {"$ref": "#/components/schemas/FlowDefinition", "title": "Config"}, "ui": {"additionalProperties": true, "title": "Ui", "type": "object"}, "internal_version": {"title": "Internal Version", "type": "string"}}, "required": ["id", "name", "description", "inputs", "outputs", "created_at", "updated_at", "config", "ui", "internal_version"], "title": "FlowDetailOut", "type": "object"}, "FlowCreateIn": {"properties": {"name": {"description": "Display name of the flow.", "title": "Name", "type": "string"}, "config": {"$ref": "#/components/schemas/FlowDefinition", "description": "Flow definition: `{inputs: [...], nodes: [...], output: {...}}`. Shape: the `FlowDefinition` model in this spec, also served as JSON Schema by `GET /flows/config-schema`. Cross-node rules are checked by `POST /flows/validate-config`.", "title": "Config"}, "description": {"default": "", "title": "Description", "type": "string"}, "ui": {"additionalProperties": true, "description": "Editor-only metadata (node positions, colors). The runtime ignores it.", "title": "Ui", "type": "object"}}, "required": ["name", "config"], "title": "FlowCreateIn", "type": "object"}, "FlowConfigErrorOut": {"description": "One reason a config is rejected \u2014 the same shape on every flow endpoint and in MCP.", "properties": {"node_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Node the problem is in; null for a flow-level one.", "title": "Node Id"}, "field": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Dotted path within the node (or within the config), e.g. `inputs.email`, when known.", "title": "Field"}, "message": {"title": "Message", "type": "string"}}, "required": ["message"], "title": "FlowConfigErrorOut", "type": "object"}, "FlowValidateOut": {"properties": {"valid": {"title": "Valid", "type": "boolean"}, "errors": {"description": "Why the config would be rejected on save. Empty when `valid` is true.", "items": {"$ref": "#/components/schemas/FlowConfigErrorOut"}, "title": "Errors", "type": "array"}}, "required": ["valid"], "title": "FlowValidateOut", "type": "object"}, "FlowConfigIn": {"properties": {"config": {"$ref": "#/components/schemas/FlowDefinition", "description": "Flow definition, possibly unsaved: `{inputs: [...], nodes: [...], output: {...}}`. Same shape `POST /flows` and `GET /flows/{flow_id}` use.", "title": "Config"}}, "required": ["config"], "title": "FlowConfigIn", "type": "object"}, "FlowCostEstimateOut": {"properties": {"min": {"description": "Cheapest one-run cost, in credits.", "title": "Min", "type": "string"}, "max": {"description": "Most expensive one-run cost, in credits.", "title": "Max", "type": "string"}, "currency": {"default": "credits", "title": "Currency", "type": "string"}}, "required": ["min", "max"], "title": "FlowCostEstimateOut", "type": "object"}, "FlowReplaceIn": {"description": "Whole-flow replace. ``internal_version`` must be the value the last\n``GET /flows/{flow_id}`` returned, so a concurrent edit is refused instead\nof silently overwritten.", "properties": {"name": {"description": "Display name of the flow.", "title": "Name", "type": "string"}, "config": {"$ref": "#/components/schemas/FlowDefinition", "description": "Flow definition: `{inputs: [...], nodes: [...], output: {...}}`. Shape: the `FlowDefinition` model in this spec, also served as JSON Schema by `GET /flows/config-schema`. Cross-node rules are checked by `POST /flows/validate-config`.", "title": "Config"}, "description": {"default": "", "title": "Description", "type": "string"}, "ui": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "Editor-only metadata. Omit to keep the stored value; send `{}` to clear it.", "title": "Ui"}, "internal_version": {"title": "Internal Version", "type": "string"}}, "required": ["name", "config", "internal_version"], "title": "FlowReplaceIn", "type": "object"}, "FlowUpdateIn": {"description": "Field-level update. Every field is optional; only what you send changes.\n\n``internal_version`` is required alongside ``config``: it is checked against\nthe stored value so a graph edit is refused rather than silently overwriting\nsomeone else's concurrent edit. Read it from `GET /flows/{flow_id}`.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "config": {"anyOf": [{"$ref": "#/components/schemas/FlowDefinition"}, {"type": "null"}], "title": "Config"}, "ui": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Ui"}, "internal_version": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Internal Version"}}, "title": "FlowUpdateIn", "type": "object"}, "FlowConfigOpsOut": {"properties": {"valid": {"title": "Valid", "type": "boolean"}, "errors": {"description": "Why the resulting config would be rejected. Only ever non-empty under `validate_only`.", "items": {"$ref": "#/components/schemas/FlowConfigErrorOut"}, "title": "Errors", "type": "array"}, "config": {"$ref": "#/components/schemas/FlowDefinition", "title": "Config"}, "flow": {"anyOf": [{"$ref": "#/components/schemas/FlowDetailOut"}, {"type": "null"}], "description": "The saved flow. Null when `validate_only` was set."}}, "required": ["valid", "config"], "title": "FlowConfigOpsOut", "type": "object"}, "FlowConfigOpsIn": {"description": "A small, ordered batch of targeted edits.\n\nEach op is `{\"op\": \"<name>\", ...}`. Available ops:\n\n* `set_input` / `remove_input` \u2014 flow-level inputs, by `input.id` / `input_id`\n* `add_node` (with optional `after`) / `replace_node` / `remove_node`\n* `update_node` \u2014 merge `patch` into one node (`data` merges one level deeper)\n* `set_node_input` / `remove_node_input` \u2014 one binding of one node\n* `set_node_output` / `remove_node_output` \u2014 one output port of one node\n* `set_output` \u2014 replace the whole flow output mapping (`null` clears it)\n* `set_output_field` / `remove_output_field` \u2014 one entry of `output.fields`\n\nThe batch is atomic: if any op fails, nothing is written.", "properties": {"ops": {"description": "Operations, applied in order.", "items": {"additionalProperties": true, "type": "object"}, "title": "Ops", "type": "array"}, "internal_version": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional. When set, the edit is refused if the flow changed since you read it. Omit to apply the ops to whatever is current.", "title": "Internal Version"}, "validate_only": {"default": false, "description": "Apply and validate the batch without saving; returns the resulting config.", "title": "Validate Only", "type": "boolean"}}, "required": ["ops"], "title": "FlowConfigOpsIn", "type": "object"}, "FlowVersionOut": {"properties": {"number": {"title": "Number", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "changed_fields": {"items": {"type": "string"}, "title": "Changed Fields", "type": "array"}, "source": {"description": "Where the edit came from: ui, api, mcp, admin or system.", "title": "Source", "type": "string"}, "created_at": {"title": "Created At", "type": "string"}, "created_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By"}, "restored_from": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version this one was restored from, if it came from a rollback.", "title": "Restored From"}}, "required": ["number", "name", "description", "changed_fields", "source", "created_at", "created_by"], "title": "FlowVersionOut", "type": "object"}, "FlowVersionDetailOut": {"properties": {"number": {"title": "Number", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "changed_fields": {"items": {"type": "string"}, "title": "Changed Fields", "type": "array"}, "source": {"description": "Where the edit came from: ui, api, mcp, admin or system.", "title": "Source", "type": "string"}, "created_at": {"title": "Created At", "type": "string"}, "created_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By"}, "restored_from": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version this one was restored from, if it came from a rollback.", "title": "Restored From"}, "config": {"$ref": "#/components/schemas/FlowDefinition", "title": "Config"}, "ui": {"additionalProperties": true, "title": "Ui", "type": "object"}}, "required": ["number", "name", "description", "changed_fields", "source", "created_at", "created_by", "config", "ui"], "title": "FlowVersionDetailOut", "type": "object"}, "RestoreFlowVersionOut": {"properties": {"flow": {"$ref": "#/components/schemas/FlowDetailOut"}, "version": {"$ref": "#/components/schemas/FlowVersionOut"}}, "required": ["flow", "version"], "title": "RestoreFlowVersionOut", "type": "object"}, "RestoreFlowVersionIn": {"properties": {"internal_version": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional concurrency check, same semantics as on update.", "title": "Internal Version"}}, "title": "RestoreFlowVersionIn", "type": "object"}, "RunFlowIn": {"properties": {"inputs": {"additionalProperties": {"type": "string"}, "description": "Maps flow input id \u2192 value string.", "title": "Inputs", "type": "object"}}, "title": "RunFlowIn", "type": "object"}, "BulkRunFlowIn": {"properties": {"inputs": {"description": "One input set per record, in the order you want results back. Each object maps flow input id \u2192 value string, same shape as `POST /flows/{id}/run`.", "items": {"additionalProperties": {"type": "string"}, "type": "object"}, "minItems": 1, "title": "Inputs", "type": "array"}}, "required": ["inputs"], "title": "BulkRunFlowIn", "type": "object"}, "DataSourceCatalogItem": {"properties": {"dataset_id": {"title": "Dataset Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "data_source": {"title": "Data Source", "type": "string"}, "category": {"items": {"type": "string"}, "title": "Category", "type": "array"}, "auth_method": {"title": "Auth Method", "type": "string"}}, "required": ["dataset_id", "name", "description", "data_source", "category", "auth_method"], "title": "DataSourceCatalogItem", "type": "object"}, "DataSourceCatalogDetails": {"properties": {"dataset_id": {"title": "Dataset Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"}, "data_source": {"title": "Data Source", "type": "string"}, "category": {"items": {"type": "string"}, "title": "Category", "type": "array"}, "auth_method": {"title": "Auth Method", "type": "string"}, "parameters": {"items": {"additionalProperties": true, "type": "object"}, "title": "Parameters", "type": "array"}, "response_fields": {"items": {"additionalProperties": true, "type": "object"}, "title": "Response Fields", "type": "array"}, "pagination": {"additionalProperties": true, "title": "Pagination", "type": "object"}, "authorization": {"additionalProperties": true, "title": "Authorization", "type": "object"}}, "required": ["dataset_id", "name", "description", "data_source", "category", "auth_method", "parameters", "response_fields", "pagination", "authorization"], "title": "DataSourceCatalogDetails", "type": "object"}, "WorkbookOut": {"properties": {"identifier": {"title": "Identifier", "type": "string"}, "name": {"title": "Name", "type": "string"}, "created_at": {"title": "Created At", "type": "string"}, "updated_at": {"title": "Updated At", "type": "string"}, "folder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Folder Id"}, "tables": {"items": {"$ref": "#/components/schemas/WorkbookTableOut"}, "title": "Tables", "type": "array"}, "tables_count": {"default": 0, "title": "Tables Count", "type": "integer"}}, "required": ["identifier", "name", "created_at", "updated_at"], "title": "WorkbookOut", "type": "object"}, "WorkbookTableOut": {"properties": {"identifier": {"title": "Identifier", "type": "string"}, "name": {"title": "Name", "type": "string"}, "position": {"title": "Position", "type": "integer"}}, "required": ["identifier", "name", "position"], "title": "WorkbookTableOut", "type": "object"}, "MergeWorkbooksIn": {"properties": {"target": {"description": "Workbook identifier that keeps the sheets.", "title": "Target", "type": "string"}, "sources": {"description": "Workbook identifiers to fold into target.", "items": {"type": "string"}, "minItems": 1, "title": "Sources", "type": "array"}}, "required": ["target", "sources"], "title": "MergeWorkbooksIn", "type": "object"}, "RenameWorkbookIn": {"properties": {"name": {"maxLength": 128, "minLength": 1, "title": "Name", "type": "string"}}, "required": ["name"], "title": "RenameWorkbookIn", "type": "object"}, "AddWorkbookTableIn": {"properties": {"name": {"anyOf": [{"maxLength": 128, "type": "string"}, {"type": "null"}], "title": "Name"}}, "title": "AddWorkbookTableIn", "type": "object"}, "ReorderWorkbookTablesIn": {"properties": {"table_ids": {"items": {"format": "uuid", "type": "string"}, "minItems": 1, "title": "Table Ids", "type": "array"}}, "required": ["table_ids"], "title": "ReorderWorkbookTablesIn", "type": "object"}, "TrashItemOut": {"properties": {"kind": {"title": "Kind", "type": "string"}, "identifier": {"title": "Identifier", "type": "string"}, "name": {"title": "Name", "type": "string"}, "trashed_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Trashed At"}, "tables_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Tables Count"}, "workbook": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Workbook"}}, "required": ["kind", "identifier", "name"], "title": "TrashItemOut", "type": "object"}, "TrashActionIn": {"properties": {"workbooks": {"items": {"type": "string"}, "title": "Workbooks", "type": "array"}, "tables": {"items": {"format": "uuid", "type": "string"}, "title": "Tables", "type": "array"}}, "title": "TrashActionIn", "type": "object"}, "FlowDefCombinedOutputField": {"additionalProperties": false, "properties": {"id": {"minLength": 1, "title": "Id", "type": "string"}, "output_id": {"title": "Output Id", "type": "string"}, "path": {"default": "", "title": "Path", "type": "string"}}, "required": ["id", "output_id"], "title": "CombinedOutputField", "type": "object"}, "FlowDefConditionNode": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "string"}, "type": {"const": "condition", "default": "condition", "title": "Type", "type": "string"}, "label": {"default": "", "title": "Label", "type": "string"}, "on_error": {"default": "stop", "description": "What to do when formula evaluation raises an exception.", "enum": ["stop", "skip"], "title": "On Error", "type": "string"}, "data": {"$ref": "#/components/schemas/FlowDefConditionNodeData"}}, "required": ["id", "data"], "title": "ConditionNode", "type": "object"}, "FlowDefConditionNodeData": {"additionalProperties": false, "properties": {"inputs": {"description": "Values to expose as {{id}} variables inside the CEL formula.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef", "static_with_refs": "#/components/schemas/FlowDefStaticWithRefsInput"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}, {"$ref": "#/components/schemas/FlowDefStaticWithRefsInput"}]}, "title": "Inputs", "type": "array"}, "formula": {"description": "CEL expression using {{input_id}} references. E.g. '{{email}} != \"\"'.", "title": "Formula", "type": "string"}, "then_nodes": {"description": "Node ids to SKIP when formula evaluates to FALSE.", "items": {"type": "string"}, "title": "Then Nodes", "type": "array"}, "else_nodes": {"description": "Node ids to SKIP when formula evaluates to TRUE.", "items": {"type": "string"}, "title": "Else Nodes", "type": "array"}}, "required": ["formula"], "title": "ConditionNodeData", "type": "object"}, "FlowDefEnrichmentNode": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "string"}, "type": {"const": "enrichment", "default": "enrichment", "title": "Type", "type": "string"}, "label": {"default": "", "title": "Label", "type": "string"}, "on_error": {"default": "stop", "description": "What to do when the enrichment call fails: stop the whole run or skip this node.", "enum": ["stop", "skip"], "title": "On Error", "type": "string"}, "on_no_data": {"default": "stop", "description": "What to do when the enrichment returns no data: stop the run or skip this node.", "enum": ["stop", "skip"], "title": "On No Data", "type": "string"}, "data": {"$ref": "#/components/schemas/FlowDefEnrichmentNodeData"}}, "required": ["id", "data"], "title": "EnrichmentNode", "type": "object"}, "FlowDefEnrichmentNodeData": {"additionalProperties": false, "properties": {"enrichment_id": {"title": "Enrichment Id", "type": "integer"}, "authorization_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "description": "UserKey PK to use for this enrichment call. Omit to use the workspace default key.", "title": "Authorization Id"}, "inputs": {"description": "Input slot bindings: each item maps a param slug (id) to a source \u2014 function input, node output, or static value.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef", "static_with_refs": "#/components/schemas/FlowDefStaticWithRefsInput"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}, {"$ref": "#/components/schemas/FlowDefStaticWithRefsInput"}]}, "title": "Inputs", "type": "array"}, "outputs": {"description": "Node outputs (id + optional response_field_id); values from ResponseField or full response.", "items": {"$ref": "#/components/schemas/FlowDefOutputPort"}, "title": "Outputs", "type": "array"}}, "required": ["enrichment_id"], "title": "EnrichmentNodeData", "type": "object"}, "FlowDefFlowOutput": {"additionalProperties": false, "description": "Flow-level output mapping: reshape the run result into a custom shape.\n\nTwo mutually-exclusive modes:\n\n* :attr:`fields` \u2014 structured mapping. Each entry is a :data:`NodeInput`\n  whose ``id`` becomes the key in the returned ``outputs`` object.\n* :attr:`template` \u2014 a raw JSON string the user writes directly, with\n  ``{{ input.x }}`` / ``{{ nodes.id.port }}`` tokens resolved at runtime.\n  Supports arbitrary nested JSON, not just a flat object.\n\nWhen ``FlowDefinition.output`` is set, the executor returns the reshaped\nresult instead of the raw namespaced ``{node_id: {port: value}}`` dict.", "properties": {"fields": {"description": "Output field bindings; each `id` is the key in the returned outputs object.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef", "static_with_refs": "#/components/schemas/FlowDefStaticWithRefsInput"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}, {"$ref": "#/components/schemas/FlowDefStaticWithRefsInput"}]}, "title": "Fields", "type": "array"}, "template": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "description": "Raw JSON template with `{{ input.x }}` / `{{ nodes.id.port }}` tokens. Overrides `fields`.", "title": "Template"}}, "title": "FlowOutput", "type": "object"}, "FlowDefFlowOutputSource": {"additionalProperties": false, "properties": {"node_id": {"title": "Node Id", "type": "string"}, "ref": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": null, "title": "Ref"}}, "required": ["node_id"], "title": "FlowOutputSource", "type": "object"}, "FlowDefFunctionInput": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "string"}, "description": {"default": "", "title": "Description", "type": "string"}, "type": {"description": "Same vocabulary as RequestParam.type_data.", "title": "Type", "type": "string"}, "required": {"default": false, "description": "If true, input_bindings must include this id when attaching the function to a table.", "title": "Required", "type": "boolean"}}, "required": ["id"], "title": "FunctionInput", "type": "object"}, "FlowDefInputRef": {"additionalProperties": false, "description": "Binds a node input slot to a function-level input.", "properties": {"id": {"description": "Slot id (param slug on the enrichment dataset).", "title": "Id", "type": "string"}, "from": {"const": "function", "title": "From", "type": "string"}, "ref": {"description": "Id of the FunctionInput being referenced.", "title": "Ref", "type": "string"}}, "required": ["id", "from", "ref"], "title": "InputRef", "type": "object"}, "FlowDefJqNode": {"additionalProperties": false, "description": "Transform a JSON value using a jq expression.", "properties": {"id": {"title": "Id", "type": "string"}, "type": {"const": "jq", "default": "jq", "title": "Type", "type": "string"}, "label": {"default": "", "title": "Label", "type": "string"}, "on_error": {"default": "stop", "description": "What to do when the jq program raises: stop the run or skip this node.", "enum": ["stop", "skip"], "title": "On Error", "type": "string"}, "data": {"$ref": "#/components/schemas/FlowDefJqNodeData"}}, "required": ["id", "data"], "title": "JqNode", "type": "object"}, "FlowDefJqNodeData": {"additionalProperties": false, "description": "Data for a JQ transform node \u2014 runs a jq expression on one or more JSON inputs.", "properties": {"inputs": {"description": "Input slot bindings. Shape of the value passed to jq is controlled by ``input_shape``: ``value`` (legacy) passes a single input as-is; ``object`` always wraps bindings into ``{id: value, ...}``.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef", "static_with_refs": "#/components/schemas/FlowDefStaticWithRefsInput"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}, {"$ref": "#/components/schemas/FlowDefStaticWithRefsInput"}]}, "title": "Inputs", "type": "array"}, "expression": {"description": "jq program. With one input and input_shape ``value`` (the default), ``.`` is that input's value itself, so a text input is a plain string (e.g. '. | split(\" \")'); with ``object`` or several inputs, ``.`` is ``{slot_id: value, ...}`` (e.g. '.name' or '.items[] | select(.active)').", "title": "Expression", "type": "string"}, "outputs": {"description": "Exactly one output port, carrying the whole jq result. Downstream refs reach into it by path (`<port>.field.sub`).", "items": {"$ref": "#/components/schemas/FlowDefOutputPort"}, "title": "Outputs", "type": "array"}, "input_shape": {"default": "value", "description": "How inputs are assembled for jq. ``value``: single input passed as-is (legacy). ``object``: always ``{slot_id: value, ...}``.", "enum": ["value", "object"], "title": "Input Shape", "type": "string"}}, "required": ["expression"], "title": "JqNodeData", "type": "object"}, "FlowDefMathFunctionNode": {"additionalProperties": false, "description": "Evaluate an arithmetic expression with SymPy (Math Function tool).", "properties": {"id": {"title": "Id", "type": "string"}, "type": {"const": "math_function", "default": "math_function", "title": "Type", "type": "string"}, "label": {"default": "", "title": "Label", "type": "string"}, "on_error": {"default": "stop", "enum": ["stop", "skip"], "title": "On Error", "type": "string"}, "data": {"$ref": "#/components/schemas/FlowDefMathFunctionNodeData"}}, "required": ["id", "data"], "title": "MathFunctionNode", "type": "object"}, "FlowDefMathFunctionNodeData": {"additionalProperties": false, "description": "Data for a Math Function node \u2014 evaluates a SymPy arithmetic expression.", "properties": {"inputs": {"description": "Input slot bindings; each binding's 'id' must match a symbol name in the expression. E.g. id='price', value=upstream node output \u2192 used as 'price' in the formula.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef", "static_with_refs": "#/components/schemas/FlowDefStaticWithRefsInput"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}, {"$ref": "#/components/schemas/FlowDefStaticWithRefsInput"}]}, "title": "Inputs", "type": "array"}, "expression": {"description": "SymPy-compatible arithmetic expression, e.g. 'price * 0.9' or 'a + b / 2'.", "title": "Expression", "type": "string"}, "outputs": {"description": "Exactly one output port, carrying the numeric result as a string.", "items": {"$ref": "#/components/schemas/FlowDefOutputPort"}, "title": "Outputs", "type": "array"}}, "required": ["expression"], "title": "MathFunctionNodeData", "type": "object"}, "FlowDefMergeNode": {"additionalProperties": false, "description": "Concatenate multiple string inputs into a single value.", "properties": {"id": {"title": "Id", "type": "string"}, "type": {"const": "merge", "default": "merge", "title": "Type", "type": "string"}, "label": {"default": "", "title": "Label", "type": "string"}, "on_error": {"default": "stop", "enum": ["stop", "skip"], "title": "On Error", "type": "string"}, "data": {"$ref": "#/components/schemas/FlowDefMergeNodeData"}}, "required": ["id", "data"], "title": "MergeNode", "type": "object"}, "FlowDefMergeNodeData": {"additionalProperties": false, "description": "Data for a merge/concatenate node.", "properties": {"inputs": {"description": "Input slot bindings to concatenate in order; empty/null values are skipped.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef", "static_with_refs": "#/components/schemas/FlowDefStaticWithRefsInput"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}, {"$ref": "#/components/schemas/FlowDefStaticWithRefsInput"}]}, "title": "Inputs", "type": "array"}, "separator": {"default": "", "description": "String inserted between non-empty parts, e.g. ' ' or ', '.", "title": "Separator", "type": "string"}, "outputs": {"description": "Exactly one output port, carrying the merged string.", "items": {"$ref": "#/components/schemas/FlowDefOutputPort"}, "title": "Outputs", "type": "array"}}, "title": "MergeNodeData", "type": "object"}, "FlowDefNamedFlowOutput": {"additionalProperties": false, "properties": {"id": {"pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$", "title": "Id", "type": "string"}, "key": {"pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$", "title": "Key", "type": "string"}, "name": {"maxLength": 200, "minLength": 1, "title": "Name", "type": "string"}, "source": {"anyOf": [{"$ref": "#/components/schemas/FlowDefFlowOutputSource"}, {"type": "null"}], "default": null}, "mapping": {"anyOf": [{"$ref": "#/components/schemas/FlowDefFlowOutput"}, {"type": "null"}], "default": null}, "combine": {"items": {"type": "string"}, "title": "Combine", "type": "array"}, "combine_fields": {"items": {"$ref": "#/components/schemas/FlowDefCombinedOutputField"}, "title": "Combine Fields", "type": "array"}}, "required": ["id", "key", "name"], "title": "NamedFlowOutput", "type": "object"}, "FlowDefNodeRef": {"additionalProperties": false, "description": "Binds a node input slot to an output of another node.", "properties": {"id": {"description": "Slot id (param slug on the enrichment dataset).", "title": "Id", "type": "string"}, "from": {"const": "node", "title": "From", "type": "string"}, "node_id": {"title": "Node Id", "type": "string"}, "ref": {"description": "OutputPort.id on the referenced node.", "title": "Ref", "type": "string"}}, "required": ["id", "from", "node_id", "ref"], "title": "NodeRef", "type": "object"}, "FlowDefOutputPort": {"additionalProperties": false, "properties": {"id": {"description": "Stable output id; referenced by NodeRef.ref.", "title": "Id", "type": "string"}, "response_field_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "description": "Primary key of a ResponseField on this enrichment's dataset. Server applies that field's expression_json to the raw API response. Omit or null to bind the whole response object to this port.", "title": "Response Field Id"}}, "required": ["id"], "title": "OutputPort", "type": "object"}, "FlowDefStaticRef": {"additionalProperties": false, "description": "Binds a node input slot to a hardcoded value.", "properties": {"id": {"description": "Slot id (param slug on the enrichment dataset).", "title": "Id", "type": "string"}, "from": {"const": "static", "title": "From", "type": "string"}, "value": {"description": "Hardcoded string value passed directly to the enrichment param.", "title": "Value", "type": "string"}}, "required": ["id", "from", "value"], "title": "StaticRef", "type": "object"}, "FlowDefStaticWithRefsInput": {"additionalProperties": false, "description": "Binds a node input slot to a template string with ``{ref_id}`` substitutions.\n\nUsed for prompt-text style fields where the resolved value is a literal with\nreferences interpolated inline, e.g. ``\"Tell me about {company}\"`` where\n``company`` is a nested ref to a function input or upstream node output.\n\nTokens supported:\n\n* ``{name}`` \u2014 required ref; raises ``ValueError`` if no matching entry in\n  :attr:`refs` resolves to a value (i.e. the ref is missing or the upstream\n  port is unset). An unmatched name that equals a function input id is\n  treated as that input (MCP/UI often persist ``{domain}`` with empty refs).\n* ``{?name}`` \u2014 optional ref; falls back to ``\"\"`` when missing.\n\nThe token character set matches the table-side rich editor\n(``[a-zA-Z0-9_.]``) so prompts copied from a table workflow keep working.", "properties": {"id": {"description": "Slot id (param slug on the enrichment dataset).", "title": "Id", "type": "string"}, "from": {"const": "static_with_refs", "title": "From", "type": "string"}, "template": {"description": "Template string with `{ref_id}` (required) or `{?ref_id}` (optional) placeholders.", "title": "Template", "type": "string"}, "refs": {"description": "Refs to substitute into the template. Each `ref.id` matches a `{ref.id}` placeholder.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}]}, "title": "Refs", "type": "array"}}, "required": ["id", "from", "template"], "title": "StaticWithRefsInput", "type": "object"}, "FlowDefTableLookupNode": {"additionalProperties": false, "description": "Query another Databar table and return matching rows as JSON.", "properties": {"id": {"title": "Id", "type": "string"}, "type": {"const": "table_lookup", "default": "table_lookup", "title": "Type", "type": "string"}, "label": {"default": "", "title": "Label", "type": "string"}, "on_error": {"default": "stop", "enum": ["stop", "skip"], "title": "On Error", "type": "string"}, "data": {"$ref": "#/components/schemas/FlowDefTableLookupNodeData"}}, "required": ["id", "data"], "title": "TableLookupNode", "type": "object"}, "FlowDefTableLookupNodeData": {"additionalProperties": false, "description": "Data for a table-lookup node \u2014 queries another Databar table.", "properties": {"lookup_table": {"description": "UUID (identifier) of the target table to query.", "title": "Lookup Table", "type": "string"}, "lookup_column": {"description": "UUID (identifier) of the column in the lookup table to filter on.", "title": "Lookup Column", "type": "string"}, "operator": {"default": "equals", "description": "Filter operator: 'equals' (exact match) or 'contains' (case-insensitive substring).", "title": "Operator", "type": "string"}, "inputs": {"description": "The search value binding. The first input's resolved value is used as the lookup value.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef", "static_with_refs": "#/components/schemas/FlowDefStaticWithRefsInput"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}, {"$ref": "#/components/schemas/FlowDefStaticWithRefsInput"}]}, "title": "Inputs", "type": "array"}, "outputs": {"description": "Exactly one output port, carrying the JSON list of matching rows. Downstream refs reach into it by path (`<port>.0.column`).", "items": {"$ref": "#/components/schemas/FlowDefOutputPort"}, "title": "Outputs", "type": "array"}}, "required": ["lookup_table", "lookup_column"], "title": "TableLookupNodeData", "type": "object"}, "FlowDefWaterfallNode": {"additionalProperties": false, "description": "Run a multi-provider waterfall enrichment pipeline.", "properties": {"id": {"title": "Id", "type": "string"}, "type": {"const": "waterfall", "default": "waterfall", "title": "Type", "type": "string"}, "label": {"default": "", "title": "Label", "type": "string"}, "on_error": {"default": "stop", "description": "What to do when the waterfall fails: stop the run or skip this node.", "enum": ["stop", "skip"], "title": "On Error", "type": "string"}, "on_no_data": {"default": "stop", "description": "What to do when no provider returns data: stop the run or skip this node.", "enum": ["stop", "skip"], "title": "On No Data", "type": "string"}, "data": {"$ref": "#/components/schemas/FlowDefWaterfallNodeData"}}, "required": ["id", "data"], "title": "WaterfallNode", "type": "object"}, "FlowDefWaterfallNodeData": {"additionalProperties": false, "description": "Data for a waterfall node \u2014 runs ordered enrichments until one succeeds.", "properties": {"waterfall_identifier": {"description": "Stable slug of the waterfall script, e.g. 'email_getter'.", "title": "Waterfall Identifier", "type": "string"}, "enrichments": {"description": "Ordered enrichment ids to try. Empty list uses the script's default cascade, omitting providers hidden by default.", "items": {"type": "integer"}, "title": "Enrichments", "type": "array"}, "email_verifier_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null, "description": "Optional email-verifier enrichment id for verifying waterfalls.", "title": "Email Verifier Id"}, "per_enrichment_authorization": {"anyOf": [{"additionalProperties": {"type": "integer"}, "type": "object"}, {"type": "null"}], "default": null, "description": "Map of enrichment_id \u2192 UserKey PK for per-provider API keys.", "title": "Per Enrichment Authorization"}, "inputs": {"description": "Input slot bindings; each id is a waterfall Param name.", "items": {"discriminator": {"mapping": {"function": "#/components/schemas/FlowDefInputRef", "node": "#/components/schemas/FlowDefNodeRef", "static": "#/components/schemas/FlowDefStaticRef", "static_with_refs": "#/components/schemas/FlowDefStaticWithRefsInput"}, "propertyName": "from"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefInputRef"}, {"$ref": "#/components/schemas/FlowDefNodeRef"}, {"$ref": "#/components/schemas/FlowDefStaticRef"}, {"$ref": "#/components/schemas/FlowDefStaticWithRefsInput"}]}, "title": "Inputs", "type": "array"}, "outputs": {"description": "Output ports; each id is a waterfall Result name. response_field_id is unused for waterfall nodes.", "items": {"$ref": "#/components/schemas/FlowDefOutputPort"}, "title": "Outputs", "type": "array"}}, "required": ["waterfall_identifier"], "title": "WaterfallNodeData", "type": "object"}, "FlowDefinition": {"additionalProperties": false, "properties": {"inputs": {"items": {"$ref": "#/components/schemas/FlowDefFunctionInput"}, "title": "Inputs", "type": "array"}, "nodes": {"items": {"discriminator": {"mapping": {"condition": "#/components/schemas/FlowDefConditionNode", "enrichment": "#/components/schemas/FlowDefEnrichmentNode", "jq": "#/components/schemas/FlowDefJqNode", "math_function": "#/components/schemas/FlowDefMathFunctionNode", "merge": "#/components/schemas/FlowDefMergeNode", "table_lookup": "#/components/schemas/FlowDefTableLookupNode", "waterfall": "#/components/schemas/FlowDefWaterfallNode"}, "propertyName": "type"}, "oneOf": [{"$ref": "#/components/schemas/FlowDefEnrichmentNode"}, {"$ref": "#/components/schemas/FlowDefConditionNode"}, {"$ref": "#/components/schemas/FlowDefJqNode"}, {"$ref": "#/components/schemas/FlowDefMergeNode"}, {"$ref": "#/components/schemas/FlowDefMathFunctionNode"}, {"$ref": "#/components/schemas/FlowDefTableLookupNode"}, {"$ref": "#/components/schemas/FlowDefWaterfallNode"}]}, "title": "Nodes", "type": "array"}, "named_outputs": {"anyOf": [{"items": {"$ref": "#/components/schemas/FlowDefNamedFlowOutput"}, "maxItems": 64, "minItems": 1, "type": "array"}, {"type": "null"}], "default": null, "title": "Named Outputs"}, "output": {"anyOf": [{"$ref": "#/components/schemas/FlowDefFlowOutput"}, {"type": "null"}], "default": null, "description": "Optional flow-level output mapping. When set, run results expose `outputs` as `{field_id: value}` instead of the namespaced node ports."}}, "required": ["nodes"], "title": "FlowDefinition", "type": "object"}}, "securitySchemes": {"UserTokenAuth": {"type": "apiKey", "in": "header", "name": "x-apikey"}}}, "servers": []}