Automations
Per-resource workflows - a trigger, optional conditions, and an ordered list of action steps. Automations hang off a parent resource, so the same eleven endpoints exist under forms, surveys, and funnels. Available on every plan, same token model as the rest of the API.
Base URL: https://formspring.io/api/v1
The paths below use /forms/{form}/...; substitute /surveys/{survey}/... or /funnels/{funnel}/... for the other products.
| Method | Path | Ability |
|---|---|---|
| GET | /forms/{form}/automations |
automations:read |
| POST | /forms/{form}/automations |
automations:write |
| GET | /forms/{form}/automations/{automation} |
automations:read |
| PUT | /forms/{form}/automations/{automation} |
automations:write |
| DELETE | /forms/{form}/automations/{automation} |
automations:write |
| POST | /forms/{form}/automations/{automation}/enable |
automations:write |
| POST | /forms/{form}/automations/{automation}/disable |
automations:write |
| POST | /forms/{form}/automations/{automation}/run |
automations:run |
| GET | /forms/{form}/automations/{automation}/runs |
automations:read |
| GET | /forms/{form}/automations/{automation}/runs/{run} |
automations:read |
| POST | /forms/{form}/automations/{automation}/runs/{run}/replay |
automations:run |
The {form}/{survey}/{funnel} parameter takes the parent's public id (funnels also accept the slug). {automation} and {run} are numeric ids. An automation is only reachable under the parent it belongs to - mismatches 404.
List automations
GET /forms/{form}/automations
Returns every automation on the parent, each with its ordered steps array, newest first.
Create an automation
POST /forms/{form}/automations
Content-Type: application/json
{
"name": "Route demo requests to sales",
"trigger_type": "submission.created",
"trigger_config": {},
"is_active": true,
"steps": [
{ "position": 1, "kind": "condition", "config": { "field": "topic", "operator": "equals", "value": "demo" } },
{ "position": 2, "kind": "action", "action_key": "send_email", "config": { "to": "sales@example.com" } }
]
}
namerequired (max 120 chars)trigger_typerequired - e.g.submission.created,submission.updated,submission.tagged,submission.marked_spam,submission.starred,manual,schedule.cron,webhook.failed. Survey parents addsurvey_submission.createdandsurvey.outcome_matched; funnel parents addfunnel_submission.created. See Triggers →.trigger_config- trigger-specific options (e.g. the cron expression)is_active- defaults totruesteps- ordered list ofcondition/actionsteps;action_keypicks the action (see Actions →)
Response 201: the automation with its steps.
Show / update an automation
GET /forms/{form}/automations/{automation}
PUT /forms/{form}/automations/{automation}
PUT accepts name, description, trigger_type, trigger_config, is_active, and run_order. Steps are managed through the dashboard builder. Returns the fresh automation with steps.
Enable / disable
POST /forms/{form}/automations/{automation}/enable
POST /forms/{form}/automations/{automation}/disable
Flips is_active. Disabled automations keep their run history but stop firing on triggers.
Delete an automation
DELETE /forms/{form}/automations/{automation}
Response 200: { "ok": true }. Deletion is processed asynchronously, consistent with every destructive action on the platform.
Run manually
POST /forms/{form}/automations/{automation}/run
Queues a manual run regardless of the configured trigger. Requires the dedicated automations:run ability (separate from automations:write so editing tokens can't fire side effects).
Response 202: { "run_id": 481 } - the run executes asynchronously; poll the run endpoint for status.
List runs
GET /forms/{form}/automations/{automation}/runs?status=failed&per_page=25
Cursor-paginated run history, newest first. Filters: status (pending, running, succeeded, failed, skipped), from / to date bounds, per_page (1-100, default 25).
Response 200:
{
"data": [
{ "id": 481, "status": "failed", "started_at": "2026-06-09T08:00:01+00:00", "finished_at": "2026-06-09T08:00:04+00:00" }
],
"next_cursor": "eyJpZCI6NDgxfQ",
"prev_cursor": null
}
Pass next_cursor back as ?cursor= to fetch the next page.
Show a run
GET /forms/{form}/automations/{automation}/runs/{run}
Returns the run's scalar fields plus an ordered, typed list of step runs:
{
"id": 481,
"automation_id": 12,
"submission_id": 90341,
"status": "failed",
"started_at": "2026-06-09T08:00:01+00:00",
"finished_at": "2026-06-09T08:00:04+00:00",
"error": "send_email: SMTP 550 mailbox unavailable",
"created_at": "2026-06-09T08:00:00+00:00",
"steps": [
{ "position": 1, "kind": "condition", "status": "succeeded", "started_at": "2026-06-09T08:00:01+00:00", "finished_at": "2026-06-09T08:00:01+00:00", "duration_ms": 12, "error": null },
{ "position": 2, "kind": "action", "status": "failed", "started_at": "2026-06-09T08:00:01+00:00", "finished_at": "2026-06-09T08:00:04+00:00", "duration_ms": 2710, "error": "send_email: SMTP 550 mailbox unavailable" }
],
"failed_step_position": 2
}
Replay a run
POST /forms/{form}/automations/{automation}/runs/{run}/replay
Dispatches a fresh run against the same submission (when the original run had one). Requires automations:run.
Response 202: { "run_id": 502 } - the new run records which run it replays.
Errors
| Status | When |
|---|---|
| 402 | Team's plan doesn't include API access |
| 403 | Token missing required ability |
| 404 | Parent or automation doesn't belong to the current team, or the automation isn't owned by that parent |
| 422 | Validation failed (missing name or trigger_type, bad status filter, …) |
See also
- Automations overview → - triggers, conditions, actions, and examples
- Tokens & abilities →
- MCP server → - the same surface as agent tools (
list_automations,create_automation,run_automation,replay_automation_run, …)