Three things stand between you and your first call: a key, a header, and knowing which school the key speaks for.
Sign in to Cohorte, then open Account → API keys
(/en/account/api-keys). Name the key after what will use it — nightly sync,
coaching bot — and choose whether it expires.
The key is shown once, at creation. Cohorte stores a hash, never the key itself, so a lost key is replaced, never recovered.
Warning
A key carries the rights its creator holds in the school it is bound to — never a role on Cohorte itself. Give it to a program that should act as that person, and to nothing else.
Every call carries the key in the x-api-key header. There is no bearer token,
no OAuth flow, and no session cookie: the key is the whole credential.
curl -H "x-api-key: $COHORTE_API_KEY" \
"https://your-school.cohorte.app/api/v1/enrollments/$ENROLLMENT_ID/timeline"A missing, unknown or expired key gets 401 Unauthorized, with no hint about
whether the resource behind it exists.
This is the part that surprises people, and it is the heart of the model.
A key is attached to one organization. Cohorte reads that binding from the
key itself — never from the request. There is no organizationId parameter to
pass anywhere, and passing one changes nothing: a key can only ever see and
change what belongs to its own school.
Two consequences worth stating plainly:
Warning
Known gap, today. The key creation screen does not yet let you choose the
school a key speaks for, and the public API refuses a key without that binding.
Until that screen ships, /api/v1 is reachable only with a key whose
organization binding was set for you. Everything else on this page — the
header, the errors, the endpoints — is already exact.
Every successful response is JSON and carries success: true next to its data.
Every failure carries an error string and the status code that matches it. The
shared rules — pagination, idempotency, the full list of status codes — are on
the API reference page.