Workflow Automations

Visual workflow builder for trigger-based email and webhook flows. Define triggers, actions, conditions, and waits as a graph. Cloud-only, Scale plan.

Workflow Automations let you build trigger-driven flows in a visual canvas — for example: "When a contact subscribes to the newsletter → wait 24 hours → send welcome email → if they clicked the CTA, tag them as engaged". You build the workflow once, then enroll contacts via triggers (UI events, webhooks, or schedules) and Posthawk runs the graph.

This is an Scale-plan-only feature on cloud. Self-hosted users get it included with everything else.

Triggers

A workflow starts an enrollment when a trigger fires. Built-in triggers:

  • newsletter_subscribed — a subscriber confirmed (DOI off) or activated (DOI on)
  • newsletter_unsubscribed — a subscriber unsubscribed (manual, suppression cascade, or one-click)
  • email_opened / email_clicked — recipient interacted with a sent email
  • contact_created — a contact was created via API or import
  • schedule — repeating cron-like trigger (every Monday 9am, etc.)
  • webhook — an external system POSTs to your workflow's webhook URL

The workflow's trigger node defines which trigger starts an enrollment. Triggers can include conditions (e.g. only fire on the weekly-digest newsletter, only on emails matching a tag).

Steps

The workflow graph is composed of step nodes:

  • send_email — send a transactional email or render a template
  • wait — pause for a duration (30 minutes, 24 hours, 7 days)
  • wait_until — pause until a specific datetime
  • condition — branch based on contact properties, prior step output, or trigger context ({{trigger.context.tag}})
  • webhook — POST to an external URL (your CRM, Slack, etc.)
  • update_contact — set tags, metadata, or unsubscribed on the enrolled contact
  • add_to_audience / remove_from_audience — tag operations

Variables in steps support trigger payload interpolation: {{trigger.contact.email}}, {{trigger.context.newsletter_slug}}, etc.

Endpoints

Most workflow operations happen through the dashboard. The worker exposes these JWT endpoints for programmatic use:

POST/automations/webhook/:token

Public webhook ingest endpoint — receives external events that should trigger a workflow enrollment. The token in the URL identifies which workflow to start. Body is forwarded as the trigger payload (`{{trigger.body}}` etc.).

Authorizations

No authentication required — this is a public endpoint.

Path Parameters

tokenstringrequired

Workflow webhook token (visible in the workflow settings)

POST /automations/webhook/:token
curl -X POST https://api.posthawk.dev/automations/webhook/wh_abc123... \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "tag": "premium",
    "amount": 99.00
  }'
Response
{
  "success": true,
  "enrollmentId": "enroll-uuid"
}
POST/automations/:id/test-run

Run a workflow end-to-end with a synthetic trigger payload. Useful for validating the full graph without enrolling a real contact. Returns the per-step execution log.

Authorizations

Authorizationstring · headerrequired

Bearer authentication header of the form Bearer <token>, where <token> is your JWT.

Path Parameters

idstringrequired

Workflow UUID

Body

triggerPayloadobjectoptional

Payload to inject as `{{trigger}}`. Defaults to a sample for the workflow's configured trigger type.

POST /automations/:id/test-run
curl -X POST https://api.posthawk.dev/automations/{id}/test-run \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_jwt_token" \
  -d '{
    "triggerPayload": {
      "contact": {
        "email": "user@example.com"
      }
    }
  }'
POST/automations/:id/test-step

Run a single step in isolation against a synthetic context. Useful for testing variable interpolation or condition expressions.

Authorizations

Authorizationstring · headerrequired

Bearer authentication header of the form Bearer <token>, where <token> is your JWT.

Path Parameters

idstringrequired

Workflow UUID

Body

stepKeystringrequired

The step's key in the workflow graph

contextobjectoptional

Synthetic context to inject

POST /automations/:id/test-step
curl -X POST https://api.posthawk.dev/automations/{id}/test-step \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_jwt_token" \
  -d '{
    "stepKey": "send_welcome",
    "context": {
      "contact": {
        "email": "user@example.com"
      }
    }
  }'
POST/automations/:id/schedule/register

Register a recurring schedule trigger for a workflow. Replaces any existing schedule.

Authorizations

Authorizationstring · headerrequired

Bearer authentication header of the form Bearer <token>, where <token> is your JWT.

Path Parameters

idstringrequired

Workflow UUID

Body

cronstringrequired

Cron expression (e.g. "0 9 * * MON")

timezonestringoptional

IANA timezone (e.g. "America/New_York"). Defaults to UTC.

POST /automations/:id/schedule/register
curl -X POST https://api.posthawk.dev/automations/{id}/schedule/register \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_jwt_token" \
  -d '{
    "cron": "0 9 * * MON",
    "timezone": "America/New_York"
  }'
POST/automations/:id/schedule/unregister

Remove the recurring schedule from a workflow without deleting the workflow itself.

Authorizations

Authorizationstring · headerrequired

Bearer authentication header of the form Bearer <token>, where <token> is your JWT.

Path Parameters

idstringrequired

Workflow UUID

POST /automations/:id/schedule/unregister
curl -X POST https://api.posthawk.dev/automations/{id}/schedule/unregister \
  -H "Authorization: Bearer your_jwt_token"
POST/automations/internal/trigger

Internal-only — used by Posthawk's suppression cascade and other server-to-server systems to fire automation triggers programmatically. Authenticated via the X-Posthawk-Internal shared-secret header.

Authorizations

No authentication required — this is a public endpoint.

POST /automations/internal/trigger
curl -X POST https://api.posthawk.dev/automations/internal/trigger