Quickstart
This guide takes you from an empty project to a first accepted event. We will install a client, send a batch to the ingestion endpoint, read the response properly, and then point you at the pages that explain what sinio.ai does with what you sent.
You need an API key before you can call anything. Create one from your project's settings in the sinio.ai console — a key is shown once, at creation, and only its hash is stored afterwards.
Choose your client
Besides plain HTTP, sinio.ai publishes first-party SDKs for Node.js, Python and PHP. They all speak the same model — same method names, same batching behaviour, same error families — with each language's naming conventions.
# cURL is most likely already installed on your machine
curl --version
Send your first events
An event is a fact that happened at a point in time: an identifier that is stable on your side, a type, a timestamp with a UTC offset, and an optional free-form payload. The four structural roles sinio.ai knows how to resolve — device, subject, location, actor — live in a fixed roles envelope, separate from the payload; any other key is refused.
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",
"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" }
}
]
}'
Read the response
Response
{
"batch_id": "0192f3a4-7b1c-7e2d-9a10-4c5b6d7e8f90",
"accepted": 1,
"pending_classification": 0,
"duplicates": 0,
"revisions": 0,
"rejected": 0,
"rejections": [],
"test_mode": false
}
Four of those counters are successes, and the distinction matters more than it looks:
accepted— stored, with a known type, and queued for derivation.pending_classification— stored, but thetypeyou sent is not known to the project yet. This is not an error; it is how onboarding works. The event waits, keeps its payload, and is derived once someone gives that type a meaning in the console.duplicates— an event you had already sent, with the same content (payload,occurred_at,roles,count). A no-op.revisions— a correction: an event you had already sent, with different content.
rejected is the only failure count, and every rejected event comes back in rejections with a code you can act on.
test_mode is true only while the key is still in test mode, during a connection set up from the console: the events are checked and counted, but nothing is derived from them until you keep the test.
What's next?
- Understand what sinio.ai derives from the events you push — episodes, habits, findings.
- Declare your reference data so devices, subjects and locations carry labels and a hierarchy.
- Load your history without setting off a year of alerts.
- Read the error and rejection codes before you write your retry logic.