Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.tracecat.com/llms.txt

Use this file to discover all available pages before exploring further.

Tables

Table Tables let you store structured data in your workspace. You can use them from the UI or from core.table.* actions in a workflow definition. Use tables when you want to:
  • Keep durable records across workflow runs
  • Look up known values such as users, hosts, or indicators
  • Search and export structured data for investigation or reporting
  • Reuse the same dataset across multiple workflows

Columns

Each table has a schema that defines its columns. Choose column types based on the data you want to store and query. When you define columns in the UI or in core.table.create_table, use the same uppercase type values exposed in the custom tables picker: You can create tables with the following column types:
  • TEXT
  • INTEGER
  • NUMERIC
  • BOOLEAN
  • DATE
  • TIMESTAMPTZ
  • JSONB
  • SELECT
  • MULTI_SELECT
Use TEXT, INTEGER, NUMERIC, and BOOLEAN for simple fields. Use DATE or TIMESTAMPTZ for time-based values, JSONB for nested structured data, and SELECT or MULTI_SELECT when the value must come from a fixed list. Case custom fields use the same storage type family: TEXT, INTEGER, NUMERIC, BOOLEAN, DATE, TIMESTAMPTZ, JSONB, SELECT, and MULTI_SELECT. In the case field picker, raw JSONB is currently surfaced through the URL kind, and Long text is layered on top of TEXT.

Rows

Rows hold the actual records in a table. You can insert, update, delete, look up, and search rows as your workflows process new events. This works well for data such as:
  • Asset inventories
  • User allowlists
  • Enrichment results
  • Investigation evidence
  • External system references
If you already know the field and value you want, use core.table.lookup. If you need broader filtering or text search, use core.table.search_rows. For example, use core.table.lookup when you know the exact value:
- ref: lookup_asset
  action: core.table.lookup
  args:
    table: asset_inventory
    column: hostname
    value: ${{ TRIGGER.hostname }}
For example, use core.table.search_rows when you want to search across rows:
- ref: search_assets
  action: core.table.search_rows
  args:
    table: asset_inventory
    search_term: production
    limit: 25

Index and upsert

You’ll often need to deduplicate data or require all values in a column to be unique. You can do that by creating an index and then using core.table.insert_row with upsert: true. Create unique index For example:
  • One row per hostname
  • One row per email address
  • One row per alert ID
  • One row per hash value
A unique index enforces that rule, and core.table.insert_row with upsert: true updates the existing row instead of creating a duplicate.

Table actions

Use core.table.* actions when you want your workflows to work with tables directly.
  • Tables to create tables, inspect metadata, insert rows, search rows, and export data
  • Use core.table.insert_row with upsert: true when you want to update an existing row that matches a unique index
core.table.create_table takes columns as a JSON array of column objects. This is the same schema you use for tables that you later link to cases.
  • name: Required string. Use letters, numbers, and underscores, and start with a letter or underscore.
  • type: Required uppercase string. Use TEXT, INTEGER, NUMERIC, BOOLEAN, DATE, TIMESTAMPTZ, JSONB, SELECT, or MULTI_SELECT.
  • nullable: Optional boolean. Defaults to true.
  • default: Optional value. It must match the column type.
  • options: Optional array of strings. Required for SELECT and MULTI_SELECT, and invalid for other types.
For example:
- ref: ensure_inventory_table
  action: core.table.create_table
  args:
    name: asset_inventory
    columns:
      - name: hostname
        type: TEXT
      - name: owner
        type: TEXT
    raise_on_duplicate: false
- ref: upsert_asset
  action: core.table.insert_row
  args:
    table: asset_inventory
    upsert: true
    row_data:
      hostname: ${{ TRIGGER.hostname }}
      owner: ${{ TRIGGER.owner }}
- ref: lookup_asset
  action: core.table.lookup
  args:
    table: asset_inventory
    column: hostname
    value: ${{ TRIGGER.hostname }}
For example, this upserts one row per alert ID:
- ref: upsert_alert
  action: core.table.insert_row
  args:
    table: alerts
    upsert: true
    row_data:
      alert_id: ${{ TRIGGER.alert_id }}
      status: ${{ TRIGGER.status }}
      severity: ${{ TRIGGER.severity }}