Source: https://dinakar-pageloop-knowledge-base.docs-staging.pageloop.ai/api-reference/create-event

# Create an event

# Create an event

POST `/v1/events`

Publishes an event. The call returns as soon as the event is durably stored — delivery
happens asynchronously, so a `201` means "accepted", not "delivered".

## Request

#### type (body, string, required)

Lowercase, dot-separated, at most 3 segments. Example: `invoice.paid`.

#### payload (body, object, required)

Your data. Must be a non-empty JSON object. Serialized size must not exceed 256 MB.

#### streamKey (body, string)

Opt-in ordering key. Events sharing a key are delivered to a given endpoint in publish
order. Maximum 128 characters.

#### occurredAt (body, string)

RFC 3339 timestamp of when the thing actually happened, if that differs from now.
Must be within the last 48 hours. Defaults to the time Kestrel received the call.

## Response

#### id (string)

The event id, prefixed `evt_`.

#### type (string)

Echoed back exactly as sent.

#### matchedSubscriptions (integer)

How many subscriptions the event will be delivered to. `0` is a successful publish with
nowhere to go — usually a pattern typo.

#### Request

```bash cURL
curl https://api.kestrel.dev/v1/events \
  -H "Authorization: Bearer $KESTREL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1a2c50-9d1e-4a3b-8f7c-2b0d5e9a1c33" \
  -d '{
    "type": "invoice.paid",
    "streamKey": "customer_9f2a",
    "payload": { "invoiceId": "in_1024", "amountCents": 4900, "currency": "usd" }
  }'
```

```js Node
const event = await kestrel.events.publish({
  type: 'invoice.paid',
  streamKey: 'customer_9f2a',
  payload: { invoiceId: 'in_1024', amountCents: 4900, currency: 'usd' },
}, { idempotencyKey: crypto.randomUUID() });
```

#### Response

```json 201
{
  "id": "evt_01HZX9K2QW",
  "type": "invoice.paid",
  "streamKey": "customer_9f2a",
  "createdAt": "2026-08-24T09:14:22.481Z",
  "apiVersion": "2026-06-01",
  "matchedSubscriptions": 2
}
```

```json 422
{
  "error": {
    "code": "empty_payload",
    "message": "payload must be a non-empty object.",
    "requestId": "req_01HZXA7C4M"
  }
}
```

## Notes

> [!NOTE]
>
> Publishing is rate limited to **1,000 requests per minute** per account on the Team plan.
> The limit is a sliding window, not a fixed bucket.

Related: [Events](/concepts/events) · [List events](/api-reference/list-events)
