GoliathDevelopersGet an API key
Reference/Workflowsgenerated from the gateway manifest

getWorkflow

Fetch one workflow automation by group id.

POST/api/v1/callREADreadruns as the key's owner
View as Markdown

Fetch one workflow automation by group id: status, versions (a workflow is a stable group holding versioned definitions), the live version, the pending draft and draft validation. channels reads ONE version, the most recently PUBLISHED whatever its status now (active, paused or suspended), else the pending draft; null when that graph could not be read, [] when the group has no version. channelsAcrossVersions reads every version not deleted, superseded ones and drafts included (the listings' field, matched by the app's Channel filter; never null), so the two differ whenever another version messages on a channel the published one does not. Both are CONFIGURED channels, not sending: a paused or suspended head answers its channels while sending nothing, so read status before calling a workflow actively texting or emailing. draftValidation.carrierRisk is the draft's text copy scored for carrier filtering, riskiest first (isFallback: the step's backup text). It never blocks the promote: reword a medium or high one with rewriteWorkflowDraftTextStep first. sendWindow is the workflow's live SENDING SCHEDULE (a graph triggerWindow's shape plus timezoneMode, see updateWorkflowGraph), or null for the platform default (Mon-Fri 09:00-19:00 org time). It belongs to the workflow, not a version: every run reads it on its next send, whichever version it started on. Only updateWorkflowSendWindow changes it; no graph write can. stepKinds names step TYPES, not waits or copy: never say a pending draft matches or changes the published one before reading BOTH with getWorkflowVersionGraph (paused: the published one is in versions, not currentVersion). TRIGGERS ARE NOT THE ONLY WAY IN. Steps in OTHER workflows enroll records into this one: a PROPERTY create_contact_action (the contact it creates), a trigger_contact_workflow_action (start another workflow), and an EVENT find_create_contact_action / event_find_property_action. A workflow whose only trigger is {type: "manual"} is normal when it is fed that way: never call it idle or unreachable from its triggers alone. getDeletionImpact(targetKind: WORKFLOW_GROUP, targetId: <this group id>) says whether anything references it: its WORKFLOW_AUTOMATION group counts REFERENCES (each step, trigger or filter in each live version naming this one, so one workflow can count more than once), not names. To see WHICH workflows feed it, scan other workflows' graphs (getWorkflowVersionGraph) for a step naming this group id. TO CHANGE WHAT A WORKFLOW DOES (add a condition, change a trigger, narrow who it acts on), edit its graph: createOrReturnWorkflowDraft → updateWorkflowGraph → promoteWorkflowDraft, then resumeWorkflow if it was paused. Pausing only stops it. E.g. a PROPERTY workflow can require a motivation signal before it creates or texts anyone: a conditional step on the hasSignal or propertySignalTypes property filter fields (listFilterFieldNames lists them) ahead of the create_contact_action step. Never tell a user restricting outreach this way needs human review: it is a graph edit.

curl https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer $GOLIATH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operationId": "getWorkflow",
    "variables": {
      "workflowGroupId": "<workflowGroupId>"
    }
  }'
import { GoliathClient } from '@goliath-data/sdk'

const goliath = new GoliathClient({
  apiKey: process.env.GOLIATH_API_KEY!,
  baseUrl: 'https://server.goliathdata.com',
})

const result = await goliath.workflows.getWorkflow({
  workflowGroupId: '<workflowGroupId>'
})
const res = await fetch('https://server.goliathdata.com/api/v1/call', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.GOLIATH_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    operationId: 'getWorkflow',
    variables: {
      workflowGroupId: '<workflowGroupId>'
    }
  }),
})
const { data, errors } = await res.json()

Variables

The example sends only what the schema requires. Some operations also need one of several optional variables (one filter or another, say); the description above says which.

workflowGroupIdID!required

Response

What comes back under data: a list shows as one entry, and a value as its type.

response shape
{
  "data": {
    "workflowAutomationsQuery": {
      "workflowGroup": {
        "id": "<ID>",
        "name": "…",
        "description": "…",
        "status": "DRAFT",
        "channels": [
          "TEXT"
        ],
        "channelsAcrossVersions": [
          "TEXT"
        ],
        "workflowDomain": "PROPERTY",
        "systemCategory": "…",
        "sendWindow": "…",
        "folderId": "<ID>",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "updatedAt": "2026-01-01T00:00:00.000Z",
        "archivedAt": "2026-01-01T00:00:00.000Z",
        "currentVersion": {
          "id": "<ID>",
          "name": "…",
          "status": "DRAFT",
          "stepKinds": [
            "…"
          ],
          "updatedAt": "2026-01-01T00:00:00.000Z"
        },
        "pendingDraft": {
          "id": "<ID>",
          "name": "…",
          "status": "DRAFT",
          "stepKinds": [
            "…"
          ],
          "updatedAt": "2026-01-01T00:00:00.000Z"
        },
        "versions": [
          {
            "id": "<ID>",
            "name": "…",
            "status": "DRAFT",
            "publishedAt": "2026-01-01T00:00:00.000Z",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "updatedAt": "2026-01-01T00:00:00.000Z"
          }
        ],
        "draftValidation": {
          "isValid": true,
          "errors": [
            "…"
          ],
          "carrierRisk": [
            {
              "nodeId": "<ID>",
              "body": "…",
              "band": "…",
              "templateId": "<ID>",
              "isFallback": true
            }
          ]
        },
        "runsPausedWithWorkflow": 0,
        "runsParkedByPublish": 0
      }
    }
  }
}

Errors

Behaviour

A read. It rejects an Idempotency-Key header with 400 bad_request.