Skip to Content

Models API

Models are SQL-defined datasets that sit between sources and syncs. A model runs a SQL query against a source to shape the data you want to sync, build audiences from, or define traits on.

Endpoints

MethodPathDescription
GET/api/v1/workspaces/{id}/modelsList all models
POST/api/v1/workspaces/{id}/modelsCreate a model
GET/api/v1/workspaces/{id}/models/{modelId}Get a model
PUT/api/v1/workspaces/{id}/models/{modelId}Update a model
DELETE/api/v1/workspaces/{id}/models/{modelId}Delete a model
POST/api/v1/workspaces/{id}/models/previewPreview query results
POST/api/v1/workspaces/{id}/models/preview-tablePreview table data
POST/api/v1/workspaces/{id}/models/{modelId}/refresh-suggestionsRefresh value suggestions
GET/api/v1/workspaces/{id}/sources/{sourceId}/schemasList schemas
GET/api/v1/workspaces/{id}/sources/{sourceId}/schemas/{schema}/tablesList tables
GET/api/v1/workspaces/{id}/sources/{sourceId}/schemas/{schema}/tables/{table}/columnsList columns

List Models

GET /api/v1/workspaces/{id}/models

Returns all models in the workspace.

Response

[ { "id": "550e8400-e29b-41d4-a716-446655440000", "workspace_id": "660e8400-e29b-41d4-a716-446655440000", "source_id": "770e8400-e29b-41d4-a716-446655440000", "name": "Active Customers", "description": "Customers with purchases in the last 90 days", "sql_query": "SELECT customer_id, email, first_name, last_name FROM customers WHERE last_purchase_date > DATEADD(day, -90, CURRENT_DATE())", "columns": [ {"name": "customer_id", "type": "VARCHAR", "nullable": false}, {"name": "email", "type": "VARCHAR", "nullable": true}, {"name": "first_name", "type": "VARCHAR", "nullable": true}, {"name": "last_name", "type": "VARCHAR", "nullable": true} ], "entity_type": "parent", "primary_key_column": "customer_id", "timestamp_column": "", "column_config": [...], "model_type": "sql", "source_schema": "", "source_table": "", "selected_columns": null, "status": "active", "status_error": "", "created_by": "880e8400-e29b-41d4-a716-446655440000", "created_at": "2024-01-15T09:30:00Z", "updated_at": "2024-01-15T09:30:00Z" } ]

Example

curl -X GET https://agentic.zeotap.com/api/v1/workspaces/{id}/models \ -H "Authorization: Bearer <token>" \ -H "X-Workspace-ID: <workspace-id>"

Create Model

POST /api/v1/workspaces/{id}/models

Creates a new model. Models can be either SQL-based (sql type) or table selectors (table_selector type).

Request Body

FieldTypeRequiredDescription
namestringYesDisplay name
descriptionstringNoDescription of the model’s purpose
source_idstring (UUID)YesSource to query against
sql_querystringYes (for sql type)SQL query to execute
model_typestringNosql (default) or table_selector
source_schemastringFor table_selectorSchema name for table selector
source_tablestringFor table_selectorTable name for table selector
selected_columnsarrayFor table_selectorColumns to include
primary_key_columnstringNoColumn to use as primary key
timestamp_columnstringNoColumn for incremental sync tracking
entity_typestringNoparent, related, or event (for schema module)
column_configarrayNoPer-column audience builder settings

SQL Model Example

{ "name": "Active Customers", "description": "Customers with purchases in the last 90 days", "source_id": "770e8400-e29b-41d4-a716-446655440000", "sql_query": "SELECT customer_id, email, first_name, last_name, lifetime_value FROM customers WHERE last_purchase_date > DATEADD(day, -90, CURRENT_DATE())", "primary_key_column": "customer_id", "entity_type": "parent" }

Table Selector Example

{ "name": "Orders Table", "source_id": "770e8400-e29b-41d4-a716-446655440000", "model_type": "table_selector", "source_schema": "PUBLIC", "source_table": "ORDERS", "selected_columns": ["order_id", "customer_id", "total", "created_at"], "primary_key_column": "order_id", "entity_type": "event" }

Response

Returns the created model with status 201 Created.

Example

curl -X POST https://agentic.zeotap.com/api/v1/workspaces/{id}/models \ -H "Authorization: Bearer <token>" \ -H "X-Workspace-ID: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{ "name": "Active Customers", "source_id": "770e8400-e29b-41d4-a716-446655440000", "sql_query": "SELECT customer_id, email, first_name FROM customers", "primary_key_column": "customer_id", "entity_type": "parent" }'

Get Model

GET /api/v1/workspaces/{id}/models/{modelId}

Returns a single model by ID.

Example

curl -X GET https://agentic.zeotap.com/api/v1/workspaces/{id}/models/{modelId} \ -H "Authorization: Bearer <token>" \ -H "X-Workspace-ID: <workspace-id>"

Update Model

PUT /api/v1/workspaces/{id}/models/{modelId}

Updates an existing model. You can modify the query, columns, entity type, and other configuration.

Request Body

Same fields as create. Only include fields you want to change.

Example

curl -X PUT https://agentic.zeotap.com/api/v1/workspaces/{id}/models/{modelId} \ -H "Authorization: Bearer <token>" \ -H "X-Workspace-ID: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{ "name": "Active Customers (Updated)", "sql_query": "SELECT customer_id, email, first_name, last_name, ltv FROM customers WHERE status = '\''active'\''" }'

Delete Model

DELETE /api/v1/workspaces/{id}/models/{modelId}

Deletes a model. The model cannot be deleted if it has active syncs, audiences, or traits depending on it.

Response

{ "status": "deleted" }

Example

curl -X DELETE https://agentic.zeotap.com/api/v1/workspaces/{id}/models/{modelId} \ -H "Authorization: Bearer <token>" \ -H "X-Workspace-ID: <workspace-id>"

Preview Query Results

POST /api/v1/workspaces/{id}/models/preview

Executes a SQL query against a source and returns sample rows and column metadata. Use this to validate queries before saving a model.

Request Body

FieldTypeRequiredDescription
source_idstring (UUID)YesSource to query against
sql_querystringYesSQL query to preview
{ "source_id": "770e8400-e29b-41d4-a716-446655440000", "sql_query": "SELECT customer_id, email, first_name FROM customers LIMIT 10" }

Response

{ "columns": [ {"name": "customer_id", "type": "VARCHAR", "nullable": false}, {"name": "email", "type": "VARCHAR", "nullable": true}, {"name": "first_name", "type": "VARCHAR", "nullable": true} ], "rows": [ {"customer_id": "C001", "email": "alice@example.com", "first_name": "Alice"}, {"customer_id": "C002", "email": "bob@example.com", "first_name": "Bob"} ] }

Example

curl -X POST https://agentic.zeotap.com/api/v1/workspaces/{id}/models/preview \ -H "Authorization: Bearer <token>" \ -H "X-Workspace-ID: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{ "source_id": "770e8400-e29b-41d4-a716-446655440000", "sql_query": "SELECT customer_id, email FROM customers LIMIT 10" }'

Preview Table

POST /api/v1/workspaces/{id}/models/preview-table

Previews data from a specific table without writing a SQL query. Used by the table selector model type.

Request Body

FieldTypeRequiredDescription
source_idstring (UUID)YesSource to query against
schemastringYesSchema name
tablestringYesTable name
{ "source_id": "770e8400-e29b-41d4-a716-446655440000", "schema": "PUBLIC", "table": "CUSTOMERS" }

Response

Same format as preview query results.


Refresh Value Suggestions

POST /api/v1/workspaces/{id}/models/{modelId}/refresh-suggestions

Re-scans the model’s data to update the value_suggestions in the column configuration. These stored suggestions back the audience builder’s value dropdowns whenever a live per-column lookup has nothing to show.

A refresh runs one query per suggestable column, so it is bounded:

  • One refresh per model at a time. A request made while a refresh of the same model is running does not start a second one.
  • Time limits. Each column query is limited to 60 seconds and a whole refresh to about 5 minutes. A refresh that stops early keeps what it found, and next time starts with the columns it scanned longest ago.

By default the endpoint always re-scans. Automatic callers, such as the audience builder refreshing a model when it opens, pass background=true. Background requests are also skipped when:

  • the model was refreshed within the last hour, or within 10 minutes of a refresh that stopped early;
  • the model’s warehouse source is already running two refreshes.

Query parameters

ParameterTypeDescription
backgroundbooleanMark the refresh as automatic. It is skipped under the conditions above instead of running. Must be true or false; defaults to false.

Response

Returns the model object with its column_config. When a background refresh was skipped, the model is returned as currently stored.

The X-Value-Suggestions-Refresh response header reports what happened: completed, partial, failed, skipped_in_progress, skipped_recent or skipped_source_busy.

Without background=true, a request made while a refresh of the same model is already running returns 409 Conflict with an explanatory error message.


Schema Discovery

These endpoints allow you to browse the schemas, tables, and columns available in a source warehouse.

List Schemas

GET /api/v1/workspaces/{id}/sources/{sourceId}/schemas

["PUBLIC", "RAW", "ANALYTICS"]

List Tables

GET /api/v1/workspaces/{id}/sources/{sourceId}/schemas/{schema}/tables

["CUSTOMERS", "ORDERS", "PRODUCTS"]

List Columns

GET /api/v1/workspaces/{id}/sources/{sourceId}/schemas/{schema}/tables/{table}/columns

Returns column metadata for a specific table.


Model Object

FieldTypeDescription
idstring (UUID)Unique identifier
workspace_idstring (UUID)Owning workspace
source_idstring (UUID)Source this model queries
namestringDisplay name
descriptionstringDescription of the model
sql_querystringSQL query (for sql type models)
columnsarrayDiscovered columns (name, type, nullable)
entity_typestringparent, related, event, or empty
primary_key_columnstringColumn used as the primary key
timestamp_columnstringColumn used for incremental sync tracking
column_configarrayPer-column audience builder settings
model_typestringsql or table_selector
source_schemastringSchema name (for table_selector type)
source_tablestringTable name (for table_selector type)
selected_columnsarraySelected columns (for table_selector type)
statusstringdraft, active, or error
status_errorstringError message when status is error
created_bystring (UUID)Account that created the model
created_atstring (ISO 8601)Creation timestamp
updated_atstring (ISO 8601)Last update timestamp

Column Config Entry

FieldTypeDescription
namestringColumn name
aliasstringDisplay alias for the audience builder
enabledbooleanWhether this column is available in the audience builder
data_typestringData type classification
value_suggestionsarray of stringsSample values for dropdown menus
Last updated on