REST API v1
Verwalten Sie Agenten, lesen Sie Gespräche und Kontakte und chatten Sie aus Ihrem eigenen Backend, mit einfachem HTTP.
curl https://api.onetype.ai/v1/agents -H "Authorization: Bearer sk_live_…"Authentifizierung und Schlüssel
Erstellen Sie Schlüssel unter Developer › API keys (Inhaber oder Administrator). Ein Schlüssel wird nur einmal angezeigt.
| Schlüssel | Präfix | Verwendung | Kann |
|---|---|---|---|
| Secret | sk_live_ | Nur Ihre Server | Alles, was ein Administrator des Workspace tun kann, außer Identitäts- und Inhaberaktionen |
| Restricted | rk_live_ | Server, CI, Automatisierungstools | Nur die Berechtigungen, die Sie beim Erstellen ankreuzen (nie mehr als Ihre eigenen) |
API-Schlüssel gehören zu Premium. Senden Sie den Schlüssel als Authorization: Bearer <key>. Schlüssel gehören zu einem Workspace, und ein Schlüssel kann nie die Daten eines anderen Workspace lesen. Halten Sie Secret- und Restricted-Schlüssel aus Browsern, Mobile-Apps und Repositories heraus. Wenn einer durchsickert, widerrufen Sie ihn im Dashboard, und die allernächste Anfrage damit schlägt fehl.
Ressourcen
| Endpunkt | Scope (Berechtigung) | Status |
|---|---|---|
GET/POST /v1/agents, GET/PATCH/DELETE /v1/agents/:id | agents.read, agents.update, … | Verfügbar |
GET /v1/conversations?agent&status&created[gte], GET /v1/conversations/:id, GET /v1/conversations/:id/messages | conversations.read | Verfügbar |
POST /v1/conversations { agent } | conversations.write (nur Schlüssel) | Verfügbar |
POST /v1/conversations/:id/messages { content, stream? } | conversations.write | Verfügbar |
GET /v1/contacts?agent, GET /v1/contacts/:id | contacts.read | Verfügbar |
POST/DELETE /v1/mcp, /v1/mcp/agents/:agent | siehe MCP | Verfügbar |
Wissen und Nutzung werden im Dashboard verwaltet.
Ein Kontakt gehört zu einem Agenten (agent, eine agt_… -ID): Dieselbe Person auf den Websites zweier Ihrer Agenten ergibt zwei Kontakte. ?agent=agt_… listet die eines Agenten auf.
Öffentliche Objekte verwenden snake_case -Felder und Präfix-IDs (die Besucher-Routen eines eigenen Chats verwenden camelCase, zum Beispiel isAiGenerated; snake_case, is_ai_generated, gibt es nur in den /v1 -Formaten). Sie enthalten nie interne Felder. Jedes Nachrichtenobjekt hat is_ai_generated (true für die Antworten des Agenten, false für die Ihres Teams), wie es die EU-KI-Verordnung verlangt.
OpenAPI: https://api.onetype.ai/v1/openapi.json, generiert aus denselben Schemas, mit denen die API validiert.
Gesprächsstatus
Gesprächsobjekte (in /v1 und in conversation.* -Webhooks) enthalten status und, wenn gelöst, resolved_by:
status | Bedeutung |
|---|---|
open | In Bearbeitung |
escalated | An Ihr Team übergeben; nur eine Person schließt es |
resolved | Mit einer Antwort geschlossen. resolved_by: ai (automatisch nach einer guten Antwort geschlossen), member (eine Person aus Ihrem Team), visitor (der Besucher hat bestätigt) oder idle (vor dem 2026-09-24 geschlossene Gespräche) |
unresolved | Automatisch geschlossen, nachdem die letzte Antwort des Agenten besagte, dass er es nicht weiß, oder abgewertet wurde. Es kehrt zu open zurück, wenn der Besucher erneut schreibt |
failed | Konnte wegen eines Fehlers nicht beantwortet werden oder wurde von Ihrem Team als nicht gelöst geschlossen (auch nach einer Übergabe) |
Ein Gespräch, das der Agent allein bearbeitet, wird 30 Minuten nach seiner letzten Nachricht automatisch geschlossen. Gespräche mit Übergabe, die von Ihrem Team gehalten werden oder auf eine unbeantwortete Besuchernachricht warten, werden nie automatisch geschlossen. Neue Werte können hinzukommen; behandeln Sie unbekannte als open.
Paginierung
Listen-Endpunkte verwenden Cursor:
curl "https://api.onetype.ai/v1/conversations?limit=50" -H "Authorization: Bearer sk_live_…"{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "b3BhcXVl…" }Übergeben Sie cursor=<next_cursor> für die nächste Seite. limit ist standardmäßig 20, mit einem Maximum von 100. Cursor sind opak und bleiben stabil, wenn beim Blättern neue Einträge hinzukommen.
Idempotenz
Senden Sie Idempotency-Key: <any unique string> bei jedem POST, um Wiederholungen sicher zu machen. Das erste Ergebnis wird 24 Stunden lang aufbewahrt, und eine Wiederholung mit demselben Schlüssel liefert es zurück, statt die Arbeit erneut auszuführen.
curl -X POST https://api.onetype.ai/v1/conversations \
-H "Authorization: Bearer sk_live_…" \
-H "Idempotency-Key: 6f1c9f2e-3b1d-4a0e-9d0f-2f6f0b3c9a11" \
-H "Content-Type: application/json" \
-d '{"agent":"YOUR_AGENT_ID"}'- Eine erneut ausgelieferte Antwort trägt
Idempotent-Replayed: true. - Schlüssel sind 1–255 druckbare ASCII-Zeichen. Alles andere ergibt
400 BAD_IDEMPOTENCY_KEY. - Derselbe Schlüssel mit einem anderen Body ergibt
409 IDEMPOTENCY_KEY_REUSED. Verwenden Sie für eine neue Anfrage einen neuen Schlüssel. - Solange die erste Anfrage mit einem Schlüssel noch läuft, erhält eine Wiederholung
409 IDEMPOTENCY_KEY_IN_USE. Warten Sie und versuchen Sie es erneut. - Validierungsfehler werden nicht gespeichert (korrigieren Sie die Anfrage und versuchen Sie es mit demselben Schlüssel erneut). Eine Ablehnung, die die Arbeit selbst erzeugt hat (z. B. ein Tarif-Limit) wird gespeichert und erneut ausgeliefert.
- Schlüssel sind auf Ihren Workspace und Ihren Schlüssel beschränkt.
Fehler
Jeder Fehler hat dieselbe Form, plus einen x-request-id -Header. Geben Sie die Anfrage-ID an, wenn Sie den Support kontaktieren.
{ "error": { "status": 422, "code": "VALIDATION_FAILED", "message": "content: required", "fields": { "content": "Required" } } }| Status | Wann | Typische Codes |
|---|---|---|
| 400 | Die Anfrage ist ungültig | VALIDATION_FAILED (siehe fields), BAD_IDEMPOTENCY_KEY |
| 401 | Der Schlüssel fehlt, ist falsch oder widerrufen | UNAUTHENTICATED |
| 403 | Dem Schlüssel fehlt die Berechtigung | PERMISSION_DENIED |
| 404 | Nicht gefunden in Ihrem Workspace (Objekte anderer Workspaces wirken wie nicht vorhanden) | NOT_FOUND |
| 409 | Konflikte | IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_KEY_IN_USE, INVALID_TRANSITION |
| 402 / 422 | Tarifgrenzen und Geschäftsregeln | QUOTA_EXCEEDED, REFUSED (die Meldung nennt den Grund) |
| 429 | Zu viele Anfragen | RATE_LIMITED |
| 5xx | Unser Fehler | immer INTERNAL, mit der Anfrage-ID. Wenn es weiterhin auftritt, schreiben Sie mit der Anfrage-ID an support@onetype.ai |
code -Werte sind stabil. Richten Sie Ihre Fehlerbehandlung nach ihnen aus, nicht nach message.
Ratenbegrenzungen
Pro Schlüssel: 100 Anfragen pro 10 Sekunden und 20 Chat-Nachrichten pro 10 Sekunden. Höhere Limits gehören zu höheren Tarifen. Jede Antwort enthält:
RateLimit-Limit: 100
RateLimit-Remaining: 87
RateLimit-Reset: 6Eine 429 enthält außerdem Retry-After (Sekunden). Warten Sie so lange und versuchen Sie es dann erneut. Wiederholen Sie nicht in einer engen Schleife.
Fehlgeschlagene Authentifizierung wird pro Netzwerkadresse begrenzt. Anfragen mit einem falschen oder widerrufenen Schlüssel zählen gegen die Adresse, von der sie kommen. Teilen viele Clients eine öffentliche Adresse (ein Firmen-NAT, ein CI-Anbieter), kann ein falsch konfigurierter Client das Budget aufbrauchen, und dann erhalten selbst Anfragen mit einem gültigen Schlüssel von dieser Adresse 429 RATE_LIMITED , bis das Zeitfenster zurückgesetzt wird. Behandeln Sie es wie jedes 429: Beachten Sie Retry-After, und beheben Sie dann den Client, der den fehlerhaften Schlüssel sendet.
async function call(url: string, init: RequestInit, attempts = 3): Promise<Response>
{
const response = await fetch(url, init);
if (response.status !== 429 || attempts <= 1)
{
return response;
}
const waitSeconds = Number(response.headers.get("retry-after") ?? "1");
await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000));
return call(url, init, attempts - 1);
}Chat aus Ihrem Backend
Erstellen Sie ein Gespräch für einen Agenten und senden Sie dann Nachrichten hinein. Jede Antwort wird genau wie eine Widget-Antwort geschrieben, gespeichert und abgerechnet.
curl -X POST https://api.onetype.ai/v1/conversations \
-H "Authorization: Bearer sk_live_…" -H "Content-Type: application/json" \
-d '{"agent":"YOUR_AGENT_ID"}'
# → { "id": "cnv_…", "object": "conversation", "status": "open", … }
curl -X POST https://api.onetype.ai/v1/conversations/cnv_…/messages \
-H "Authorization: Bearer sk_live_…" -H "Idempotency-Key: order-1234-question-1" -H "Content-Type: application/json" \
-d '{"content":"Where is order 1234?"}'
# → { "id": "msg_…", "object": "message", "role": "assistant", "is_ai_generated": true, "parts": [ … ], … }Die parts der Antwort enthalten text -Teile und einen source-document -Teil für jede zitierte Quelle (title und url bei Webseiten).
Streaming
Senden Sie "stream": true , um die Antwort so zu erhalten, wie sie geschrieben wird, als Server-Sent Events im Format AI SDK UI Message Stream v1 . Die Antwort enthält x-vercel-ai-ui-message-stream: v1, und das Feld data jedes Ereignisses ist ein JSON-Teil: start, text-start, text-delta (mit delta), text-end, source-document, finish (mit messageMetadata.outcome), error oder abort. Der Stream endet mit data: [DONE].
const response = await fetch(`https://api.onetype.ai/v1/conversations/${conversationId}/messages`, {
method: "POST",
headers: { "Authorization": `Bearer ${process.env.ONETYPE_API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({ content: "How do refunds work?", stream: true }),
});
const reader = response.body!.pipeThrough(new TextDecoderStream()).getReader();
let buffer = "";
for (;;)
{
const { value, done } = await reader.read();
if (done) break;
buffer += value;
const events = buffer.split("\n\n");
buffer = events.pop() ?? "";
for (const event of events)
{
const data = event.split("\n").find((line) => line.startsWith("data: "))?.slice(6);
if (data === undefined || data === "[DONE]") continue;
const part = JSON.parse(data);
if (part.type === "text-delta") process.stdout.write(part.delta);
if (part.type === "source-document") console.log(`\n[source] ${part.title}`);
}
}Mit dem Vercel AI SDK auf Ihrem eigenen Server können Sie die Antwort direkt an useChat durchreichen, weil es dasselbe Format ist.
- Das Trennen der Verbindung bricht die Antwort nicht ab. Die Antwort wird weiterhin geschrieben, gespeichert und abgerechnet.
- Das erneute Abrufen eines beendeten Streams ist sicher. Wiederholen Sie die Anfrage mit demselben
Idempotency-Key, und Sie erhalten die gespeicherte Antwort als JSON (Status 200), nicht eine zweite Antwort.
Versionierung
/v1 ändert sich nur additiv: neue Felder, neue Endpunkte, neue Ereignistypen. Ihr Code sollte Felder ignorieren, die er nicht kennt. Falls je eine inkompatible Änderung nötig wird, erscheint sie als neue Version, die pro Schlüssel gewählt wird, mit Vorankündigung.