---
title: "Create an automation: a trigger plus ordered steps (email, webhook, A/B split), or Resend’s graph of steps and connections (delay, wait for event, condition,…"
method: POST
path: "/automations"
tags: ["automations"]
---

# Create an automation: a trigger plus ordered steps (email, webhook, A/B split), or Resend’s graph of steps and connections (delay, wait for event, condition,…

`POST /automations`

## Request

- Base URL: `https://api.agentisend.com`
- URL: `https://api.agentisend.com/automations`
- Auth: HTTP bearer

Create an automation: a trigger plus ordered steps (email, webhook, A/B split), or Resend’s graph of steps and connections (delay, wait for event, condition, send email, contact update and delete, add to segment).

## Headers

- `Idempotency-Key` string
- `Resend-Idempotency-Key` string

## Request body

- PostAutomationsBody
  - `name` string, required
  - `status` 'enabled' | 'disabled': enabled starts firing now. A graph defaults to disabled; a linear automation is a draft until enabled.
  - `trigger` object: Linear automations: what starts a run.
    - `type` 'custom_event' | 'contact.created' | 'contact.updated' | 'segment.joined' | 'segment.left' | 'scheduled', required
    - `event_name` string
    - `segment_id` string, uuid
    - `interval_minutes` integer
  - `steps` object[], required: Linear: ordered steps with kind email, webhook or ab_split, beside a trigger. Graph (Resend): steps with key, type (trigger, delay, send_email, wait_for_event, condition, contact_update, contact_delete, add_to_segment) and config, sent together with connections. A graph has exactly one trigger step, at most 150 steps, every step reachable from the trigger and no loops.
  - `connections` object[]: Graph only: the links between steps, by key. type is default, condition_met / condition_not_met from a condition, or event_received / timeout from a wait_for_event. Sent together with steps.
    - `from` string, required: The key of the step the connection leaves.
    - `to` string, required: The key of the step it leads to.
    - `type` 'default' | 'condition_met' | 'condition_not_met' | 'timeout' | 'event_received': default, or condition_met / condition_not_met from a condition, or event_received / timeout from a wait_for_event.

## Response `201`

Success

- PostAutomationsReply
  - `object` 'automation', required
  - `id` string, uuid, required
  - `name` string, required
  - `status` string, required
  - `format` 'linear' | 'graph', required
  - `trigger` object, required
    - `type` 'custom_event' | 'contact.created' | 'contact.updated' | 'segment.joined' | 'segment.left' | 'scheduled', required
    - `event_name` string
    - `segment_id` string, uuid
    - `interval_minutes` integer
  - `steps` unknown[], required
    - unknown
  - `connections` object[], required
    - `from` string, required
    - `to` string, required
    - `type` 'default' | 'condition_met' | 'condition_not_met' | 'timeout' | 'event_received', required
  - `current_version` integer, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required

## Other responses

- `400`: The request is malformed or a field failed validation. Codes: validation_error, invalid_idempotency_key, invalid_cursor, plan_not_purchasable, stripe_signature_invalid, support_upload_rejected, sign_in_check_required.
- `401`: No usable credential was sent. Codes: missing_api_key, session_required, mfa_required.
- `403`: The credential may not do this, or the account or key is stopped. Codes: sending_domain_blocked, young_domain_held, domain_sending_disabled, domain_not_verified, onboarding_recipient_not_a_member, onboarding_sender_unavailable, account_suspended, account_sandboxed, human_action_required, csrf_origin_rejected, charge_not_this_account, invalid_api_key, restricted_api_key, insufficient_role, invite_email_mismatch, domain_scope_violation, dedicated_ip_assigned_by_us, approval_required, staff_review_required, trust_paused, kill_switch_active.
- `404`: Nothing with this id exists on the account. Codes: billing_customer_missing, not_found, session_expired, support_ticket_not_found.
- `409`: The request conflicts with the current state. Codes: domain_already_exists, template_name_taken, template_alias_taken, template_in_use, segment_in_use, contact_resubscribe_required, email_still_scheduled, domain_verified_elsewhere, domain_not_claimable, return_path_subdomain_in_use, overage_not_on_plan, term_not_on_sale, subscription_active, portal_change_unavailable, already_in_account, idempotency_in_flight, idempotency_payload_mismatch, approval_expired, support_closed, support_reopen_expired, support_merge_conflict, support_reply_too_soon.
- `413`: The request body is larger than this operation accepts. Codes: payload_too_large, support_upload_too_large.
- `415`: The request body is not JSON. Codes: unsupported_media_type.
- `429`: A rate, quota or ramp ceiling was reached. Codes: onboarding_daily_cap_reached, trust_throttled, invite_limit_reached, rate_ceiling_exceeded, daily_quota_exceeded, monthly_quota_exceeded, rate_limit_exceeded, support_rate_limited.
- `500`: Something failed on our side. Codes: internal_server_error.

---

[API](https://skmtc.dev/agentisend/apis/agentisend-api.md) · [All operations](https://skmtc.dev/agentisend/apis/agentisend-api/llms.txt) · [OpenAPI document](https://skmtc.dev/agentisend/apis/agentisend-api/revisions/3066dda62a56?raw)
