REST allowlist
Dieses Verhalten ändert sich. Stand: 2026-09-02. Aktuelle kommerzielle Details: uely.ch/preise.
If you would rather speak HTTP than MCP, a small allowlist accepts the same agent token. The reach is identical to the tools — the two surfaces are held equal by a test, so neither can quietly grow past the other.
Everything else on api.uely.ch takes a browser session and is not part of this contract.
The routes
Abschnitt betitelt „The routes“| Method | Path | Scope |
|---|---|---|
GET | /documents, /documents/{id} | documents.read |
GET | /contacts, /contacts/{id} | contacts.read |
GET | /places, /places/{id} | places.read |
GET | /work-items, /work-items/{id} | work_items.read |
GET | /listings, /listings/{id} | listings.read |
GET | /animals, /animals/{id} | animals.read |
GET | /letters, /letters/{id} | letters.read |
POST | /chat/ask | ask |
POST | /research | research |
GET | /research/{job_id} | research |
POST | /training | training.write |
GET | /training/{document_id} | training.write |
Send Authorization: Bearer <token>. Without one you get a 401 and a WWW-Authenticate
naming the scope.
POST /chat/ask
Abschnitt betitelt „POST /chat/ask“curl -s -X POST https://api.uely.ch/chat/ask \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: your-key' \ -d '{"question":"Wie viele Kontakte habe ich?"}'{ "answer": "...", "sources": [], "refused": false, "message_id": "..."}German answers, grounded in the workspace and knowledge base. Read tools only — no code execution, no browsing. There is a timeout; a question that runs too long is abandoned rather than left hanging.
Idempotency
Abschnitt betitelt „Idempotency“POST /chat/ask, POST /research and POST /training accept an Idempotency-Key.
- Same key, same body → the stored response, byte for byte, with the same
message_id. The model does not run again and you are not charged again. - Same key, different body →
409. A key identifies one request; answering a different question with a cached answer would be worse than an error. - No key → every call is a new request and a new charge.
The window is 24 hours.
POST /research
Abschnitt betitelt „POST /research“curl -s -X POST https://api.uely.ch/research \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: your-key' \ -d '{"question":"Wie oft Klauenpflege beim Milchvieh?"}'Answers 202 with a job_id. A report reads a large corpus and takes one to several
minutes, so nothing holds the connection open for it.
{ "job_id": "…", "status": "queued", "poll": "/research/…" }Poll GET /research/{job_id} until status is succeeded, then read report and
citations. A failed job carries error. Polling is free — only starting a report is
charged.
The same Idempotency-Key returns the same job_id, so a retry polls the report already
being written rather than paying for a second one.
POST /training
Abschnitt betitelt „POST /training“curl -s -X POST https://api.uely.ch/training \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{"file_name":"notes.md","content":"# ..."}'Answers 202 with a job id when ingest is asynchronous, which it normally is. Poll
GET /training/{document_id} for processing_step.
202 rather than 200 is a deliberate contract: the document is accepted, not ready. Treating the response as “indexed” and immediately asking a question about it will disappoint you.
Rate limits
Abschnitt betitelt „Rate limits“Responses carry RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset. Read them
rather than guessing. A 429 carries Retry-After.