> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Subscribe to a trigger (beta)

`POST /api/v1/connections/{connection_id}/trigger-subscriptions`

This endpoint is in beta. Its request and response may change.

Subscribes one connected account, or the whole connection, to a trigger. Pass `connected_account_id` for a per-account trigger, and leave it out for a per-connection trigger. Set the trigger's filters in `config`, using the keys from the trigger's `config_fields`. For a polling trigger, `interval_seconds` sets how often Scalekit checks the app; it defaults to the trigger's default interval, and a value below its minimum is refused.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `connection_id` | string | Yes | ID of the connection, in this environment. Up to 64 characters. |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `trigger_name` | string | Yes | Name of the trigger to subscribe to, as returned in the name field of [List available triggers](https://docs.scalekit.com/agentkit/reference/triggers/list-available-triggers/). Up to 128 characters. |
| `config` | object | No | Filter values for the subscription, keyed by the trigger's config_fields keys, spelled exactly as returned. Every required field must be set. An unknown key, or a value longer than 512 characters, is refused. Subscribing again with different values creates another subscription; subscribing again with identical values returns 409. |
| `connected_account_id` | string | No | Connected account to subscribe on, for an account-scoped trigger. Omit it for a connection-scoped trigger — the trigger is then subscribed on the connection itself and no account is named. Whether omitting it is valid depends on the trigger's own delivery_scope. |
| `interval_seconds` | integer | No | Polling interval in seconds, for a polled trigger only. Omit it to use the trigger's default_interval_seconds. A value below the trigger's min_interval_seconds is refused, naming the minimum, rather than rounded up. Setting it for a webhook trigger is refused. The subscription can run slower than requested when the environment's polling budget is shared across many polled subscriptions; effective_interval_seconds on the response shows the interval it runs at. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `account_health` | string (enum) | How the subscribed account stands for this trigger. AWAITING_CONFIRMATION means Scalekit cannot route this trigger's events to the account yet, so the subscription will not fire until the account's user reconnects it. Absent for connection-scoped subscriptions. One of: `READY`, `AWAITING_CONFIRMATION`, `WRONG_APP`, `DISCONNECTED`, `NEEDS_REAUTHENTICATION`. |
| `config` | object | The subscription's filter values, keyed by the trigger's config_fields keys. Keys are returned exactly as stored; send them back without changing their case. |
| `connected_account_id` | string | ID of the subscribed connected account. Empty for a connection-scoped subscription. |
| `connected_account_identifier` | string | The identifier the connected account was created with, your app's ID for the user, such as `user_123`, so you can label the subscription without fetching each account. Empty for a connection-scoped subscription, and empty when the account has no identifier recorded — fall back to connected_account_id rather than showing a blank. |
| `connection_id` | string | ID of the connection the subscription belongs to. |
| `created_at` | string | When the subscription was created. Returned so a list can be ordered or explained by age without a second lookup. |
| `delivery_scope` | string (enum) | Whether this subscription receives one event per connected account or one event for the whole connection. A connection-scoped subscription carries no connected_account_id — the connection is the only recipient. One of: `ACCOUNT`, `CONNECTION`. |
| `effective_interval_seconds` | integer | The polling interval, in seconds, the subscription actually runs at. Larger than requested_interval_seconds when the environment's polling budget is shared across many polled subscriptions; the subscription's status is then THROTTLED. Zero for a webhook trigger. |
| `id` | string | Unique identifier of the trigger subscription. |
| `poll_state` | object | How a POLL subscription's feed is doing: when it last ran, why the last run failed, and whether polling is held off. Absent for a WEBHOOK subscription, which is never polled. |
| `poll_state.backoff_until` | string | Polling is held off until this time, because the provider asked Scalekit to slow down or a run failed in a way retrying cannot fix. Absent when no hold-off has been recorded. A time in the past means the hold-off has ended and the next scheduled run polls again. |
| `poll_state.consecutive_failures` | integer | How many runs in a row have failed. Zero after any successful run. |
| `poll_state.last_error` | string | A short, human-readable explanation of why the most recent run failed and what happens next. Empty when the most recent run succeeded or no run has happened yet. Chosen from a fixed set of messages by last_error_code and never contains the provider's response. The wording can change: match on last_error_code, not on this text. |
| `poll_state.last_error_code` | string (enum) | Why the most recent run failed, as a stable code to branch on. TRIGGER_POLL_ERROR_CODE_UNSPECIFIED when the most recent run succeeded or no run has happened yet. CREDENTIAL_REVOKED and INVALID_CONFIGURATION need a change from you before polling can succeed; every other code is retried automatically. One of: `RATE_LIMITED`, `CREDENTIAL_REVOKED`, `INVALID_CONFIGURATION`, `PROVIDER_ERROR`, `DELIVERY_FAILED`, `TIMED_OUT`, `POLL_FAILED`. |
| `poll_state.last_run_at` | string | When Scalekit last polled the provider for this subscription, whether or not the run succeeded. Absent until the first run. A value far older than the effective interval means the feed has stopped running. |
| `poll_state.watermark_updated_at` | string | When the feed's position last moved forward — the last time a run found and delivered newer events. A run that finds nothing new leaves it unchanged. |
| `provider` | string | The provider the trigger belongs to. |
| `requested_interval_seconds` | integer | The polling interval, in seconds, the subscription asked for, or the trigger's default when it did not set one. Returned next to effective_interval_seconds so a subscription running slower than requested is visible. Zero for a webhook trigger. |
| `status` | string (enum) | Whether the subscription is delivering. ACTIVE — delivering. THROTTLED — delivering, but polling slower than requested; compare requested_interval_seconds with effective_interval_seconds. PAUSED — stopped by you. PAUSED_CREDENTIAL — stopped because the account's credential no longer works. One of: `ACTIVE`, `THROTTLED`, `PAUSED`, `PAUSED_CREDENTIAL`. |
| `trigger_name` | string | Name of the subscribed trigger, as returned by [List available triggers](https://docs.scalekit.com/agentkit/reference/triggers/list-available-triggers/). |

**Errors**

- `400`: Invalid request - the message names what to change. Returned when an ID is malformed; config holds an unknown key, misses a required key, or holds a value longer than 512 characters; interval_seconds is below the trigger's minimum, or is set for a webhook trigger; connected_account_id is missing for an account-scoped trigger, or present for a connection-scoped one; the trigger polls and is connection-scoped, which is not supported; or the account cannot receive the trigger because its grant lacks a required scope or the bot install the trigger needs, it was authorized under a different app, the trigger needs your own provider app, its provider workspace or user is not yet confirmed, or it holds no usable credential
- `404`: Not found - the connection or connected account does not exist in this environment, the connected account belongs to a different connection, the connection's provider publishes no trigger with this name, or Triggers isn't turned on for your environment
- `409`: Conflict - this account, or this connection for a connection-scoped trigger, already has a subscription to this trigger with exactly these config values
- `500`: Internal error - the subscription could not be created; nothing was created
- `503`: Service unavailable - polling for the new subscription could not be scheduled, so the subscription was not created; retry the same request

**Request**

```bash
curl -sS -X POST \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/connections/conn_133400101014995480/trigger-subscriptions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "trigger_name": "salesforce_lead_created",
    "connected_account_id": "ca_133400349586228019",
    "config": {
      "lead_source": "Web"
    },
    "interval_seconds": 300
  }'
```

**Response**

```json
{
  "id": "trgs_141020933185734981",
  "connected_account_id": "ca_133400349586228019",
  "connected_account_identifier": "user_123",
  "connection_id": "conn_133400101014995480",
  "provider": "salesforce",
  "trigger_name": "salesforce_lead_created",
  "status": "ACTIVE",
  "delivery_scope": "ACCOUNT",
  "requested_interval_seconds": 300,
  "effective_interval_seconds": 300,
  "config": {
    "lead_source": "Web"
  },
  "created_at": "2026-10-28T09:12:44.120Z",
  "poll_state": {
    "last_error": "",
    "last_error_code": "TRIGGER_POLL_ERROR_CODE_UNSPECIFIED",
    "consecutive_failures": 0,
    "watermark_updated_at": "2026-10-28T09:12:44.120Z"
  },
  "account_health": "READY"
}
```

**Python SDK:** `scalekit_client.actions.triggers.create_subscription`

Subscribe a connected account, or the whole connection, to a trigger. Not retried on `UNAVAILABLE`: a retry could create the subscription twice. Creating the same subscription again raises `ScalekitConflictException`.

```python
scalekit_client.actions.triggers.create_subscription(
    connection_id: str,
    trigger_name: str,
    connected_account_id: str | None = None,
    interval: timedelta | None = None,
    config: Mapping[str, str] | None = None,
) -> TriggerSubscription
```

Example:

```python
from datetime import timedelta

result = scalekit_client.actions.triggers.create_subscription(
    connection_id="conn_133400101014995480",
    trigger_name="salesforce_lead_created",
    connected_account_id="ca_133400349586228019",
    interval=timedelta(minutes=5),
    config={"lead_source": "Web"},
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `connection_id` | `str` | Yes | The connection (`conn_...`). |
| `trigger_name` | `str` | Yes | `AvailableTrigger.name`. |
| `connected_account_id` | `str \| None` | No | The account (`ca_...`). Leave out only for a connection-scoped trigger. |
| `interval` | `timedelta \| None` | No | Poll interval for a poll trigger, in whole seconds; at least the trigger's `min_interval`. Leave out for the default and for webhook triggers. |
| `config` | `Mapping[str, str] \| None` | No | Values for the trigger's `config_fields`. |

Returns `TriggerSubscription`: The new subscription.


Part of [Triggers](https://docs.scalekit.com/agentkit/reference/triggers/) in the [AgentKit API reference](https://docs.scalekit.com/agentkit/reference/). Authentication: https://docs.scalekit.com/agentkit/reference/authentication.md. Errors and rate limits: https://docs.scalekit.com/agentkit/reference/errors.md. Pagination: https://docs.scalekit.com/agentkit/reference/pagination.md


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
