Skip to content

API: Shared schemas

These shapes are defined once, in the shared contracts package the api, the web app and the pipelines worker all build against, and exported as JSON Schema (draft 2020-12). Response schemas describe what the api sends; request schemas describe what it accepts.

The resolved product entitlements for the caller (GET /api/entitlements).

Used by: GET /api/entitlements (response)

Field Type Required Description
bi object yes BI is always licensed; the tier sets its feature level.
bi.tier "team" | "business" | "enterprise" yes BI tier. enterprise comes only from a licence file.
pipelines object yes Licensed by the licence, an active trial grant, or a plan row.
pipelines.licensed boolean yes
warehouse object yes Licensed by the licence, an active trial grant, or a plan row.
warehouse.licensed boolean yes
trialGrants map of string, keyed by bi, pipelines, warehouse yes Product key to the YYYY-MM-DD date its trial grant expires (inclusive, UTC). Expired grants stay listed.
availability object no The operator’s product switches (platform default + company override), apart from the plan, so an app can say “turned off for your company” rather than “not on your plan”. Set by GET /api/entitlements; absent from licence-derived snapshots.
availability.pipelines boolean yes
availability.warehouse boolean yes
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "EntitlementSnapshot",
"type": "object",
"properties": {
"bi": {
"type": "object",
"properties": {
"tier": {
"type": "string",
"enum": [
"team",
"business",
"enterprise"
],
"description": "BI tier. `enterprise` comes only from a licence file."
}
},
"required": [
"tier"
],
"additionalProperties": false,
"description": "BI is always licensed; the tier sets its feature level."
},
"pipelines": {
"default": {
"licensed": false
},
"description": "Licensed by the licence, an active trial grant, or a plan row.",
"type": "object",
"properties": {
"licensed": {
"type": "boolean"
}
},
"required": [
"licensed"
],
"additionalProperties": false
},
"warehouse": {
"default": {
"licensed": false
},
"description": "Licensed by the licence, an active trial grant, or a plan row.",
"type": "object",
"properties": {
"licensed": {
"type": "boolean"
}
},
"required": [
"licensed"
],
"additionalProperties": false
},
"trialGrants": {
"default": {},
"description": "Product key to the YYYY-MM-DD date its trial grant expires (inclusive, UTC). Expired grants stay listed.",
"type": "object",
"propertyNames": {
"type": "string",
"enum": [
"bi",
"pipelines",
"warehouse"
]
},
"additionalProperties": {
"type": "string"
}
},
"availability": {
"description": "The operator's product switches (platform default + company override), apart from the plan, so an app can say \"turned off for your company\" rather than \"not on your plan\". Set by GET /api/entitlements; absent from licence-derived snapshots.",
"type": "object",
"properties": {
"pipelines": {
"type": "boolean"
},
"warehouse": {
"type": "boolean"
}
},
"required": [
"pipelines",
"warehouse"
],
"additionalProperties": false
}
},
"required": [
"bi",
"pipelines",
"warehouse",
"trialGrants"
],
"additionalProperties": false,
"description": "The resolved product entitlements for the caller (GET /api/entitlements)."
}

Per-product usage against plan allowances for one workspace (GET /api/usage/products).

Used by: GET /api/usage/products (response)

Field Type Required Description
month string yes ‘YYYY-MM’ (UTC): the period the usage numbers cover.
workspace_id string yes The workspace the cards describe.
products object yes
products.pipelines object yes The Pipelines usage card.
products.pipelines.licensed boolean yes
products.pipelines.planKey string | null yes The plan row that grants this product, or null without one.
products.pipelines.overageOptIn boolean | null yes Metered overage consent on that plan row. false = hard cap at the allowance (the default).
products.pipelines.draft boolean | null yes The plan’s pricing is still provisional (plans.config.draft).
products.pipelines.allowance object | null yes null = no plan row, uncapped.
products.pipelines.allowance.execution_hours number | null yes
products.pipelines.allowance.execution_seconds number | null yes execution_hours × 3600, the unit the cap compares.
products.pipelines.currentPeriod object yes Month to date: settled ledger days plus a live read of the last two days.
products.pipelines.currentPeriod.execution_seconds number yes
products.pipelines.currentPeriod.rows_moved number yes
products.pipelines.currentPeriod.bytes_moved number yes
products.pipelines.currentPeriod.runs number yes
products.warehouse object yes The Warehouse usage card.
products.warehouse.licensed boolean yes
products.warehouse.planKey string | null yes The plan row that grants this product, or null without one.
products.warehouse.overageOptIn boolean | null yes Metered overage consent on that plan row. false = hard cap at the allowance (the default).
products.warehouse.draft boolean | null yes The plan’s pricing is still provisional (plans.config.draft).
products.warehouse.allowance object | null yes null = no plan row, uncapped.
products.warehouse.allowance.storage_gb number | null yes
products.warehouse.allowance.storage_bytes number | null yes storage_gb × 1024³.
products.warehouse.currentPeriod object yes Month to date.
products.warehouse.currentPeriod.storage_bytes number yes The month’s storage peak: the metered figure.
products.warehouse.currentPeriod.storage_bytes_current number yes What is stored right now.
products.warehouse.currentPeriod.datasets number yes
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "ProductUsage",
"type": "object",
"properties": {
"month": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}$",
"description": "'YYYY-MM' (UTC): the period the usage numbers cover."
},
"workspace_id": {
"type": "string",
"description": "The workspace the cards describe."
},
"products": {
"type": "object",
"properties": {
"pipelines": {
"type": "object",
"properties": {
"licensed": {
"type": "boolean"
},
"planKey": {
"description": "The plan row that grants this product, or null without one.",
"type": [
"string",
"null"
]
},
"overageOptIn": {
"description": "Metered overage consent on that plan row. false = hard cap at the allowance (the default).",
"type": [
"boolean",
"null"
]
},
"draft": {
"description": "The plan's pricing is still provisional (plans.config.draft).",
"type": [
"boolean",
"null"
]
},
"allowance": {
"anyOf": [
{
"type": "object",
"properties": {
"execution_hours": {
"type": [
"number",
"null"
]
},
"execution_seconds": {
"description": "execution_hours × 3600, the unit the cap compares.",
"type": [
"number",
"null"
]
}
},
"required": [
"execution_hours",
"execution_seconds"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "null = no plan row, uncapped."
},
"currentPeriod": {
"type": "object",
"properties": {
"execution_seconds": {
"type": "number"
},
"rows_moved": {
"type": "number"
},
"bytes_moved": {
"type": "number"
},
"runs": {
"type": "number"
}
},
"required": [
"execution_seconds",
"rows_moved",
"bytes_moved",
"runs"
],
"additionalProperties": false,
"description": "Month to date: settled ledger days plus a live read of the last two days."
}
},
"required": [
"licensed",
"planKey",
"overageOptIn",
"draft",
"allowance",
"currentPeriod"
],
"additionalProperties": false,
"description": "The Pipelines usage card."
},
"warehouse": {
"type": "object",
"properties": {
"licensed": {
"type": "boolean"
},
"planKey": {
"description": "The plan row that grants this product, or null without one.",
"type": [
"string",
"null"
]
},
"overageOptIn": {
"description": "Metered overage consent on that plan row. false = hard cap at the allowance (the default).",
"type": [
"boolean",
"null"
]
},
"draft": {
"description": "The plan's pricing is still provisional (plans.config.draft).",
"type": [
"boolean",
"null"
]
},
"allowance": {
"anyOf": [
{
"type": "object",
"properties": {
"storage_gb": {
"type": [
"number",
"null"
]
},
"storage_bytes": {
"description": "storage_gb × 1024³.",
"type": [
"number",
"null"
]
}
},
"required": [
"storage_gb",
"storage_bytes"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "null = no plan row, uncapped."
},
"currentPeriod": {
"type": "object",
"properties": {
"storage_bytes": {
"type": "number",
"description": "The month's storage peak: the metered figure."
},
"storage_bytes_current": {
"type": "number",
"description": "What is stored right now."
},
"datasets": {
"type": "number"
}
},
"required": [
"storage_bytes",
"storage_bytes_current",
"datasets"
],
"additionalProperties": false,
"description": "Month to date."
}
},
"required": [
"licensed",
"planKey",
"overageOptIn",
"draft",
"allowance",
"currentPeriod"
],
"additionalProperties": false,
"description": "The Warehouse usage card."
}
},
"required": [
"pipelines",
"warehouse"
],
"additionalProperties": false
}
},
"required": [
"month",
"workspace_id",
"products"
],
"additionalProperties": false,
"description": "Per-product usage against plan allowances for one workspace (GET /api/usage/products)."
}

A pipeline definition: the dag field of POST /api/pipelines and PATCH /api/pipelines/{id}. Each step’s config is checked against its step type by validateDag, beyond this envelope.

Used by: POST /api/pipelines (dag in the request body) · PATCH /api/pipelines/{id} (dag in the request body)

Field Type Required Description
version 1 yes
steps array of object yes
steps[].id string yes
steps[].type "extract" | "load" | "transform_sql" | "transform_code" | "route" yes
steps[].config map of object yes
steps[].dependsOn array of string no
steps[].fromPorts map of string no
steps[].retry object no
steps[].retry.maxAttempts integer no
steps[].retry.initialIntervalMs integer no
steps[].retry.backoffCoefficient number no
steps[].retry.nonRetryableErrors array of string no
steps[].when object no
steps[].when.param string yes
steps[].when.op "eq" | "ne" | "in" | "not_in" | "truthy" | "falsy" yes
steps[].when.value one of 2 shapes no
schedule object no
schedule.cron string no
schedule.everySeconds integer no
schedule.timezone string no
schedule.enabled boolean no
trigger one of 3 shapes no
concurrency object no
concurrency.maxConcurrentRuns integer no
concurrency.onOverlap "skip" | "queue" | "cancel_previous" no
parameters array of object no
parameters[].name string yes
parameters[].type "string" | "number" | "boolean" | "list" yes
parameters[].default one of 2 shapes no
parameters[].required boolean no
parameters[].description string no
forEach array of object no
forEach[].id string yes
forEach[].items one of 2 shapes yes
forEach[].steps array of string yes
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "PipelineDag",
"description": "A pipeline definition: the `dag` field of POST /api/pipelines and PATCH /api/pipelines/{id}. Each step's `config` is checked against its step type by validateDag, beyond this envelope.",
"type": "object",
"properties": {
"version": {
"type": "number",
"const": 1
},
"steps": {
"minItems": 1,
"maxItems": 100,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$"
},
"type": {
"type": "string",
"enum": [
"extract",
"load",
"transform_sql",
"transform_code",
"route"
]
},
"config": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"dependsOn": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"fromPorts": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": {
"default": 3,
"type": "integer",
"minimum": 1,
"maximum": 10
},
"initialIntervalMs": {
"default": 1000,
"type": "integer",
"minimum": 100,
"maximum": 9007199254740991
},
"backoffCoefficient": {
"default": 2,
"type": "number",
"minimum": 1
},
"nonRetryableErrors": {
"default": [],
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
},
"when": {
"type": "object",
"properties": {
"param": {
"type": "string",
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"
},
"op": {
"type": "string",
"enum": [
"eq",
"ne",
"in",
"not_in",
"truthy",
"falsy"
]
},
"value": {
"anyOf": [
{
"anyOf": [
{
"type": "string",
"maxLength": 1024
},
{
"type": "number"
},
{
"type": "boolean"
}
]
},
{
"minItems": 1,
"maxItems": 100,
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"maxLength": 1024
},
{
"type": "number"
},
{
"type": "boolean"
}
]
}
}
]
}
},
"required": [
"param",
"op"
],
"additionalProperties": false
}
},
"required": [
"id",
"type",
"config"
],
"additionalProperties": false
}
},
"schedule": {
"type": "object",
"properties": {
"cron": {
"type": "string",
"minLength": 1
},
"everySeconds": {
"type": "integer",
"minimum": 15,
"maximum": 86400
},
"timezone": {
"default": "UTC",
"type": "string"
},
"enabled": {
"default": true,
"type": "boolean"
}
},
"additionalProperties": false
},
"trigger": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"const": "file_arrival"
},
"sourceId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"path": {
"type": "string",
"minLength": 1,
"maxLength": 1024
},
"quietSeconds": {
"default": 60,
"type": "integer",
"minimum": 0,
"maximum": 3600
},
"minFiles": {
"default": 1,
"type": "integer",
"minimum": 1,
"maximum": 10000
}
},
"required": [
"kind",
"sourceId",
"path"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"const": "pipeline"
},
"pipelineId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"on": {
"default": "success",
"type": "string",
"enum": [
"success",
"completion"
]
}
},
"required": [
"kind",
"pipelineId"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"const": "webhook"
}
},
"required": [
"kind"
],
"additionalProperties": false
}
]
},
"concurrency": {
"default": {
"maxConcurrentRuns": 1,
"onOverlap": "skip"
},
"type": "object",
"properties": {
"maxConcurrentRuns": {
"default": 1,
"type": "integer",
"minimum": 1,
"maximum": 10
},
"onOverlap": {
"default": "skip",
"type": "string",
"enum": [
"skip",
"queue",
"cancel_previous"
]
}
},
"additionalProperties": false
},
"parameters": {
"maxItems": 50,
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"
},
"type": {
"type": "string",
"enum": [
"string",
"number",
"boolean",
"list"
]
},
"default": {
"anyOf": [
{
"anyOf": [
{
"type": "string",
"maxLength": 1024
},
{
"type": "number"
},
{
"type": "boolean"
}
]
},
{
"maxItems": 100,
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"maxLength": 256
},
{
"type": "number"
}
]
}
}
]
},
"required": {
"default": false,
"type": "boolean"
},
"description": {
"type": "string",
"maxLength": 500
}
},
"required": [
"name",
"type"
],
"additionalProperties": false
}
},
"forEach": {
"maxItems": 10,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-zA-Z][a-zA-Z0-9]{0,15}$"
},
"items": {
"anyOf": [
{
"minItems": 1,
"maxItems": 100,
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"maxLength": 256
},
{
"type": "number"
}
]
}
},
{
"type": "string",
"pattern": "^\\{\\{\\s*params\\.([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\}\\}$"
}
]
},
"steps": {
"minItems": 1,
"maxItems": 50,
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"id",
"items",
"steps"
],
"additionalProperties": false
}
}
},
"required": [
"version",
"steps"
],
"additionalProperties": false
}

Type: "queued" | "running" | "succeeded" | "failed" | "cancelled"

JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "RunStatus",
"type": "string",
"enum": [
"queued",
"running",
"succeeded",
"failed",
"cancelled"
]
}

Type: "queued" | "running" | "succeeded" | "failed" | "cancelled" | "skipped"

JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "StepStatus",
"type": "string",
"enum": [
"queued",
"running",
"succeeded",
"failed",
"cancelled",
"skipped"
]
}