Data planeIngest events

POST /v1/events

Ingest a batch of privacy-safe interaction signals for a session. Authenticated by site key, async-scored, idempotent, never rate-limited.

curl -X POST https://api.botect.ai/v1/events \
  -H "X-Botect-Site-Key: pk_YOUR_SITE_KEY" \
  -H "Idempotency-Key: 6f1c0e2a-batch-uuid" \
  -H "Content-Type: application/json" \
  -d '{
    "session_token": null,
    "events": [
      {
        "request_id": "a1b2c3d4-event-uuid",
        "type": "mouse",
        "received_at": "2026-06-14T10:00:00Z",
        "payload": { "entropy": 0.74, "samples": 128 }
      }
    ]
  }'
{
  "session_token": "sess_9f3c…",
  "accepted": 1,
  "duplicates": 0
}

The browser SDK posts batches of signals here. Authenticated by the site key (public). Scoring runs asynchronously — the score is not in the response; read it from the verdict endpoint.

POST https://api.botect.ai/v1/events

Authentication

Site key via the X-Botect-Site-Key header (preferred) or a site_key body field. The key's project must have scoring enabled and the owning account must have an active subscription. See Authentication.

X-Botect-Site-Key: pk_YOUR_SITE_KEY

Idempotency

Pass an Idempotency-Key: <uuid> header per batch. On first contact (no session_token), Botect stores it so a retry of the same batch resolves to the same session instead of minting a new one. Combined with per-event request_id de-duplication, this guarantees retries never double-count — even if the first 202 is lost.

Idempotency-Key: 6f1c…batch-uuid

Request body

body
session_tokenstring | null
Required

The session's token, or null on first contact. When null (or unrecoverable), Botect mints one and returns it.

body
eventsarray
Required

The batch of signal events. Each entry:

Example

Response fields

session_tokenstring
Required

The session's token. Newly minted if the request sent null; the SDK should store it (typically in the botect_session cookie) and reuse it.

acceptedinteger
Required

How many events in the batch were newly recorded.

duplicatesinteger
Required

How many events were recognized as duplicates (by request_id) and not re-counted.

over_quotaboolean

Present and true when the account has crossed its monthly quota. The batch is still accepted. See Plans & quotas.

Errors

StatuscodeWhen
401UNAUTHENTICATEDMissing / bad site key, or scoring not enabled
402NO_ACTIVE_SUBSCRIPTIONOwning account has no active subscription
422INVALID_PAYLOADSchema violation, non-whitelisted payload key, or over-size batch

There is no 429. The customer's ingest traffic is never rate-limited — over-quota is soft (above) and overload is handled server-side by sampling/shedding. A malformed batch is rejected whole; there is no partial ingest.