Scrydon
Authoring: Workflows

Process-Flow Platform Blocks

Three host-executed workflow blocks for creating process-flow tasks, spawning instances, and writing governed table rows — the building blocks of automated ingest pipelines.

The process-flow platform blocks are first-party workflow blocks that run with host-level database and network access — they cannot run inside a sandboxed vendor integration. Use them when a workflow needs to interact directly with the process-flow or managed-table subsystem.

These blocks are visible in the workflow editor's block gallery under the Core category: Create Process Task, Table Write, and Create Process Instance. They are available in every workflow, regardless of which integrations the organization has enabled.


create_process_task — Create Process Task

Creates a new task inside an existing process-flow instance. Use this when a workflow is triggered by an external event (calendar, webhook, schedule) and needs to add a task to a flow that is already running.

Block type: create_process_task

Sub-blocks:

Sub-blockRequiredMeaning
processInstanceYesThe process-flow instance to add the task to. Populated from a combobox listing live instances in the current workspace environment. Can also be set via a template reference (e.g. {{trigger.instanceId}}).
taskNameYesDisplay name for the new task. Supports template variables from the workflow trigger (e.g. {{trigger.event.title}}).
attributesNoA JSON object of extra attributes to store on the task (e.g. { "scheduledDate": "{{trigger.event.start}}" }). Must be valid JSON.

Output: { taskId, instanceId, stageName } when successful; { error } when not.

Example (calendar trigger → add a board-pack review task):

import { defineWorkflow, defineBlock, defineEdge } from '@scrydon/sdk-authoring/workflows'

export const calendarToTask = defineWorkflow({
  slug: 'calendar-to-board-review-task',
  name: 'Calendar → Board Review Task',
  version: '1.0.0',
  definition: {
    blocks: {
      'block-start': {
        id: 'block-start',
        type: 'starter',
        name: 'Start',
        position: { x: 0, y: 0 },
        subBlocks: {},
        outputs: {},
        enabled: true,
      },
      'block-create-task': {
        id: 'block-create-task',
        type: 'create_process_task',
        name: 'Create board review task',
        position: { x: 240, y: 0 },
        subBlocks: {
          processInstance: {
            id: 'processInstance',
            type: 'combobox',
            value: '{{trigger.instanceId}}',
          },
          taskName: {
            id: 'taskName',
            type: 'short-input',
            value: 'Board pack review — {{trigger.event.title}}',
          },
          attributes: {
            id: 'attributes',
            type: 'code',
            value: '{ "scheduledDate": "{{trigger.event.start}}" }',
          },
        },
        outputs: { taskId: 'string', instanceId: 'string', stageName: 'string' },
        enabled: true,
      },
    },
    edges: [
      { id: 'e1', source: 'block-start', target: 'block-create-task' },
    ],
    loops: {},
    parallels: {},
  },
})

table_write — Table Write

Writes one or more rows to a governed managed table bound to an ontology object type. The block resolves the object type to its silver table at run time, then dispatches the write through the api-table path. No user interaction is required — designed for automated ingest pipelines.

Block type: table_write

Sub-blocks:

Sub-blockRequiredMeaning
objectTypeYesOntology object-type slug identifying the target managed table. The block resolves the silver binding at run time.
modeYes"upsert" (match on identity column, update or insert) or "append" (always insert a new row).
rowsYesA JSON array of { [columnSlug]: value } objects, 1–500 rows per call. A code sub-block can produce this as a JSON string.

Output: { written: <row count>, tableId: "<uuid>" }.

Sentinel errors (returned as { success: false, error: "<sentinel>" }):

SentinelMeaning
table_write_target_unresolvedobjectType is not bound to a silver table in this workspace. Verify the ontology type exists and is bound to a managed table.
table_write_org_mismatchThe resolved table belongs to a different organization than the running workflow. This should not happen in normal usage; contact support.
table_write_user_requiredThe workflow execution context does not carry a user identity. Workflows triggered by service accounts or webhooks satisfy this automatically.

Example (webhook ingest — writing a track observation):

'block-write-observation': {
  id: 'block-write-observation',
  type: 'table_write',
  name: 'Write track observation',
  position: { x: 480, y: 0 },
  subBlocks: {
    objectType: {
      id: 'objectType',
      type: 'short-input',
      value: 'track_observation',      // ontology object-type slug
    },
    mode: {
      id: 'mode',
      type: 'dropdown',
      value: 'upsert',
    },
    rows: {
      id: 'rows',
      type: 'code',
      // JSON array produced by a preceding function block:
      value: '{{block-parse-payload.response}}',
    },
  },
  outputs: { written: 'number', tableId: 'string' },
  enabled: true,
},

The object type must be bound to a managed table in the workspace environment where the workflow runs. If the object type ships in the same Pack, the Pack must be installed before the workflow runs. The write is attributed to the workflow execution's user identity — workflows run by a service account satisfy the identity requirement automatically.


create_process_instance — Create Process Instance

Creates a new process-flow instance from a pack-declared template, optionally seeding it with a context object and a dedupeKey. When a dedupeKey is set, the block is idempotent: a second call with the same key returns the existing live instance instead of creating a duplicate.

Block type: create_process_instance

Sub-blocks:

Sub-blockRequiredMeaning
packIdYesThe package.id of the Pack that ships the target process-flow template.
processFlowSlugYesThe slug of the process-flow template within that Pack.
nameYes (1–200 chars)Human-readable name for the created instance. Supports template references.
contextNoA JSON object seeded into the instance as processFlow.context (accessible to map actions via focusAttribute, to agent steps, etc.). A code sub-block can produce a JSON string.
dedupeKeyNo (1–500 chars)When set, enforces at most one live instance per key in this workspace environment. Concurrent calls with the same key converge to a single instance.
detectionNoA TrackDetectedEvent-shaped JSON object. Accepted and validated; on a valid parse the platform publishes a thin signal to the org-events realtime topic (this is what powers live operational pictures such as Horizon) — leave it unset if you do not need live-event integration. The pre-rename key copDetection is still accepted as a legacy alias; new workflows should use detection.

Deduplication contract. The dedupe key is enforced at the database level — a partial unique index on (workspaceEnvironmentId, dedupeKey) covering only non-terminal instances. Concurrent webhook deliveries for the same key always converge to one instance; no application-level race is possible. A terminal instance (completed or cancelled) releases the key, allowing a fresh instance to be created.

Output: { instanceId: "<uuid>", deduped: <boolean> }. deduped: true when the call returned an existing live instance rather than creating a new one.

Sentinel errors:

SentinelMeaning
create_process_instance_no_environmentThe workflow execution context does not carry a workspace environment id, or workspace resolution failed.
create_process_instance_invalid_contextcontext is not a valid JSON object.
create_process_instance_user_requiredThe workflow execution context does not carry a user identity.

Example (webhook ingest — open a response instance per detected track):

'block-create-instance': {
  id: 'block-create-instance',
  type: 'create_process_instance',
  name: 'Open response instance',
  position: { x: 720, y: 0 },
  subBlocks: {
    packId: {
      id: 'packId',
      type: 'short-input',
      value: 'scrydon-drone-response',
    },
    processFlowSlug: {
      id: 'processFlowSlug',
      type: 'short-input',
      value: 'drone-response',
    },
    name: {
      id: 'name',
      type: 'short-input',
      value: 'Track {{trigger.body.trackId}}',
    },
    context: {
      id: 'context',
      type: 'code',
      value: '{ "trackRef": "{{trigger.body.trackId}}" }',
    },
    dedupeKey: {
      id: 'dedupeKey',
      type: 'short-input',
      value: '{{trigger.body.trackId}}',   // one live instance per track
    },
  },
  outputs: { instanceId: 'string', deduped: 'boolean' },
  enabled: true,
},

packId and processFlowSlug must match a template that is already installed in the organization. The block instantiates an existing template — it does not install the Pack. Install the Pack first (Settings → Packs), then deploy the ingest workflow.


Building an ingest pipeline

The three blocks compose naturally into a webhook-driven ingest pipeline:

[Webhook trigger]

[Function block — parse payload, build rows]

[table_write — write observation rows]

[create_process_instance — open response flow, deduped by trackId]

A full worked example ships as part of the drone-response C2 pack (see the Pack examples directory). The Pack includes the ontology (Track / TrackObservation object types), the ingest workflow, and the response process flow — install them in one upload and the webhook URL is live immediately.

Where to next

On this page

On this page