Actions
| Action key | Config | Notes |
|---|---|---|
send_email |
to, subject, body |
All values are templated - {{ submission.email }} works. |
send_webhook |
url, headers?, include_submission? |
JSON POST. |
tag_submission |
tag |
Adds to submission.tags. |
set_submission_status |
status |
One of `received |
mark_spam |
- | Shorthand for status=spam. |
update_field |
field, value |
Mutates submission.payload. |
http_request |
method, url, headers?, body? |
Generic call. |
ai_classify |
- | Runs the same classifier the AI queue uses. |
integration_driver |
provider, url, config? |
Invoke a Slack/Discord/Sheets driver without a Webhook row. |
Templating
String config values can reference submission data, for example {{ submission.email }} in an email recipient or body. Keep templates simple and prefer field names that already exist in the stored payload. If a field may be empty, add a condition step before the action so the run fails intentionally early instead of sending incomplete data.
Failure behavior
Action failures stop the run unless the step has continue_on_failure enabled. Use that flag only for optional side effects. For example, a Slack notification can often fail without blocking a later tag, but a failed CRM sync should usually remain visible so the run can be replayed after credentials are fixed.
External calls
Use send_webhook when you want Formspring's standard JSON payload. Use http_request when you need a custom method, headers, or body shape. Use integration_driver when the destination is one of the built-in providers and you want the driver to format the payload for that service.
Data mutation
tag_submission, set_submission_status, mark_spam, and update_field change the submission record. Put those after any notification or sync step that depends on the original payload, and keep the run history in mind when you replay a failed run.