The decision endpoint takes the event inline and does not store it. To store events — and to feed velocity rules — you use the ingestion endpoints.

A single record

Multiple records

The body is an array. The same validation applies to each element independently.

CSV upload

The file field is named file. Download the template for the table first: its header row is generated from your own data model and is what validation runs against.
All or nothing. If any row fails validation nothing is written, and the response lists the problems with the line number in your file. Re-uploading a corrected file is safe: records are versioned by object_id rather than duplicated.
Maximum file size is 50 MB. Split larger loads.

Upload history

The CSV imports for this object type, newest first. status is completed or failed. rows_ingested can be lower than lines_processed — that happens when a re-upload finds rows already stored unchanged.

Validation

Validation happens before the response returns. These are refused with 400:
  • An object_type that does not exist in the data model
  • Malformed JSON
  • A missing object_id or updated_at
  • A field of the wrong type

What 202 means

The record was accepted and placed on a durable queue. The write is asynchronous.
If you ask for a decision that depends on a record immediately after its 202, the decision may not see it yet. Where ordering matters, either delay the decision slightly or pass the relevant values directly in trigger_object.

Dates and timezones

The updated_at format is yyyy-MM-dd HH:mm:ss. Send it in your own runtime’s timezone, and make sure that matches the deployment’s TIMEZONE setting. A mismatch shifts velocity windows, and nobody notices.