createWorkflow
Create a workflow automation.
Create a workflow automation: a new group plus its initial DRAFT version. workflowDomain is CONTACT | DEAL | PROPERTY | APPOINTMENT | EVENT. There is no workflowType: the variable is gone, so sending it is a 400 unknown_variable, not a no-op. Which channels a workflow messages on is not a property of the group: it is the union of the channels its communicationConfig configures with its own text_action / email_action steps, reported as channels on this response and on getWorkflow (the paginated listings carry channelsAcrossVersions; see them for how the two differ). A create seeds NO communication config unless a templateId brings one; adding a text or email step with updateWorkflowGraph seeds that channel's editor defaults, and a sender must still be chosen before promoting. Optional templateId seeds the draft graph from a registered starter template. Edit the draft with updateWorkflowGraph, whose step vocabulary is far more than texts and emails (tags, team and round-robin assignment, teammate notifications, tasks, appointments, deals, custom fields, AI employees, webhooks, Slack, chaining workflows), then ship it with promoteWorkflowDraft. Optional sendWindow is the starting SENDING SCHEDULE (updateWorkflowSendWindow's shape); absent takes the template's when it has one, else the platform default. The graph never carries it: change it later with updateWorkflowSendWindow. THE SKIP-TRACE WORKFLOW (watches property signals in a buy-box and skip-traces each owner into a contact) is created with workflowDomain: "PROPERTY", systemCategory: "PROPERTY_SIGNAL_SKIP_TRACE" and templateId: "property_signal_skip_trace" together, as the onboarding package does. Its draft is a trigger, a create-contact step and an end. It is promoted only with TWO triggers: a MUTATION trigger whose filter names at least one property signal type (propertySignalTypes, in ONE flat OR group: a run starts when a property gets any of them), and a MATCH trigger whose filter is an AND root carrying a top-level spicyLeadScore minimum (the buy-box; places and property types are optional conditions beside it). Read the draft with getWorkflowVersionGraph, replace its trigger with those two through updateWorkflowGraph, then promoteWorkflowDraft; getWorkflow.draftValidation names whichever is missing. Each run spends a skip-trace credit. Its daily run limit is the ORGANIZATION's, shared by every skip-trace workflow: setSkipTraceDailyCap sets it, getWorkflowThrottleUsage reads it.
curl https://server.goliathdata.com/api/v1/call \
-H "Authorization: Bearer $GOLIATH_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"operationId": "createWorkflow",
"variables": {
"name": "<String>",
"workflowDomain": "PROPERTY"
}
}'import { GoliathClient } from '@goliath-data/sdk'
const goliath = new GoliathClient({
apiKey: process.env.GOLIATH_API_KEY!,
baseUrl: 'https://server.goliathdata.com',
})
// Enum values as strings: the SDK's enum types aren't exported yet, so assert to the method's variables type.
const variables = {
name: '<String>',
workflowDomain: 'PROPERTY'
} as Parameters<typeof goliath.workflows.createWorkflow>[0]
const result = await goliath.workflows.createWorkflow(variables, { idempotencyKey: crypto.randomUUID() })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',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
operationId: 'createWorkflow',
variables: {
name: '<String>',
workflowDomain: 'PROPERTY'
}
}),
})
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.
Response
What comes back under data: a list shows as one entry, and a value as its type.
{
"data": {
"workflowAutomationsMutation": {
"createWorkflowGroup": {
"id": "<ID>",
"name": "…",
"status": "DRAFT",
"channels": [
"TEXT"
],
"workflowDomain": "PROPERTY",
"pendingDraft": {
"id": "<ID>",
"name": "…",
"status": "DRAFT"
}
}
}
}
}Errors
unknown_variableA variable the operation does not declare. A typo is refused rather than silently dropped.
unauthorizedNo bearer header, or the key is invalid or revoked.
insufficient_scopeThe key lacks the scope the operation requires.
forbiddenA referenced record does not exist, was deleted, or is outside your organization. The gateway cannot tell those apart.
idempotency_conflictA request with this Idempotency-Key is still in flight.
Idempotency
Send an Idempotency-Key of 1 to 255 characters. A finished request retried with the same key replays its stored response, marked Idempotency-Replayed: true; one still in flight returns 409 idempotency_conflict. Keys expire after 24 hours. Write without fear →