Events

This is the endpoint everything else exists for. You push facts — a badge read, a work order closed, a temperature reading — and sinio.ai derives episodes, durations and findings from them. On this page: the event model, the endpoint, and the two authentication surfaces that reach it.

The event model

An event is a fact with an identity that is stable on your side, a type, a moment and, optionally, a payload. The four structural roles sinio.ai knows how to resolve live in a fixed roles envelope, separate from the payload.

Properties

  • Name
    source_event_id
    Type
    string
    Description

    Required. The event's identity in your system, stable over time. Together with the project and the source, it is what makes replays free.

  • Name
    type
    Type
    string
    Description

    Required. The code of an event type. A code the project does not know yet is not an error — the event is stored as pending_classification.

  • Name
    occurred_at
    Type
    string
    Description

    Required. ISO 8601 with a UTC offset, written YYYY-MM-DDThh:mm:ss with seconds, an optional fraction, then Z or ±hh:mm — for instance 2026-08-28T07:58:12+02:00. Anything else is rejected with invalid_occurred_at — a timestamp with no offset is not a moment, and guessing one silently corrupts every duration derived from it.

  • Name
    payload
    Type
    object
    Description

    Optional, {} when omitted. Free-form, up to 256 KB per event (beyond, that event alone is rejected with payload_too_large): its content is never checked. Stored whole; only what the type's published interpretation (and the readings its source declares) names is read from it. A badge read often has nothing else to say — leave it out.

  • Name
    count
    Type
    integer
    Description

    Optional, 1 to 1,000,000. How many units this one event stands for — a satisfaction button pressed ten times between two messages of a terminal is one event with a count of 10. Omitted, the event counts once. Only this top-level field is read — a count inside payload is never used. Every total and satisfaction score is weighed by it.

  • Name
    roles
    Type
    object
    Description

    Optional. The four structural roles: device, subject, location, actor, each the raw identifier your system uses, as a string. All optional, except a subject or an actor that the event type's interpretation marks required: true (device and location can never be required). Any other key is refused — a ticket number or a firmware version belongs in payload.

  • Name
    source_version
    Type
    string
    Description

    Optional. Your system's version of this event, stored with it for your own tracing. It plays no part in deduplication: whether a resend is a duplicate or a correction is decided on its content alone — see Batching & idempotency.

  • Name
    label
    Type
    string
    Description

    Optional. A human-readable name for the type, used only when the type is unknown — it gives whoever classifies it later something better to read than a raw code.


POST/v1/events

Send events

Ingest a batch of up to 500 events, in a request body of up to 10 MB. Acceptance is partial: valid events are stored even when others in the same batch are rejected.

A 200 confirms reception, not derivation — derivation runs on its own queue moments later. A body over 10 MB is refused as a whole with 413.

Required attributes

  • Name
    events
    Type
    array
    Description

    Up to 500 events. More is a 400 for the whole call.

Optional attributes

  • Name
    mode
    Type
    string
    Description

    webhook (default) or backfill. The declared mode decides whether the batch can raise alerts: a backfill raises none, and once it has arrived the project's processes, if it has any, read it again — see Backfill.

Headers

  • Name
    Authorization
    Type
    string
    Description

    Bearer <api_key>.

Request

POST
/v1/events
curl https://api.sinio.ai/v1/events \
  -H "Authorization: Bearer $SINIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "source_event_id": "evt_88213",
        "source_version": "3",
        "type": "badge_in",
        "occurred_at": "2026-08-28T07:58:12+02:00",
        "roles": {
          "device": "BORNE-A12",
          "subject": "P-4582",
          "location": "SITE-A.HALL"
        },
        "payload": { "badge": "04A2B9C1", "reader_firmware": "2.4.1" }
      }
    ]
  }'

Response

{
  "batch_id": "0192f3a4-7b1c-7e2d-9a10-4c5b6d7e8f90",
  "accepted": 497,
  "pending_classification": 1,
  "duplicates": 1,
  "revisions": 0,
  "rejected": 1,
  "rejections": [
    {
      "source_event_id": "evt_88240",
      "code": "invalid_occurred_at",
      "message": "occurred_at must be ISO 8601 with an offset, got: \"2026-08-28T07:58:12\""
    }
  ],
  "test_mode": false
}

Reading the response

  • Name
    batch_id
    Type
    string
    Description

    The identifier sinio.ai assigned to this call (a UUID), generated on its side — you cannot send one. Quote it when you contact support. It plays no part in deduplication.

  • Name
    accepted
    Type
    integer
    Description

    Stored, with a known type. In webhook mode it is queued for derivation; in backfill mode the project's processes read it once the batch has arrived.

  • Name
    pending_classification
    Type
    integer
    Description

    Stored, waiting for its type to be given a meaning. A success, not a rejection — the payload is kept whole and derived once the type is known.

  • Name
    duplicates
    Type
    integer
    Description

    No-ops: events whose content is identical to any revision you had already sent — the latest one, or one that has since been superseded.

  • Name
    revisions
    Type
    integer
    Description

    Corrections: same source_event_id, different content (payload, occurred_at, roles or count). A new revision was written and a recomputation queued.

  • Name
    rejected
    Type
    integer
    Description

    The only failure count. Every one of them is detailed in rejections.

  • Name
    rejections
    Type
    array
    Description

    One entry per rejected event: source_event_id, code, message. The codes are listed in Errors.

  • Name
    test_mode
    Type
    boolean
    Description

    true when the key is in test mode, while a connection is being set up: the events were checked exactly as live ones and counted the same way, but kept aside — nothing is derived from them until the test is kept. See Authentication.


POST/v1/webhooks/{key}

Send events with a webhook key

The same body, the same mode, the same processing as POST /v1/events — only the authentication moves from the Authorization header into the URL, carried by a webhook token rather than an API key. It exists for systems that can be pointed at a URL and nothing else.

The key is a credential like any other, so treat the whole URL as a secret.

Request

POST
/v1/webhooks/{key}
curl https://api.sinio.ai/v1/webhooks/$SINIO_WEBHOOK_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "source_event_id": "evt_88213",
        "type": "badge_in",
        "occurred_at": "2026-08-28T07:58:12+02:00",
        "roles": { "device": "BORNE-A12", "subject": "P-4582" }
      }
    ]
  }'

Response

{
  "batch_id": "0192f3a4-7b1c-7e2d-9a10-4c5b6d7e8f90",
  "accepted": 1,
  "pending_classification": 0,
  "duplicates": 0,
  "revisions": 0,
  "rejected": 0,
  "rejections": [],
  "test_mode": false
}

Was this page helpful?