---
title: "Create a new workflow"
method: POST
path: "/v4/workflows"
tags: ["Workflows"]
---

# Create a new workflow

`POST /v4/workflows`

## Request

- Base URL: `https://api.kadoa.com`
- URL: `https://api.kadoa.com/v4/workflows`
- Auth: API key in header `x-api-key`

Create a workflow from natural-language instructions, an existing schema, an inline schema, raw-data output options, or a published template.

## Request body

- union: Request body for creating a new workflow
  - WorkflowFromTemplate: Create a workflow by instantiating a published template. Only `urls` and `templateId` are required; prompt, schema, frequency, and notifications are inherited from the template version. `templateVersion` is optional — omit it to use the latest published version. Example: `{"urls": ["https://example.com"], "templateId": "..."}`
    - `urls` string[], required: Source URLs. Multiple URLs must belong to one website: subdomains and country domains of the same name (acme.com, careers.acme.co.uk) count as one website. Requests that span several websites are rejected with 422 SOURCES_MULTIPLE_SITES; create one workflow per website instead, optionally from a shared template.
    - `name` string: Human-readable name for this workflow (e.g., 'Product Catalog Scraper')
    - `description` string: Detailed description of what this workflow does and why it was created (maximum 500 characters)
    - `tags` string[]: Tags for organizing and categorizing workflows (minimum 2 characters per tag)
    - `interval` 'ONLY_ONCE' | 'EVERY_10_MINUTES' | 'EVERY_20_MINUTES' | 'HALF_HOURLY' | 'HOURLY' | 'TWO_HOURLY' | 'THREE_HOURLY' | 'FOUR_HOURLY' | 'SIX_HOURLY' | 'TWELVE_HOURLY' | 'EIGHTEEN_HOURLY' | 'DAILY' | 'TWO_DAY' | 'THREE_DAY' | 'WEEKLY' | 'BIWEEKLY' | 'TRIWEEKLY' | 'FOUR_WEEKS' | 'MONTHLY' | 'CUSTOM': How frequently this workflow should run (ONLY_ONCE, HOURLY, DAILY, WEEKLY, etc.)
    - `schedules` string[]: Cron expressions for custom schedules. Overrides the interval setting for fine-grained control
    - `timezone` string: IANA timezone for cron `schedules` (e.g. 'America/New_York'). Defaults to UTC. Cron schedules only.
    - `location` Location: Geographic location for scraping. Use 'auto' for automatic detection or 'manual' to specify a country
      - `type` 'auto' | 'manual', required: Location type
      - `isoCode` string: Country ISO code for manual location
    - `bypassPreview` boolean: Skip preview and validation, deploy scraper immediately. Use with caution - set to true only when you're confident the configuration is correct
    - `additionalData` unknown
    - `interactions` Interaction[]: Browser interactions to perform before scraping (e.g., clicking buttons, filling forms, scrolling). See Interaction schema for available action types
      - union: Browser interaction definition. Accepts both simple format (with selector, text, url) and complex format from browser extensions
        - BrowserInteraction: Browser interaction definition. Examples: - CLICK: {type: 'CLICK', selector: '#submit-btn'} - TYPE: {type: 'TYPE', text: 'hello world'} - WAIT: {type: 'WAIT', timeMs: 2000} - GOTO: {type: 'GOTO', url: 'https://example.com'} - ENTER/TAB/BACKSPACE/DELETE/REFRESH/NAVIGATE_BACK/SCROLL/HOVER/SELECT/LOAD/KEYPRESS: {type: 'ENTER'} (no additional parameters needed)
          - `type` 'CLICK' | 'TYPE' | 'HOVER' | 'SCROLL' | 'WAIT' | 'KEYPRESS' | 'LOAD' | 'SELECT' | 'BACKSPACE' | 'ENTER' | 'TAB' | 'DELETE' | 'GOTO' | 'REFRESH' | 'NAVIGATE_BACK', required: Type of interaction
          - `selector` string: CSS selector for the target element (required for CLICK, HOVER)
          - `text` string: Text to type (required for TYPE)
          - `timeMs` number: Time in milliseconds (required for WAIT)
          - `url` string: URL to navigate to (required for GOTO)
          - `tagName` string: HTML tag name of the element
          - `innerText` string: Inner text content of the element
        - WebExtensionInteraction: Web extension interaction in complex format
          - `type` string, required: Type of interaction
          - `id` string: Unique interaction ID
          - `x` number: X coordinate
          - `y` number: Y coordinate
          - `link` string: Page URL
          - `time` string: Timestamp
          - `bodyHTMLUrl` string: URL to captured HTML body
          - `screenshotUrl` string: URL to captured screenshot
          - `target` object: Target element information
            - `id` string
            - `x` number
            - `y` number
            - `width` number
            - `height` number
            - `tagName` string
            - `html` string
            - `innerText` string
          - `key` string: Key value
          - `code` string: Key code
          - `metaKeys` object: Modifier keys state
            - `alt` boolean
            - `ctrl` boolean
            - `meta` boolean
            - `shift` boolean
    - `limit` integer, nullable: Maximum number of items to scrape. Useful for limiting scope during development or cost control. Pass null to clear an existing limit (unlimited).
    - `templateId` string, uuid, required: ID of the template to instantiate.
    - `templateVersion` integer: Optional version (integer) of the template to instantiate. Omit to use the latest published version (resolved once at request time). Provide it to pin a specific version.
    - `userPrompt` string: Workflow-specific instructions added to the selected template prompt. The template prompt remains template-owned and this text survives template updates.
  - PromptWorkflow: Create a workflow using natural language instructions to extract data and navigate the site automatically. Example: `{"urls": ["https://example.com"], "userPrompt": "Extract all job listings with title, company, salary, and location. Click on each listing to get full details."}`
    - `urls` string[], required: Source URLs. Multiple URLs must belong to one website: subdomains and country domains of the same name (acme.com, careers.acme.co.uk) count as one website. Requests that span several websites are rejected with 422 SOURCES_MULTIPLE_SITES; create one workflow per website instead, optionally from a shared template.
    - `name` string: Human-readable name for this workflow (e.g., 'Product Catalog Scraper')
    - `description` string: Detailed description of what this workflow does and why it was created (maximum 500 characters)
    - `tags` string[]: Tags for organizing and categorizing workflows (minimum 2 characters per tag)
    - `limit` integer, nullable: Maximum number of items to scrape. Useful for limiting scope during development or cost control. Pass null to clear an existing limit (unlimited).
    - `location` Location: Geographic location for scraping. Use 'auto' for automatic detection or 'manual' to specify a country
      - `type` 'auto' | 'manual', required: Location type
      - `isoCode` string: Country ISO code for manual location
    - `monitoring` MonitoringConfig: Monitoring configuration
      - `fields` MonitoredField[], required: Fields to monitor (at least one required)
        - `fieldName` string, required: Name of the field to monitor
        - `operator` 'changed' | 'added' | 'removed', required: Change operator
        - `isKeyField` boolean: Optional explicit schema-key metadata update for this field. Omit to leave workflow schema key flags unchanged.
      - `channels` unknown[]: Notification channels
        - unknown
      - `conditions` unknown
    - `interval` 'ONLY_ONCE' | 'EVERY_10_MINUTES' | 'EVERY_20_MINUTES' | 'HALF_HOURLY' | 'HOURLY' | 'TWO_HOURLY' | 'THREE_HOURLY' | 'FOUR_HOURLY' | 'SIX_HOURLY' | 'TWELVE_HOURLY' | 'EIGHTEEN_HOURLY' | 'DAILY' | 'TWO_DAY' | 'THREE_DAY' | 'WEEKLY' | 'BIWEEKLY' | 'TRIWEEKLY' | 'FOUR_WEEKS' | 'MONTHLY' | 'CUSTOM': How frequently this workflow should run (ONLY_ONCE, HOURLY, DAILY, WEEKLY, etc.)
    - `schedules` string[]: Cron expressions for custom schedules. Overrides the interval setting for fine-grained control
    - `timezone` string: IANA timezone for cron `schedules` (e.g. 'America/New_York'). Defaults to UTC. Cron schedules only.
    - `bypassPreview` boolean: Skip preview and validation, deploy scraper immediately. Use with caution - set to true only when you're confident the configuration is correct
    - `interactions` Interaction[]: Browser interactions to perform before scraping (e.g., clicking buttons, filling forms, scrolling). See Interaction schema for available action types
      - union: Browser interaction definition. Accepts both simple format (with selector, text, url) and complex format from browser extensions
        - BrowserInteraction: Browser interaction definition. Examples: - CLICK: {type: 'CLICK', selector: '#submit-btn'} - TYPE: {type: 'TYPE', text: 'hello world'} - WAIT: {type: 'WAIT', timeMs: 2000} - GOTO: {type: 'GOTO', url: 'https://example.com'} - ENTER/TAB/BACKSPACE/DELETE/REFRESH/NAVIGATE_BACK/SCROLL/HOVER/SELECT/LOAD/KEYPRESS: {type: 'ENTER'} (no additional parameters needed)
          - `type` 'CLICK' | 'TYPE' | 'HOVER' | 'SCROLL' | 'WAIT' | 'KEYPRESS' | 'LOAD' | 'SELECT' | 'BACKSPACE' | 'ENTER' | 'TAB' | 'DELETE' | 'GOTO' | 'REFRESH' | 'NAVIGATE_BACK', required: Type of interaction
          - `selector` string: CSS selector for the target element (required for CLICK, HOVER)
          - `text` string: Text to type (required for TYPE)
          - `timeMs` number: Time in milliseconds (required for WAIT)
          - `url` string: URL to navigate to (required for GOTO)
          - `tagName` string: HTML tag name of the element
          - `innerText` string: Inner text content of the element
        - WebExtensionInteraction: Web extension interaction in complex format
          - `type` string, required: Type of interaction
          - `id` string: Unique interaction ID
          - `x` number: X coordinate
          - `y` number: Y coordinate
          - `link` string: Page URL
          - `time` string: Timestamp
          - `bodyHTMLUrl` string: URL to captured HTML body
          - `screenshotUrl` string: URL to captured screenshot
          - `target` object: Target element information
            - `id` string
            - `x` number
            - `y` number
            - `width` number
            - `height` number
            - `tagName` string
            - `html` string
            - `innerText` string
          - `key` string: Key value
          - `code` string: Key code
          - `metaKeys` object: Modifier keys state
            - `alt` boolean
            - `ctrl` boolean
            - `meta` boolean
            - `shift` boolean
    - `additionalData` unknown
    - `templateId` string, uuid: Optional: ID of the template this workflow was created from. Records provenance only — the template's config is cloned at creation, not synced.
    - `templateVersion` unknown
    - `userPrompt` string, required: Natural language instructions for the workflow (10-5000 characters). Describe what data to extract and how to navigate the site
    - `schemaId` string: Optional: Schema ID to use with prompt-driven extraction
    - `entity` string: Optional: Entity name for prompt-driven extraction
    - `fields` union[]: Optional: Additional extraction fields to guide the workflow
      - union: Extraction field schema
        - DataField: Extract and structure specific data from web pages with typed values (e.g., product prices, article titles, dates). `description` explains what the field is; optional `instruction` gives the AI field-specific extraction guidance. Use this for actual data you want to capture. Kadoa-managed functions such as job description, job type classification, taxonomy mapping, and stable unique ID are normal `fieldType: SCHEMA` fields with their output `dataType`; their function identity lives in `mapper`. To expose source values such as the page URL, full HTML, or full Markdown, use a normal `fieldType: SCHEMA` field with `params.sourceKey` (for example `link`, `allExtracts.fullHtml`, or `allExtracts.fullMarkdown`).
          - `mapper` 'jobDescription' | 'categoryClassifier' | 'taxonomyMapping' | 'stableUniqueId' | 'linkExtraction' | 'additionalData' | 'categorize': Function that produces this field's value.
          - `mapperConfig` object: Configuration for the selected mapper.
          - `name` string, required: Field name (e.g., productName, 3dListings, listing-count)
          - `description` string, required: Human-readable field description shown in Kadoa.
          - `instruction` string: Optional field-specific AI instruction. Use this for extraction guidance that is more specific than the description.
          - `fieldType` 'SCHEMA': Field role. Use SCHEMA for extracted data fields.
          - `example` union: Example value for the field
            - string
            - string[]
          - `shape` unknown
          - `dataType` 'STRING' | 'NUMBER' | 'BOOLEAN' | 'DATE' | 'DATETIME' | 'MONEY' | 'IMAGE' | 'LINK' | 'OBJECT' | 'ARRAY', required: Output data type for SCHEMA fields. Use uppercase public values: STRING, NUMBER, BOOLEAN, DATE, DATETIME, MONEY, IMAGE, LINK, OBJECT, ARRAY. Classification fields use fieldType=CLASSIFICATION instead of dataType=CLASSIFICATION. Kadoa-managed functions are not data types; they keep a normal output dataType and carry their function identity in mapper, with configuration in mapperConfig.
          - `isKey` boolean: Marks this field as part of the record's primary key. Key fields define row identity across runs and enable data linking (records with the same key values are treated as the same record over time, used for dedupe and change detection). Set true ONLY when the complete key tuple uniquely identifies a logical output record and every component is stable across runs and reliably present (not nullable/missing). Key fields should be scalar STRING, NUMBER, or LINK fields; avoid structured, semantic, boolean, image, and timestamp/date fields as keys. Good candidates: external IDs, SKUs, canonical URLs, posting IDs. Bad candidates: prices, counts, timestamps, free-text titles/descriptions, or anything that can change between runs. Multiple fields may form a composite key; uniqueness applies to their combination, not each component. For derived rows, source-backed grouping dimensions and a deterministic output discriminator may identify the result; measured values and explanations do not. If no supported key tuple satisfies these guarantees, leave isKey unset on every field — data linking will simply be disabled, which is preferable to a wrong key. Choosing a non-stable or non-unique key causes duplicate rows and missed updates.
        - ClassificationField: Categorize extracted data into predefined labels. Classification is a field role (`fieldType: CLASSIFICATION`), not a schema data type. Use this when you want the system to classify content into specific categories you define.
          - `name` string, required: Field name (e.g., category, product-type)
          - `description` string: Optional human-readable field description
          - `fieldType` 'CLASSIFICATION', required: Field role. Use CLASSIFICATION for predefined category labels.
          - `categories` object[], required: List of predefined categories for classification
            - `title` string, required: Short title/label of the category
            - `definition` string, required: Full definition/description of the category
  - WorkflowWithExistingSchema: Create a workflow using a pre-defined schema configuration. Reference an existing schema by ID to extract data without re-defining fields. Perfect when you have multiple workflows using the same data structure. Example: `{"urls": ["https://example.com"], "schemaId": "schema-abc123", "interval": "DAILY"}`
    - `urls` string[], required: Source URLs. Multiple URLs must belong to one website: subdomains and country domains of the same name (acme.com, careers.acme.co.uk) count as one website. Requests that span several websites are rejected with 422 SOURCES_MULTIPLE_SITES; create one workflow per website instead, optionally from a shared template.
    - `name` string: Human-readable name for this workflow (e.g., 'Product Catalog Scraper')
    - `description` string: Detailed description of what this workflow does and why it was created (maximum 500 characters)
    - `tags` string[]: Tags for organizing and categorizing workflows (minimum 2 characters per tag)
    - `limit` integer, nullable: Maximum number of items to scrape. Useful for limiting scope during development or cost control. Pass null to clear an existing limit (unlimited).
    - `location` Location: Geographic location for scraping. Use 'auto' for automatic detection or 'manual' to specify a country
      - `type` 'auto' | 'manual', required: Location type
      - `isoCode` string: Country ISO code for manual location
    - `monitoring` MonitoringConfig: Monitoring configuration
      - `fields` MonitoredField[], required: Fields to monitor (at least one required)
        - `fieldName` string, required: Name of the field to monitor
        - `operator` 'changed' | 'added' | 'removed', required: Change operator
        - `isKeyField` boolean: Optional explicit schema-key metadata update for this field. Omit to leave workflow schema key flags unchanged.
      - `channels` unknown[]: Notification channels
        - unknown
      - `conditions` unknown
    - `interval` 'ONLY_ONCE' | 'EVERY_10_MINUTES' | 'EVERY_20_MINUTES' | 'HALF_HOURLY' | 'HOURLY' | 'TWO_HOURLY' | 'THREE_HOURLY' | 'FOUR_HOURLY' | 'SIX_HOURLY' | 'TWELVE_HOURLY' | 'EIGHTEEN_HOURLY' | 'DAILY' | 'TWO_DAY' | 'THREE_DAY' | 'WEEKLY' | 'BIWEEKLY' | 'TRIWEEKLY' | 'FOUR_WEEKS' | 'MONTHLY' | 'CUSTOM': How frequently this workflow should run (ONLY_ONCE, HOURLY, DAILY, WEEKLY, etc.)
    - `schedules` string[]: Cron expressions for custom schedules. Overrides the interval setting for fine-grained control
    - `timezone` string: IANA timezone for cron `schedules` (e.g. 'America/New_York'). Defaults to UTC. Cron schedules only.
    - `bypassPreview` boolean: Skip preview and validation, deploy scraper immediately. Use with caution - set to true only when you're confident the configuration is correct
    - `interactions` Interaction[]: Browser interactions to perform before scraping (e.g., clicking buttons, filling forms, scrolling). See Interaction schema for available action types
      - union: Browser interaction definition. Accepts both simple format (with selector, text, url) and complex format from browser extensions
        - BrowserInteraction: Browser interaction definition. Examples: - CLICK: {type: 'CLICK', selector: '#submit-btn'} - TYPE: {type: 'TYPE', text: 'hello world'} - WAIT: {type: 'WAIT', timeMs: 2000} - GOTO: {type: 'GOTO', url: 'https://example.com'} - ENTER/TAB/BACKSPACE/DELETE/REFRESH/NAVIGATE_BACK/SCROLL/HOVER/SELECT/LOAD/KEYPRESS: {type: 'ENTER'} (no additional parameters needed)
          - `type` 'CLICK' | 'TYPE' | 'HOVER' | 'SCROLL' | 'WAIT' | 'KEYPRESS' | 'LOAD' | 'SELECT' | 'BACKSPACE' | 'ENTER' | 'TAB' | 'DELETE' | 'GOTO' | 'REFRESH' | 'NAVIGATE_BACK', required: Type of interaction
          - `selector` string: CSS selector for the target element (required for CLICK, HOVER)
          - `text` string: Text to type (required for TYPE)
          - `timeMs` number: Time in milliseconds (required for WAIT)
          - `url` string: URL to navigate to (required for GOTO)
          - `tagName` string: HTML tag name of the element
          - `innerText` string: Inner text content of the element
        - WebExtensionInteraction: Web extension interaction in complex format
          - `type` string, required: Type of interaction
          - `id` string: Unique interaction ID
          - `x` number: X coordinate
          - `y` number: Y coordinate
          - `link` string: Page URL
          - `time` string: Timestamp
          - `bodyHTMLUrl` string: URL to captured HTML body
          - `screenshotUrl` string: URL to captured screenshot
          - `target` object: Target element information
            - `id` string
            - `x` number
            - `y` number
            - `width` number
            - `height` number
            - `tagName` string
            - `html` string
            - `innerText` string
          - `key` string: Key value
          - `code` string: Key code
          - `metaKeys` object: Modifier keys state
            - `alt` boolean
            - `ctrl` boolean
            - `meta` boolean
            - `shift` boolean
    - `additionalData` unknown
    - `templateId` string, uuid: Optional: ID of the template this workflow was created from. Records provenance only — the template's config is cloned at creation, not synced.
    - `templateVersion` unknown
    - `schemaId` string, required: ID of an existing schema configuration. Use this to reference a previously defined schema without re-defining extraction fields
  - WorkflowWithEntityAndFields: Create a workflow by defining extraction entity and fields directly in the request. Inline your schema definition to quickly set up custom data extraction without creating a schema separately. Example: `{"urls": ["https://example.com"], "entity": "Product", "fields": [{"name": "title", "description": "Product title", "fieldType": "SCHEMA", "dataType": "STRING"}, {"name": "price", "description": "Product price", "fieldType": "SCHEMA", "dataType": "NUMBER"}]}`
    - `urls` string[], required: Source URLs. Multiple URLs must belong to one website: subdomains and country domains of the same name (acme.com, careers.acme.co.uk) count as one website. Requests that span several websites are rejected with 422 SOURCES_MULTIPLE_SITES; create one workflow per website instead, optionally from a shared template.
    - `name` string: Human-readable name for this workflow (e.g., 'Product Catalog Scraper')
    - `description` string: Detailed description of what this workflow does and why it was created (maximum 500 characters)
    - `tags` string[]: Tags for organizing and categorizing workflows (minimum 2 characters per tag)
    - `limit` integer, nullable: Maximum number of items to scrape. Useful for limiting scope during development or cost control. Pass null to clear an existing limit (unlimited).
    - `location` Location: Geographic location for scraping. Use 'auto' for automatic detection or 'manual' to specify a country
      - `type` 'auto' | 'manual', required: Location type
      - `isoCode` string: Country ISO code for manual location
    - `monitoring` MonitoringConfig: Monitoring configuration
      - `fields` MonitoredField[], required: Fields to monitor (at least one required)
        - `fieldName` string, required: Name of the field to monitor
        - `operator` 'changed' | 'added' | 'removed', required: Change operator
        - `isKeyField` boolean: Optional explicit schema-key metadata update for this field. Omit to leave workflow schema key flags unchanged.
      - `channels` unknown[]: Notification channels
        - unknown
      - `conditions` unknown
    - `interval` 'ONLY_ONCE' | 'EVERY_10_MINUTES' | 'EVERY_20_MINUTES' | 'HALF_HOURLY' | 'HOURLY' | 'TWO_HOURLY' | 'THREE_HOURLY' | 'FOUR_HOURLY' | 'SIX_HOURLY' | 'TWELVE_HOURLY' | 'EIGHTEEN_HOURLY' | 'DAILY' | 'TWO_DAY' | 'THREE_DAY' | 'WEEKLY' | 'BIWEEKLY' | 'TRIWEEKLY' | 'FOUR_WEEKS' | 'MONTHLY' | 'CUSTOM': How frequently this workflow should run (ONLY_ONCE, HOURLY, DAILY, WEEKLY, etc.)
    - `schedules` string[]: Cron expressions for custom schedules. Overrides the interval setting for fine-grained control
    - `timezone` string: IANA timezone for cron `schedules` (e.g. 'America/New_York'). Defaults to UTC. Cron schedules only.
    - `bypassPreview` boolean: Skip preview and validation, deploy scraper immediately. Use with caution - set to true only when you're confident the configuration is correct
    - `interactions` Interaction[]: Browser interactions to perform before scraping (e.g., clicking buttons, filling forms, scrolling). See Interaction schema for available action types
      - union: Browser interaction definition. Accepts both simple format (with selector, text, url) and complex format from browser extensions
        - BrowserInteraction: Browser interaction definition. Examples: - CLICK: {type: 'CLICK', selector: '#submit-btn'} - TYPE: {type: 'TYPE', text: 'hello world'} - WAIT: {type: 'WAIT', timeMs: 2000} - GOTO: {type: 'GOTO', url: 'https://example.com'} - ENTER/TAB/BACKSPACE/DELETE/REFRESH/NAVIGATE_BACK/SCROLL/HOVER/SELECT/LOAD/KEYPRESS: {type: 'ENTER'} (no additional parameters needed)
          - `type` 'CLICK' | 'TYPE' | 'HOVER' | 'SCROLL' | 'WAIT' | 'KEYPRESS' | 'LOAD' | 'SELECT' | 'BACKSPACE' | 'ENTER' | 'TAB' | 'DELETE' | 'GOTO' | 'REFRESH' | 'NAVIGATE_BACK', required: Type of interaction
          - `selector` string: CSS selector for the target element (required for CLICK, HOVER)
          - `text` string: Text to type (required for TYPE)
          - `timeMs` number: Time in milliseconds (required for WAIT)
          - `url` string: URL to navigate to (required for GOTO)
          - `tagName` string: HTML tag name of the element
          - `innerText` string: Inner text content of the element
        - WebExtensionInteraction: Web extension interaction in complex format
          - `type` string, required: Type of interaction
          - `id` string: Unique interaction ID
          - `x` number: X coordinate
          - `y` number: Y coordinate
          - `link` string: Page URL
          - `time` string: Timestamp
          - `bodyHTMLUrl` string: URL to captured HTML body
          - `screenshotUrl` string: URL to captured screenshot
          - `target` object: Target element information
            - `id` string
            - `x` number
            - `y` number
            - `width` number
            - `height` number
            - `tagName` string
            - `html` string
            - `innerText` string
          - `key` string: Key value
          - `code` string: Key code
          - `metaKeys` object: Modifier keys state
            - `alt` boolean
            - `ctrl` boolean
            - `meta` boolean
            - `shift` boolean
    - `additionalData` unknown
    - `templateId` string, uuid: Optional: ID of the template this workflow was created from. Records provenance only — the template's config is cloned at creation, not synced.
    - `templateVersion` unknown
    - `entity` string, required: Entity name for extraction (e.g., 'Product', 'JobListing')
    - `fields` union[], required: Array of fields to extract from each item. Each field defines a property to capture (e.g., title, price, description)
      - union: Extraction field schema
        - DataField: Extract and structure specific data from web pages with typed values (e.g., product prices, article titles, dates). `description` explains what the field is; optional `instruction` gives the AI field-specific extraction guidance. Use this for actual data you want to capture. Kadoa-managed functions such as job description, job type classification, taxonomy mapping, and stable unique ID are normal `fieldType: SCHEMA` fields with their output `dataType`; their function identity lives in `mapper`. To expose source values such as the page URL, full HTML, or full Markdown, use a normal `fieldType: SCHEMA` field with `params.sourceKey` (for example `link`, `allExtracts.fullHtml`, or `allExtracts.fullMarkdown`).
          - `mapper` 'jobDescription' | 'categoryClassifier' | 'taxonomyMapping' | 'stableUniqueId' | 'linkExtraction' | 'additionalData' | 'categorize': Function that produces this field's value.
          - `mapperConfig` object: Configuration for the selected mapper.
          - `name` string, required: Field name (e.g., productName, 3dListings, listing-count)
          - `description` string, required: Human-readable field description shown in Kadoa.
          - `instruction` string: Optional field-specific AI instruction. Use this for extraction guidance that is more specific than the description.
          - `fieldType` 'SCHEMA': Field role. Use SCHEMA for extracted data fields.
          - `example` union: Example value for the field
            - string
            - string[]
          - `shape` unknown
          - `dataType` 'STRING' | 'NUMBER' | 'BOOLEAN' | 'DATE' | 'DATETIME' | 'MONEY' | 'IMAGE' | 'LINK' | 'OBJECT' | 'ARRAY', required: Output data type for SCHEMA fields. Use uppercase public values: STRING, NUMBER, BOOLEAN, DATE, DATETIME, MONEY, IMAGE, LINK, OBJECT, ARRAY. Classification fields use fieldType=CLASSIFICATION instead of dataType=CLASSIFICATION. Kadoa-managed functions are not data types; they keep a normal output dataType and carry their function identity in mapper, with configuration in mapperConfig.
          - `isKey` boolean: Marks this field as part of the record's primary key. Key fields define row identity across runs and enable data linking (records with the same key values are treated as the same record over time, used for dedupe and change detection). Set true ONLY when the complete key tuple uniquely identifies a logical output record and every component is stable across runs and reliably present (not nullable/missing). Key fields should be scalar STRING, NUMBER, or LINK fields; avoid structured, semantic, boolean, image, and timestamp/date fields as keys. Good candidates: external IDs, SKUs, canonical URLs, posting IDs. Bad candidates: prices, counts, timestamps, free-text titles/descriptions, or anything that can change between runs. Multiple fields may form a composite key; uniqueness applies to their combination, not each component. For derived rows, source-backed grouping dimensions and a deterministic output discriminator may identify the result; measured values and explanations do not. If no supported key tuple satisfies these guarantees, leave isKey unset on every field — data linking will simply be disabled, which is preferable to a wrong key. Choosing a non-stable or non-unique key causes duplicate rows and missed updates.
        - ClassificationField: Categorize extracted data into predefined labels. Classification is a field role (`fieldType: CLASSIFICATION`), not a schema data type. Use this when you want the system to classify content into specific categories you define.
          - `name` string, required: Field name (e.g., category, product-type)
          - `description` string: Optional human-readable field description
          - `fieldType` 'CLASSIFICATION', required: Field role. Use CLASSIFICATION for predefined category labels.
          - `categories` object[], required: List of predefined categories for classification
            - `title` string, required: Short title/label of the category
            - `definition` string, required: Full definition/description of the category

## Response `201`

201

- CreateWorkflowResponse: Response for workflow creation
  - `error` false, required: Error flag (always false on success)
  - `success` boolean, required: Success flag
  - `workflowId` string, required: ID of the created workflow
  - `message` string, required: Success message

## Other responses

- `400`: 400
- `401`: 401
- `403`: 403
- `404`: 404
- `422`: 422
- `500`: 500
- `503`: 503

---

[API](https://skmtc.dev/kadoa/apis/kadoa-api.md) · [All operations](https://skmtc.dev/kadoa/apis/kadoa-api/llms.txt) · [OpenAPI document](https://skmtc.dev/kadoa/apis/kadoa-api/revisions/bf7803c927b4?raw)
