Events

Subscribe to events generated by Motor. Included with the services that use them. The base URL is https://www.motor.dev/meta, and the OpenAPI 3.1 specification describes each endpoint.

Try it

Sign in to try the API here with one of your team's keys. Requests use that key's permissions and spending limit. Standard charges apply.

Subscribe to Motor events

Receive notifications when resources in Motor change. Motor generates these events; the separately planned webhook service will deliver your application's own events. Register a public HTTPS receiver with POST /meta/event_subscriptions. Choose the events and feature flag environments to subscribe to. Your secret key must have admin access to those environments. Only feature flag event names and the wildcard feature_flags.* are currently supported.

curl https://api.motor.dev/meta/event_subscriptions \
  -H "Authorization: Bearer $MOTOR_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://app.example.com/hooks/motor", "events": ["feature_flags.flag.updated"], "environment_ids": ["ffe_..."]}'

Save the signing secret returned when you create the endpoint. Verify signatures before processing incoming events. Endpoint updates use the endpoint's own ETag in If-Match. Each team can have up to 20 active endpoints. Feature flag event delivery is included in feature flag pricing.

Use /event_subscriptions/{endpoint_id}/deliveries to inspect delivery attempts, and /events to read the team's event history. Both paths are relative to https://api.motor.dev/meta. The reference below also covers test deliveries, signing secret rotation, and manual retries.

Verify and acknowledge deliveries

POST /meta/event_subscriptions subscribes an HTTPS URL to events, such as feature_flags.flag.updated or feature_flags.*. Events identify the changed resource and revision. Fetch the configuration if you need the updated rules or values.

Check each delivery's signature with the endpoint's secret:

header = request.headers["Motor-Signature"]        # t=1790000000,v1=5257a8...
t, signatures = parse(header)
key = base64url_decode(secret.removeprefix("whsec_"))
expected = hex(hmac_sha256(key, t + "." + raw_body))
assert any(constant_time_equal(expected, s) for s in signatures)
assert abs(now() - int(t)) <= 300
skip if Motor-Event-Id was seen before

Return a 2xx response within 10 seconds to acknowledge delivery. Motor retries failed deliveries after 1, 5, and 15 minutes, then 1, 4, 12, 24, and 48 hours. Deliveries are processed in commit order for each endpoint. A failed event blocks later events for at most 24 hours; manual retries can arrive out of order. Use event revisions to detect older updates. A 410 response stops retries. Delivery is at least once, so use Motor-Event-Id to ignore duplicate events. Endpoints with "format": "slack", "discord", or "teams" receive summaries formatted for those services.

Authentication and retries

Authenticate with Authorization: Bearer <credential>. POST requests that create or change resources require an Idempotency-Key. Retry a lost response with the same key, body, and headers to recover the original response for up to 35 days. For feature flags, omit Motor-Mode or set it to live; test is not supported. These APIs add no separate usage charge, but the underlying service's permissions and limits still apply.

Event subscriptions

POST/meta/event_subscriptions

Create a event subscription

Creates an endpoint for signed events. The response shows the signing secret once. Credentials: a secret key.

ParameterLocationDescription
Request body
{
  "url": "https://hooks.example.com/motor",
  "events": [
    "feature_flags.*"
  ],
  "environment_ids": [
    "ffe_UJAs9eZep7hvba6xBh5dvY"
  ],
  "description": "Deploy bot"
}
FieldTypeDescription
urlrequiredstringA public HTTPS URL on port 443, at most 2,048 bytes, without credentials or a fragment.
eventsrequiredarrayEvent types, or feature_flags.*.
environment_idsrequiredarray
descriptionstring
enabledboolean
formatstring
Responses

201Success.

{
  "id": "whe_V1nN1KXCbpCbzw7NKeYxfs",
  "url": "https://hooks.example.com/motor",
  "events": [
    "feature_flags.*"
  ],
  "environment_ids": [
    "ffe_UJAs9eZep7hvba6xBh5dvY"
  ],
  "description": "Deploy bot",
  "enabled": true,
  "disabled_reason": null,
  "format": "motor",
  "version": "1",
  "secret_rotation_ends_at": null,
  "created_at": "2026-10-05T00:08:33Z",
  "updated_at": "2026-10-05T00:08:33Z",
  "secret": "whsec_EXAMPLE_NOT_A_REAL_SECRET"
}

401

409

422

429

GET/meta/event_subscriptions

List event subscriptions

Lists the team's endpoints. Credentials: a secret key.

ParameterLocationDescription
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "whe_V1nN1KXCbpCbzw7NKeYxfs",
      "url": "https://hooks.example.com/motor",
      "events": [
        "feature_flags.*"
      ],
      "environment_ids": [
        "ffe_UJAs9eZep7hvba6xBh5dvY"
      ],
      "description": "Deploy bot",
      "enabled": true,
      "disabled_reason": null,
      "format": "motor",
      "version": "1",
      "secret_rotation_ends_at": null,
      "created_at": "2026-10-05T00:08:33Z",
      "updated_at": "2026-10-05T00:08:33Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/meta/event_subscriptions/{endpoint_id}

Get a event subscription

Returns an endpoint. Credentials: a secret key.

ParameterLocationDescription
endpoint_idpath
Responses

200Success.

{
  "id": "whe_V1nN1KXCbpCbzw7NKeYxfs",
  "url": "https://hooks.example.com/motor",
  "events": [
    "feature_flags.*"
  ],
  "environment_ids": [
    "ffe_UJAs9eZep7hvba6xBh5dvY"
  ],
  "description": "Deploy bot",
  "enabled": true,
  "disabled_reason": null,
  "format": "motor",
  "version": "1",
  "secret_rotation_ends_at": null,
  "created_at": "2026-10-05T00:08:33Z",
  "updated_at": "2026-10-05T00:08:33Z"
}

401

404

429

PATCH/meta/event_subscriptions/{endpoint_id}

Update a event subscription

Changes an endpoint. Credentials: a secret key.

ParameterLocationDescription
endpoint_idpath
Request body
{
  "description": "Deploy notifications"
}
FieldTypeDescription
urlstringA public HTTPS URL on port 443, at most 2,048 bytes, without credentials or a fragment.
eventsarrayEvent types, or feature_flags.*.
environment_idsarray
descriptionstring
enabledboolean
formatstring
Responses

200Success.

{
  "id": "whe_V1nN1KXCbpCbzw7NKeYxfs",
  "url": "https://hooks.example.com/motor",
  "events": [
    "feature_flags.*"
  ],
  "environment_ids": [
    "ffe_UJAs9eZep7hvba6xBh5dvY"
  ],
  "description": "Deploy notifications",
  "enabled": true,
  "disabled_reason": null,
  "format": "motor",
  "version": "2",
  "secret_rotation_ends_at": null,
  "created_at": "2026-10-05T00:08:33Z",
  "updated_at": "2026-10-05T00:08:42Z"
}

401

404

412

422

428

429

DELETE/meta/event_subscriptions/{endpoint_id}

Delete a event subscription

Deletes an endpoint and cancels its pending deliveries. A delivery already in progress may still complete; in_flight_may_complete indicates whether there was an active delivery when deletion began. Credentials: a secret key.

ParameterLocationDescription
endpoint_idpath
Responses

200Success.

{
  "id": "whe_V1nN1KXCbpCbzw7NKeYxfs",
  "deleted": true,
  "in_flight_may_complete": true
}

401

404

412

428

429

POST/meta/event_subscriptions/{endpoint_id}/rotate_secret

Rotate a signing secret

Creates a new signing secret and returns it in this response. During the rotation overlap period, each delivery includes signatures made with both the old and new secrets. Credentials: a secret key.

ParameterLocationDescription
endpoint_idpath
Request body
{
  "overlap_seconds": 3600
}
FieldTypeDescription
overlap_secondsinteger0 to 86,400. Default 86,400.
Responses

200Success.

{
  "id": "whe_V1nN1KXCbpCbzw7NKeYxfs",
  "url": "https://hooks.example.com/motor",
  "events": [
    "feature_flags.*"
  ],
  "environment_ids": [
    "ffe_UJAs9eZep7hvba6xBh5dvY"
  ],
  "description": "Deploy notifications",
  "enabled": true,
  "disabled_reason": null,
  "format": "motor",
  "version": "3",
  "secret_rotation_ends_at": "2026-10-05T01:08:45Z",
  "created_at": "2026-10-05T00:08:33Z",
  "updated_at": "2026-10-05T00:08:45Z",
  "secret": "whsec_EXAMPLE_NOT_A_REAL_SECRET"
}

401

404

412

422

428

429

POST/meta/event_subscriptions/{endpoint_id}/test

Send a test event

Queues a feature_flags.webhook.test event without customer values. Credentials: a secret key.

ParameterLocationDescription
endpoint_idpath
Responses

202Success.

{
  "event_id": "evt_L7MD1mLYvKdP2yCi77gZpR",
  "endpoint_id": "whe_V1nN1KXCbpCbzw7NKeYxfs"
}

401

404

429

GET/meta/event_subscriptions/{endpoint_id}/deliveries

List deliveries

Lists an endpoint's deliveries with their attempts, newest first, for 30 days. Credentials: a secret key.

ParameterLocationDescription
endpoint_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "whd_L7MD1mLYvKdP2yCi77gZpR",
      "event_id": "evt_L7MD1mLYvKdP2yCi77gZpR",
      "status": "pending",
      "attempt_count": 0,
      "next_attempt_at": "2026-10-05T00:08:48Z",
      "attempts": [],
      "created_at": "2026-10-05T00:08:48Z"
    }
  ],
  "next_cursor": null
}

401

404

429

POST/meta/event_subscriptions/{endpoint_id}/deliveries/{delivery_id}/retry

Retry a delivery

Queues a new attempt of a delivery's original event. Credentials: a secret key.

ParameterLocationDescription
endpoint_idpath
delivery_idpath
Responses

202Success.

{
  "id": "whd_LFdyqiU6BRRRF1C51Jng4Q",
  "event_id": "evt_L7MD1mLYvKdP2yCi77gZpR"
}

401

404

429

GET/meta/events

List events

Lists the team's events, newest first, for 30 days. Credentials: a secret key.

ParameterLocationDescription
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "evt_L7MD1mLYvKdP2yCi77gZpR",
      "type": "feature_flags.webhook.test",
      "created_at": "2026-10-05T00:08:48Z",
      "team_id": "team_AFybMp6KhJzT6pZKvZteA5",
      "environment_id": null,
      "revision": null,
      "data": {
        "endpoint_id": "whe_V1nN1KXCbpCbzw7NKeYxfs"
      }
    }
  ],
  "next_cursor": null
}

401

429

GET/meta/events/{event_id}

Get an event

Returns an event. Credentials: a secret key.

ParameterLocationDescription
event_idpath
Responses

200Success.

{
  "id": "evt_L7MD1mLYvKdP2yCi77gZpR",
  "type": "feature_flags.webhook.test",
  "created_at": "2026-10-05T00:08:48Z",
  "team_id": "team_AFybMp6KhJzT6pZKvZteA5",
  "environment_id": null,
  "revision": null,
  "data": {
    "endpoint_id": "whe_V1nN1KXCbpCbzw7NKeYxfs"
  }
}

401

404

429