curl --request POST \
--url https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"payload": {
"email": "jane@example.com",
"firstName": "Jane"
}
}
'import requests
url = "https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire"
payload = { "payload": {
"email": "jane@example.com",
"firstName": "Jane"
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({payload: {email: 'jane@example.com', firstName: 'Jane'}})
};
fetch('https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'payload' => [
'email' => 'jane@example.com',
'firstName' => 'Jane'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire"
payload := strings.NewReader("{\n \"payload\": {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"payload\": {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"payload\": {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\"\n }\n}"
response = http.request(request)
puts response.read_body{
"triggerInstanceId": "tin_4fZ2kQ9pLm7xR1tV8wYcD",
"triggerEventId": "user_signed_up",
"status": "replayed",
"automationRunIds": [
"jh7acthhe99pq4448xh83gn54x8eennb"
],
"publishedAutomations": [
{
"automationId": "M3nRk8LqW2xT5vBp9YcZd",
"name": "Welcome flow"
}
],
"counts": {
"automations": 1,
"skipped": 0
},
"warnings": [],
"receivedAt": "2026-04-08T12:34:56.789Z"
}Fire a trigger
Fires the trigger: validates the payload against the stored contract, upserts the contact it describes, then starts one run per published automation attached to the trigger.
Use when an event in your product should start every published automation attached to this trigger.
Input { payload }, validated against the trigger’s payloadSchema. Unknown fields are accepted and reported in warnings[]. The contact derived from the payload is upserted before the fan-out.
Returns 202 { triggerInstanceId, triggerEventId, status, automationRunIds[], publishedAutomations[], counts, warnings[], receivedAt }. Follow a run with getAutomationRun, the fire itself with getTriggerInstance. counts.skipped is the recipients a suppression already covered, so automations: 2, skipped: 2 means nothing was delivered.
Idempotency send a stable Idempotency-Key header on every retry. A repeat answers 200 with status: "replayed" and the ORIGINAL run ids; nothing fires twice.
Errors 400 INVALID_PAYLOAD when the payload does not satisfy the schema; 404 TRIGGER_EVENT_NOT_FOUND for an unknown or cross-brand id; 422 NO_PUBLISHED_AUTOMATION when nothing published listens for the trigger; 409 IDEMPOTENCY_CONFLICT when a key is reused with a different body.
See also checkTriggerReady, getTriggerInstance, listAutomationRuns.
curl --request POST \
--url https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"payload": {
"email": "jane@example.com",
"firstName": "Jane"
}
}
'import requests
url = "https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire"
payload = { "payload": {
"email": "jane@example.com",
"firstName": "Jane"
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({payload: {email: 'jane@example.com', firstName: 'Jane'}})
};
fetch('https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'payload' => [
'email' => 'jane@example.com',
'firstName' => 'Jane'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire"
payload := strings.NewReader("{\n \"payload\": {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"payload\": {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/automations/triggers/{triggerEventId}/fire")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"payload\": {\n \"email\": \"jane@example.com\",\n \"firstName\": \"Jane\"\n }\n}"
response = http.request(request)
puts response.read_body{
"triggerInstanceId": "tin_4fZ2kQ9pLm7xR1tV8wYcD",
"triggerEventId": "user_signed_up",
"status": "replayed",
"automationRunIds": [
"jh7acthhe99pq4448xh83gn54x8eennb"
],
"publishedAutomations": [
{
"automationId": "M3nRk8LqW2xT5vBp9YcZd",
"name": "Welcome flow"
}
],
"counts": {
"automations": 1,
"skipped": 0
},
"warnings": [],
"receivedAt": "2026-04-08T12:34:56.789Z"
}Authorizations
Send your Brew API key as Authorization: Bearer brew_xxx.
Headers
Optional idempotency key for safe retries. Reusing the same key with the same request body returns the original response for 24 hours.
1 - 100The brand this request acts on. REQUIRED for organization-scoped credentials (otherwise 400 BRAND_ID_REQUIRED — there is no default brand); list ids with GET /v1/brands. Brand-scoped credentials may omit it, and sending a different brand returns 403 BRAND_SCOPE_MISMATCH. A brand outside your organization returns 404 BRAND_NOT_FOUND.
1 - 64Path Parameters
Trigger id returned by POST /v1/automations/triggers. Custom triggers use tri_… ids; integration triggers use composite ids (e.g. clerk:org_…:brand_…:user.created, URL-encode the colons).
1 - 256"user_signed_up"
Body
Event payload — fields and types must match the trigger's payloadSchema. Unknown fields are accepted but reported as unexpected_key warnings.
Show child attributes
Show child attributes
Response
Idempotent replay: this Idempotency-Key already fired. The ids are the original run’s.
The persisted inbound row — GET /v1/automations/trigger-instances/{triggerInstanceId} for its match state.
1 - 256triggered = this call started the runs. replayed = the same Idempotency-Key already fired; nothing ran twice.
triggered, replayed The runs this fire started — GET /v1/automations/runs/{automationRunId}.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Was this page helpful?