---
title: "Import events for many subscribers"
method: POST
path: "/subscribers/events/imports"
tags: ["Subscribers"]
---

# Import events for many subscribers

`POST /subscribers/events/imports`

Records a bounded batch of up to 25 events for many subscribers. Email is required to create a contact; externalId-only rows must resolve to an existing contact. Events are grouped per contact - a contact whose rows are all more than an hour old is imported silently as history, including no double-opt-in email, while any recent row makes that contact's whole group live. Stable eventIds keep one receipt and let retries re-attempt downstream recovery idempotently.

## Request body

- object
  - `events` object[], required — Events to record. Each event identifies its own subscriber.
    - `email` string, email, nullable — Subscriber email address. Required when the event may create a new contact; null is treated as absent.
    - `externalId` string, nullable — Customer-owned subscriber ID. It can be used alone only when it resolves to an existing contact; null is treated as absent.
    - `name` string, required — Event name.
    - `properties` object — Event properties. Unrecognized keys outside these documented fields are ignored - keep row data inside properties.
    - `occurredAt` string, date-time, nullable — When the event happened (ISO 8601, null treated as absent). Only when every row for that contact is more than an hour old is the group historical; any recent row makes the whole group live.
    - `eventId` string, required — Required source-owned id for this event, used as an idempotency key so re-running the import records nothing twice.

## Response `200`

Import processed. success is false when any event failed - recorded events are kept, so treat errors as partial success.

- object
  - `success` boolean
  - `total` integer — Events submitted in this request.
  - `recorded` integer — Events recorded by this request.
  - `duplicates` integer — Events skipped because their eventId was already recorded.
  - `failed` integer — Events that failed to record.
  - `sideEffectFailed` integer — Receipt rows whose downstream side effects or historical automation shielding failed. This is orthogonal to receipt accounting and may accompany either recorded or duplicate rows during recovery.
  - `subscribers` integer — Distinct subscriber identities in the request.
  - `failures` object[] — Failed events by input index.
    - `index` integer
    - `error` string
  - `sideEffectFailures` object[] — Post-write failures by input index. The receipt exists (new or duplicate); retry with the same eventId for recovery.
    - `index` integer
    - `stages` string[]
    - `error` string
  - `error` string — First failure message when any event failed.

## Other responses

- `400` — Invalid request - a row is missing identity or carries a bad timestamp
- `401` — Unauthorized
- `403` — Missing required scope
- `500` — Internal server error

## Changes

- **2026-08-26** `c78765f7e84f` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/sequenzy/apis/sequenzy-api/changes/subscribers/events/imports/post.md)

---

[API](https://skmtc.dev/sequenzy/apis/sequenzy-api.md) · [All operations](https://skmtc.dev/sequenzy/apis/sequenzy-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/sequenzy/sequenzy-api/revisions/73f826277d9a/schema)
