---
title: "Create a trigger"
method: POST
path: "/v1/automations/triggers"
tags: ["Automations"]
---

# Create a trigger

`POST /v1/automations/triggers`

Creates a custom trigger event definition — the contract automations subscribe to. Body carries `{ title, description?, payloadSchema }`; the server mints `triggerEventId` and hardcodes `provider: "brew_api"`. Integration triggers (clerk, stripe, shopify, …) are provisioned by the corresponding integration only.

`payloadSchema.fields` MUST declare `{ key: "email", type: "string", required: true }` so downstream automations can resolve a recipient. Returns `201` with the bare trigger row.

## Headers

- `Idempotency-Key` string

## Request body

- TriggersPostRequest
  - `title` string, required
  - `description` string
  - `payloadSchema` object, required
    - `type` 'object', required
    - `fields` object[], required
      - `key` string, required — Variable name used by emails and automations, e.g. email or firstName. Prefer self-descriptive keys; this column has no separate description field.
      - `type` 'string' | 'int' | 'boolean', required
      - `required` boolean, required
      - `fallbackValue` union — Substitution value when the inbound payload is missing this field. Also used as the email agent's `e.g. {{ key | fallback }}` example.
        - string
        - number
        - boolean
      - `pii` 'none' | 'low' | 'high' — PII classification for redaction. "high" auto-redacts the value in execution logs and the inbound log. "low" (default when omitted) preserves the value. "none" is an explicit marker that the field is non-personal.

## Response `201`

Created. The bare trigger row.

- TriggerRow
  - `triggerEventId` string, required
  - `title` string, required
  - `description` string
  - `provider` 'brew_api' | 'clerk' | 'stripe' | 'shopify' | 'stytch' | 'supabase' | 'workos' | 'revenuecat' | 'custom', required
  - `providerEventKey` string
  - `payloadSchema` object, required
    - `type` 'object', required
    - `fields` object[], required
      - `key` string, required — Variable name used by emails and automations, e.g. email or firstName. Prefer self-descriptive keys; this column has no separate description field.
      - `type` 'string' | 'int' | 'boolean', required
      - `required` boolean, required
      - `fallbackValue` union — Substitution value when the inbound payload is missing this field. Also used as the email agent's `e.g. {{ key | fallback }}` example.
        - string
        - number
        - boolean
      - `pii` 'none' | 'low' | 'high' — PII classification for redaction. "high" auto-redacts the value in execution logs and the inbound log. "low" (default when omitted) preserves the value. "none" is an explicit marker that the field is non-personal.
  - `createdAt` string, date-time, required
  - `updatedAt` string, date-time, required

## Other responses

- `400` — Strict-body violation — unknown keys (including `provider` / `providerEventKey`) or a payload schema without the required `email` field.
- `401` — The API key was missing, invalid, or revoked.
- `403` — The caller does not have the required `automations` permission.
- `409` — The same `Idempotency-Key` was reused with a different request body.
- `429` — The request hit the rolling rate limit window.
- `500` — Unexpected internal error.

---

[API](https://skmtc.net/brew/apis/brew-public-api-v1.md) · [All operations](https://skmtc.net/brew/apis/brew-public-api-v1/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/brew/brew-public-api-v1/versions/db96cfedc6c5/schema)
