Für Entwickler · getestete Beispiele · EU-souverän
Die Xenori-API.
Starten Sie vollständige Agenten-Sessions per HTTP: Aufgabe senden, Fortschritt verfolgen, Ergebnis samt Dateien abholen. Dieselbe Plattform wie im Produkt — inklusive Sandbox, Skills und Verifikation.
Authentifizierung
Jede Anfrage trägt Ihren API-Schlüssel im Header x-maxicore-api-key. Schlüssel erstellen und widerrufen Sie im Produkt unter Einstellungen → Entwickler. Der Klartext wird genau einmal angezeigt; ein Widerruf wirkt sofort (die nächste Anfrage erhält 401). Verwenden Sie Schlüssel nur server-seitig — nie im Browser, nie im Client-Code, nie im Repository.
Session starten
curl -X POST https://xenori.ai/api/v2/task.create \
-H "x-maxicore-api-key: $XENORI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": { "content": [ { "type": "text",
"text": "Erstelle einen Monats-Haushaltsplan als Excel-Datei." } ] },
"model": "max-smart"
}'
# Antwort (getestet):
# { "ok": true, "request_id": "req_…",
# "task": { "id": "task_6d09c5…", "status": "running", … } }Die Stufe wählen Sie mit model: max-fast, max-smart oder max-genius. Government & Legal steht ausschließlich freigeschalteten Konten offen — fordert ein anderes Konto diese Stufe an, begrenzt der Server die Anfrage automatisch auf die Stufe des Kontos. Danach: Status abfragen, bis die Session terminal ist.
curl "https://xenori.ai/api/v2/task.detail?task_id=task_6d09c5…" \
-H "x-maxicore-api-key: $XENORI_API_KEY"
# → "status": "running" | "in_queue" | "waiting" | "completed" | "failed" | "stopped"Endpunkte
| Methode | Pfad | Zweck |
|---|---|---|
| POST | /api/v2/task.create | Neue Aufgaben-Session starten (Text + optional Stufe/Anhänge) |
| GET | /api/v2/task.detail?task_id=… | Status & Metadaten einer Session |
| GET | /api/v2/task.listMessages?task_id=… | Vollständiger Verlauf (Nachrichten, Werkzeuge, Anhänge) |
| POST | /api/v2/task.sendMessage | Folge-Nachricht — steuert einen laufenden Lauf oder startet den nächsten Turn |
| POST | /api/v2/task.stop | Laufende Session anhalten |
| GET | /api/v2/task.list?limit=… | Eigene Sessions auflisten |
| GET | /api/v2/usage.ledger?limit=… | Gutschriftenverlauf: Verbrauch je Lauf + Kontobewegungen |
Credits
Jeder Lauf wird in Credits abgerechnet — dieselbe Währung wie im Produkt, abhängig von Stufe, Werkzeugnutzung und Sandbox-Zeit (ein kurzer Fast-Lauf kostet wenige Credits). Den Verbrauch je Lauf sehen Sie im Produkt unter Einstellungen → Nutzung oder per usage.ledger. Reicht das Guthaben nicht, antwortet die API mit einem klaren Fehler statt einen Lauf anzubrechen; Credits sind jederzeit im Produkt zukaufbar.
Rate-Limits & Parallelität
| Plan | Anfragen | Gleichzeitige Läufe | Credits |
|---|---|---|---|
| Fast | 60 / min | 2 parallele Läufe | 250 Credits / Tag |
| Smart | 120 / min | 3 parallele Läufe | 5.000 Credits / Monat |
| Genius | 240 / min | 5 parallele Läufe | 25.000 Credits / Monat |
| Government & Legal | 240 / min | 5 parallele Läufe | nach Vereinbarung |
Zusätzliche Läufe über dem Parallel-Limit werden nicht abgelehnt, sondern eingereiht und starten automatisch, sobald ein Platz frei wird (Status in_queue). Beim Minuten-Limit antwortet die API so — bitte mit Backoff wiederholen:
HTTP/1.1 429 Too Many Requests
retry-after: 60
{ "ok": false, "error": { "code": "rate_limited",
"message": "Zu viele Anfragen (60/min für diese Stufe). Bitte in 60s erneut versuchen." } }Kontingent-Kopfzeilen: Jede Antwort trägt Ihren aktuellen Stand, damit Sie Ihre Aufrufrate steuern können, ohne sie zu erraten:
| Kopfzeile | Bedeutung |
|---|---|
| X-RateLimit-Limit | Anfragen pro Minute für Ihren Plan |
| X-RateLimit-Remaining | im laufenden Fenster noch frei |
| X-RateLimit-Reset | Sekunden bis zum Zurücksetzen |
| Retry-After | nur bei 429: Sekunden bis zum nächsten Versuch |
Anfragegröße: Der Rumpf einer Anfrage ist auf 4 MB begrenzt (darüber 413 payload_too_large). Das reicht für sehr lange Prompts; größere Inhalte senden Sie als Datei-Anhang. Kaufpfade (Plan-Auswahl, Checkout) sind vom Minuten-Limit ausgenommen.
Für Lastspitzen, dedizierte Kapazität und höhere Kontingente (Enterprise, Load-Balancing über reservierte Sandbox-Pools) sprechen Sie uns an: info@xenori.ai.
Webhooks
Statt zu pollen lassen Sie sich benachrichtigen. Xenori schickt zwei Ereignisse an eine Adresse Ihrer Wahl: task_created, sobald eine Aufgabe angelegt wurde, und task_stopped, sobald sie fertig ist, gescheitert ist oder auf eine Eingabe wartet. Bewusst nur diese zwei — jeder Zwischenschritt gehört in den Ereignisstrom, nicht in Ihr Postfach.
curl -X POST https://xenori.ai/api/v2/webhook.create \
-H "x-maxicore-api-key: $XENORI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://ihre-anwendung.example/xenori-hook",
"events": ["task_created", "task_stopped"]
}'Ihr Endpunkt bekommt einen HTTP-POST mit dieser Nutzlast. Antworten Sie innerhalb von zehn Sekunden mit Status 200; alles andere gilt als Fehlschlag und wird wiederholt.
{
"event_id": "task_stopped_task_abc123",
"event_type": "task_stopped",
"task_detail": {
"task_id": "task_abc123",
"task_title": "Quartalsbericht erstellen",
"task_url": "https://xenori.ai/chat/task_abc123",
"status": "done"
}
}Echtheit prüfen — Pflicht
Jede Zustellung ist mit RSA-SHA256 signiert. Prüfen Sie die Signatur, bevor Sie den Inhalt verwenden — sonst kann jeder, der Ihre Adresse kennt, Ereignisse erfinden. Sie erhalten zwei Kopfzeilen: X-Webhook-Signature (Base64) und X-Webhook-Timestamp (Unix-Sekunden). Signiert wird die Zeichenkette {timestamp}.{url}.{sha256_hex(body)} — der Zeitstempel und die Adresse gehören dazu, damit eine abgefangene Zustellung nicht andernorts wiedereingespielt werden kann. Den öffentlichen Schlüssel holen Sie einmalig von GET /api/v2/webhook.publicKey.
# Signatur pruefen (Python) — RSA-SHA256 ueber
# "{timestamp}.{url}.{sha256_hex(body)}"
import base64, hashlib, time
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
def ist_echt(kopfzeilen, url, rumpf_bytes, oeffentlicher_schluessel_pem):
signatur = base64.b64decode(kopfzeilen["X-Webhook-Signature"])
zeitstempel = int(kopfzeilen["X-Webhook-Timestamp"])
# Aelter als fuenf Minuten: ablehnen (Schutz vor Wiedereinspielung)
if abs(time.time() - zeitstempel) > 300:
return False
rumpf_hash = hashlib.sha256(rumpf_bytes).hexdigest()
signiert = f"{zeitstempel}.{url}.{rumpf_hash}".encode()
schluessel = serialization.load_pem_public_key(oeffentlicher_schluessel_pem)
try:
schluessel.verify(signatur, signiert, padding.PKCS1v15(), hashes.SHA256())
return True
except Exception:
return FalseWeisen Sie Zustellungen ab, deren Zeitstempel älter als fünf Minuten ist. Verwalten und widerrufen können Sie Ihre Webhooks im Produkt unter Einstellungen → Entwickler.
Fehlerformat
Alle Fehler kommen in einem einheitlichen Umschlag — Ihr Code braucht genau einen Fehlerpfad:
{ "ok": false, "request_id": "req_…",
"error": { "code": "not_found | invalid_argument | rate_limited | …",
"message": "menschenlesbare Erklärung" } }Komplettbeispiel (Python)
import os, time, requests
BASE = "https://xenori.ai/api/v2"
H = {"x-maxicore-api-key": os.environ["XENORI_API_KEY"]}
r = requests.post(f"{BASE}/task.create", headers=H, json={
"message": {"content": [{"type": "text",
"text": "Fasse die wichtigsten EU-KI-Regeln in 5 Punkten zusammen."}]},
"model": "max-smart",
})
task = r.json()["task"]
while task["status"] in ("running", "in_queue", "waiting"):
time.sleep(4)
task = requests.get(f"{BASE}/task.detail",
headers=H, params={"task_id": task["id"]}).json()["task"]
verlauf = requests.get(f"{BASE}/task.listMessages", headers=H,
params={"task_id": task["id"], "limit": 200}).json()
print(task["status"], "→", len(verlauf.get("messages", [])), "Nachrichten")