Skip to content

Run an automation for a contact

POST
https://api.getsitecontrol.com/v1/sites/{site_id}/automations/{automation_id}/runs
curl --request POST \
--url https://api.getsitecontrol.com/v1/sites/1/automations/1/runs \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "contact": { "email": "jane@example.com", "first_name": "Jane" }, "data": { "order_id": "A-981", "total": 129.9 } }'

Queues a run of the automation for one contact and answers 202 at once. Runs an automation that is on and has the manual or the webhook trigger (find them with list_automations by trigger_type, is_active set to true). Needs the emails.full permission.

The body names the contact by contact_id or gives it as contact, exactly one of the two. contact is created or updated by e-mail as upsert_contact does, then run; a status the contact cannot take refuses the run and writes nothing. It needs contacts.edit on top of emails.full and spends the contact creation limit, even when the automation refuses the run. A limit hit here is not kept under the Idempotency-Key: the same key runs again once the window passes. The contact and the run are saved together: on 202 both are; on any error, neither is.

The two triggers run differently:

  • manual is a sequence of steps that other automations start too. A contact is in it once at a time: while its run is queued or going on, a new run is refused. Once the run finishes, the contact may be run again. Other manual starts (the dashboard, contact imports, the “start automation” step) honour the same check; starts by other trigger types and bulk event packs are not seen by it. A run that failed may be repeated at once through this operation only: the other manual starts skip a contact whose run in this automation failed. data is not read.
  • webhook takes an event with its values: every call is a new run, also for a contact already in the automation. data reaches the steps as {{$webhook.<key>}}, the values its e-mails and conditions use; the contact is {{$contact.<field>}}. The automation’s webhook_url from get_automation starts the same automation without credentials, for a service that can only send a request: it takes a flat body, finds the contact in it and answers before the automation is checked. Its whole body is $webhook, while here $webhook holds only data: a value the automation reads from $webhook, the e-mail included, goes into data.

The response carries no run id: the run waits to start; follow it with list_automation_runs by contact_id and order=newest. Send an Idempotency-Key to retry safely: a retry with the same key gets the stored 202, not a 409.

An unsubscribed contact is run as well, but the steps send it no e-mails.

FieldDescription
site_id
required
Site Id
integer
automation_id
required
Automation Id

Automation id from list_automations

integer

Automation id from list_automations

FieldDescription
Idempotency-Key
Idempotency-Key

Makes a retry of a POST safe: a repeat with the same key, body and GSC-Version returns the stored response with Idempotency-Replayed: true instead of running again. The key protects against repeated execution while the key store works. Saving the change and storing the response under the key are not atomic: if the process or the key store fails between them, the change is kept, the key is released after 15 minutes and a retry runs the request again. After a timeout or a 5xx, read the resource to check the result before retrying. 5xx and 429 responses and responses over 256 KB are not stored, so a repeat runs the request again. A key is kept for 24 hours. The same key with another body or version is 422; a repeat while the first request runs is 409.

string
>= 1 characters <= 128 characters /^[A-Za-z0-9_-]+$/

Makes a retry of a POST safe: a repeat with the same key, body and GSC-Version returns the stored response with Idempotency-Replayed: true instead of running again. The key protects against repeated execution while the key store works. Saving the change and storing the response under the key are not atomic: if the process or the key store fails between them, the change is kept, the key is released after 15 minutes and a retry runs the request again. After a timeout or a 5xx, read the resource to check the result before retrying. 5xx and 429 responses and responses over 256 KB are not stored, so a repeat runs the request again. A key is kept for 24 hours. The same key with another body or version is 422; a repeat while the first request runs is 409.

Media typeapplication/json
AutomationRunCreate

Exactly one of contact_id and contact.

object
FieldDescription
contact_id
Contact Id

Id of an existing contact of the site, from list_contacts; leave it out when contact is given

integer
contact
Contact

A contact by e-mail, created or updated as upsert_contact does, then run; email is required. A status the contact cannot take refuses the run. Leave it out when contact_id is given. Needs the contacts.edit permission

object
FieldDescription
email
required
Email

Finds the contact, without case; kept as stored when found, stored in lower case when created

string
<= 250 characters
status
Status

subscribed or unsubscribed; bounced is set only by e-mail delivery. Left out: unchanged, a new contact is subscribed; may not be null

string
Allowed values: subscribed unsubscribed
first_name
First Name

Null clears it

string
nullable <= 250 characters
last_name
Last Name

Null clears it

string
nullable <= 250 characters
country
Country

ISO 3166-1 alpha-2 code or an English country name; stored as the code; null clears it

string
nullable <= 250 characters
phone
Phone

In the international format, or national with country in the same request; stored normalized; null clears it

string
nullable <= 250 characters
timezone
Timezone

IANA time zone name such as Europe/Berlin; null clears it

string
nullable <= 250 characters
language
Language

ISO 639-1 code such as de; stored in lower case; null clears it

string
nullable <= 250 characters
fields
Fields

Values by field id from list_contact_fields: a string for text, a whole number for integer, a number, an ISO 8601 string for a datetime (UTC without an offset), YYYY-MM-DD for a date, true or false for a boolean. Fields of the other type are read-only. Merged into the stored values: null removes a value, keys not given stay as they are

object
FieldDescription
key
additional properties
Allowed types:
stringintegernumberboolean
string:
<= 1000 characters
add_tags
Add Tags

Tag names to add, compared without case; a tag the site does not have is created. Tags the contact has stay

Array<string>
<= 100 items
remove_tags
Remove Tags

Tag names to remove, compared without case; a name with no tag, or a tag the contact does not have, is no change. Never creates a tag

Array<string>
<= 100 items
data
Data

Values for the steps of an automation with the webhook trigger: each key is {{$webhook.<key>}} in its e-mails and conditions. $webhook holds only these values; the contact is {{$contact.<field>}}. A manual automation does not read them.

object

Example

{
"contact": {
"email": "jane@example.com",
"first_name": "Jane"
},
"data": {
"order_id": "A-981",
"total": 129.9
}
}

Successful Response

Media typeapplication/json
AutomationRunQueued
object
FieldDescription
automation_id
required
Automation Id
integer
contact_id
required
Contact Id

The contact run; for contact, the one created or found

integer

Example · Generated

{
"automation_id": 1,
"contact_id": 1
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Idempotency-Replayed
string

True when the response is a stored one, replayed

Unsupported GSC-Version

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Missing or invalid API key or access token

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

WWW-Authenticate
string

Authentication scheme: Bearer

Media typeapplication/problem+json

forbidden: no emails.full permission, or no contacts.edit for contact; account_suspended: the site is suspended; feature_unavailable: the plan has no automations

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

site_not_found, automation_not_found; contact_not_found: no contact of the site with contact_id

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Media typeapplication/problem+json

automation_inactive: the automation is off, turn it on with enable_automation; automation_not_startable: its trigger is neither manual nor webhook; run_in_progress: the contact is in this manual automation, metadata.state is queued (waiting to start) or ongoing (going on, waiting in a delay or on hold); contact_email_taken: another request took the e-mail of contact at the same moment; idempotency_in_progress: a request with the same Idempotency-Key is still running

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Request body too large

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Media typeapplication/problem+json

validation_failed; for contact, a field, tag or status transition refused, or the contact unreadable; idempotency_key_reused

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Rate limited

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Retry-After
integer

Seconds until the bucket refills

Media typeapplication/problem+json

temporarily_unavailable: for manual, a bulk start of this automation was being saved and the call waited for it longer than the 25-second request timeout, or rate limits or idempotency keys cannot be enforced; retry later

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds