Zum Inhalt springen
All articles
Setup

Entwicklerreferenz: REST-API und MCP

Die vollständige Sellio-API-Referenz: Authentifizierung per API-Key, Felderkennung, REST-Endpunkte, Fehlerformat, Rate-Limit und der MCP-Server für KI-Agenten.

Integrieren Sie Sellio über HTTP oder verbinden Sie Ihren KI-Agenten über MCP. So oder so ist es derselbe Schlüssel, derselbe Tenant-Geltungsbereich und dasselbe Rate-Limit. Entdecken Sie die Felder jedes Objekts und beginnen Sie in Minuten, Datensätze zu lesen und zu schreiben.

💡 Es gibt außerdem ein öffentliches Entwicklerportal unter www.selliocrm.com/developers mit derselben Referenz, den ausgehenden Webhooks, der herunterladbaren OpenAPI-Spezifikation und einer Postman-Collection.

Authentifizierung

Jede Anfrage trägt einen API-Key im Header Authorization: Bearer. Dieser Schlüssel identifiziert den zugehörigen Tenant, sodass alles automatisch auf ihn beschränkt ist. Geben Sie den Schlüssel niemals im Browser preis; verwenden Sie ihn nur serverseitig. Schlüssel erzeugen und widerrufen Sie unter Einstellungen → API & Entwickler.

curl -H "Authorization: Bearer sk_live_..." \
  https://www.selliocrm.com/api/v1/objects

Schlüsselbereiche (Scopes)

Beim Erzeugen eines Schlüssels unter Einstellungen → API & Entwickler wählen Sie dessen Geltungsbereich. Geben Sie jeder Integration nur den Zugriff, den sie benötigt. Die Beschränkungen gelten in REST und MCP gleichermaßen, da beide Schnittstellen denselben Schlüssel und dieselbe Kontrolle verwenden.

  • Nur Lesen: Der Schlüssel liest Daten, kann aber nichts erstellen, bearbeiten oder löschen. Er blockiert POST, PATCH und DELETE in REST sowie die Tools create_record, update_record und delete_record in MCP. Schreib- oder Löschversuche erhalten 403 mit { "error": "errors.apiKeyReadOnly" }.
  • Auf Objekte beschränkt: Wählen Sie die Objekte aus, auf die der Schlüssel zugreifen darf. Jedes Objekt außerhalb der Liste liefert 403 mit { "error": "errors.apiKeyObjectDenied" }. Die Objektliste (GET /api/v1/objects und das Tool list_objects) ist bereits nach dem Geltungsbereich gefiltert, und Aktivitäten (/api/v1/activities) zählen als Aktivitätsobjekt: Der Schlüssel erreicht sie nur, wenn activity im Geltungsbereich enthalten ist.
  • Löschen erlauben: Standardmäßig löscht ein Schlüssel NIEMALS, selbst wenn Schreiben aktiviert ist. Beim Erzeugen des Schlüssels können Sie das Löschen aktivieren, um DELETE /api/v1/{object}/{id} und das MCP-Tool delete_record freizuschalten. Ohne diesen Geltungsbereich liefert das Löschen 403 mit { "error": "errors.apiKeyDeleteDenied" }. Das Löschen erfolgt weich: Datensätze wandern in den Papierkorb und können wiederhergestellt werden.

Ein Schlüssel ohne festgelegten Geltungsbereich (Standard) hat wie bisher vollen Lese- und Schreibzugriff auf alle Objekte. Vor dieser Änderung erstellte Schlüssel behalten den vollen Zugriff, bis Sie einen neuen Schlüssel mit Geltungsbereich erzeugen.

OAuth und verbundene Apps

Wenn ein DRITTSYSTEM im Namen des Nutzers integrieren muss (ohne dass der Kunde einen Admin-Schlüssel einfügt), verwenden Sie den OAuth-2.0-Authorization-Code-Flow mit PKCE. Der Nutzer sieht einen Zustimmungsbildschirm mit den angeforderten Berechtigungen, stimmt zu, und die App erhält ein Zugriffstoken, das nur das darf, wozu zugestimmt wurde. Apps werden kuratiert: Der Entwickler registriert und veröffentlicht die App, um eine client_id und ein client_secret zu erhalten.

  • Leiten Sie den Nutzer zu GET /api/oauth/authorize weiter, mit client_id, redirect_uri (exakter Abgleich mit der App-Allowlist), scope, state und PKCE (code_challenge mit code_challenge_method=S256). PKCE ist erforderlich.
  • Der angemeldete Nutzer stimmt auf dem Zustimmungsbildschirm zu, und das CRM leitet mit code und demselben state zurück.
  • Tauschen Sie auf Ihrem Server den Code unter POST /api/oauth/token (grant_type=authorization_code, mit code_verifier, client_id, client_secret und redirect_uri) gegen ein Zugriffstoken (Bearer, ca. 1 Stunde) und ein Refresh-Token.
  • Rufen Sie die v1-API und den MCP-Server mit Authorization: Bearer at_... auf, beschränkt auf die Zustimmung. Erneuern Sie mit grant_type=refresh_token; der Refresh wird rotiert (der alte stirbt bei Verwendung), und Wiederverwendung widerruft die ganze Familie. Widerrufen unter POST /api/oauth/revoke.
# 1) Consent (the user approves → redirect_uri?code=...&state=...)
GET https://www.selliocrm.com/api/oauth/authorize?response_type=code&client_id=app_...&redirect_uri=https://your-app/callback&scope=records:read%20activities:read&state=abc&code_challenge=...&code_challenge_method=S256

# 2) Exchange the code for tokens (server-side)
curl -X POST https://www.selliocrm.com/api/oauth/token \
  -d grant_type=authorization_code -d code=<authcode> -d code_verifier=<verifier> \
  -d client_id=app_... -d client_secret=secret_... -d redirect_uri=https://your-app/callback

# → { "access_token": "at_...", "token_type": "Bearer", "expires_in": 3600,
#     "refresh_token": "rt_...", "scope": "records:read activities:read" }

OAuth-Scopes: records:read und records:write (alle Objekte); records:read:contact und records:write:opportunity (pro Objekt); activities:read und activities:write; objects:read (Discovery). Sie werden auf dieselbe Lese-, Schreib- und Pro-Objekt-Durchsetzung abgebildet wie bei Schlüsseln.

Eingebettete Widgets (iframe)

Ihre App kann einen eigenen Bildschirm (ein Widget) auf einer Datensatzdetailseite oder auf dem Dashboard einbetten. Das Widget läuft in einem sandboxed iframe, das von Ihrer eigenen Origin aus der App-Allowlist bereitgestellt wird, und fordert den Scope widgets:embed an. Der Tenant-Administrator legt fest, wo jedes Widget unter Apps → Installiert erscheint.

Der Host sendet dem Widget nur UI-Kontext per postMessage (sellio:widget:context, Version 1): recordId, objectApiName, locale, theme und installId. Es werden keine Geschäftsdaten, Token oder Secrets in dieser Nachricht übertragen. Zum Lesen oder Schreiben von Daten verwendet das Widget die OAuth-API mit seinem eigenen Token (die bei der Installation gewährten Scopes). Das Widget darf nur sellio:widget:ready antworten (um den Kontext erneut zu erhalten) und sellio:widget:resize mit { height } (um seine Höhe anzupassen, begrenzt); jede andere Nachricht wird ignoriert.

Sicherheit: Der iframe ist sandboxed und cross-origin, sodass das Widget nicht auf das Host-DOM oder Cookies zugreifen kann. Der Host prüft bei jeder postMessage die exakte Origin, und die embedUrl wird immer gegen die App-Allowlist geprüft. Akzeptieren Sie in Ihrem Widget Nachrichten nur, wenn event.origin der Host-Origin entspricht.

window.addEventListener('message', (event) => {
  if (event.origin !== 'https://www.selliocrm.com') return; // host only
  const msg = event.data;
  if (!msg || msg.version !== 1) return;
  if (msg.type === 'sellio:widget:context') {
    const { recordId, objectApiName, locale, theme } = msg.payload;
    // data: use the OAuth API with YOUR token (never comes over postMessage)
  }
});
parent.postMessage({ type: 'sellio:widget:ready', version: 1 }, 'https://www.selliocrm.com');

Felderkennung

Bevor Sie einen Datensatz erstellen oder aktualisieren, ermitteln Sie die Felder des Objekts: was existiert, was ist erforderlich, und welche Werte eine Auswahl akzeptiert. Kein Raten, und keine Notwendigkeit, einen bestehenden Datensatz zu untersuchen.

In REST erhalten Sie das Objekt und seine Felder, mit required, options (für Auswahlfelder) und targetObject (für Lookup):

GET https://www.selliocrm.com/api/v1/objects/contact

# → {
#   "apiName": "contact",
#   "label": "Contact",
#   "fields": [
#     { "apiName": "name",  "label": "Name",   "type": "text",  "required": true },
#     { "apiName": "email", "label": "Email",  "type": "email", "required": false },
#     { "apiName": "source", "label": "Source", "type": "select", "required": true,
#       "options": [ { "value": "site", "label": "Website" },
#                    { "value": "referral", "label": "Referral" } ] },
#     { "apiName": "company", "label": "Company", "type": "lookup",
#       "required": false, "targetObject": "company" }
#   ]
# }

In MCP liefert das Tool describe_object dieselben Felder an den Agenten:

{ "method": "tools/call",
  "params": { "name": "describe_object", "arguments": { "object": "contact" } } }

REST-API v1

Datensätze jedes Objekts, Senden und Empfangen von JSON. {object} ist der apiName (zum Beispiel contact, lead, opportunity) und {id} ist die UUID des Datensatzes.

  • GET /api/v1/objects: die Objekte des Tenants auflisten.
  • GET /api/v1/objects/{object}: Objektfelder (Discovery).
  • GET /api/v1/{object}: Datensätze auflisten und durchsuchen.
  • GET /api/v1/{object}/{id}: ein Datensatz.
  • POST /api/v1/{object}: einen Datensatz erstellen.
  • POST /api/v1/{object}/bulk: Massenerstellung (bis zu 500; teilweiser Erfolg pro Eintrag).
  • PATCH /api/v1/{object}/{id}: Felder aktualisieren (teilweise).
  • PATCH /api/v1/{object}/bulk: Massenaktualisierung ({ updates: [{ id, ...fields }] }).
  • DELETE /api/v1/{object}/{id}: löschen (weich, landet im Papierkorb; erfordert den Delete-Scope beim Schlüssel).

Listenparameter (GET): limit (1 bis 500, Standard 50), offset (Paginierungs-Offset, Standard 0; die Gesamtzahl ohne Paginierung steht im Feld total), search (Suche nach Name, akzent- und groß-/kleinschreibungsunabhängig), order (Feld mit :asc oder :desc zum Sortieren) und filter. Erweiterte Filter: filter=field:operator:value wiederholen, um mehrere mit logischem UND zu kombinieren (es gibt kein ODER; bis zu 12 pro Aufruf). Operatoren: eq, neq, contains, gt, lt, gte, lte, empty, not_empty (empty und not_empty benötigen keinen Wert). Die alte Form filter=field:value (ohne Operator) bedeutet weiterhin exakte Gleichheit.

# List (limit, offset, search, filter, order)
curl -H "Authorization: Bearer sk_live_..." \
  "https://www.selliocrm.com/api/v1/opportunity?limit=20&order=updated_at:desc&filter=stage:won"

# Rich filters (logical AND: amount >= 1000 AND stage = won)
curl -H "Authorization: Bearer sk_live_..." \
  "https://www.selliocrm.com/api/v1/opportunity?filter=amount:gte:1000&filter=stage:eq:won"

# One record
curl -H "Authorization: Bearer sk_live_..." \
  https://www.selliocrm.com/api/v1/contact/8f3c...

# Create
curl -X POST -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"Ana Souza","email":"ana@acme.com","source":"site"}' \
  https://www.selliocrm.com/api/v1/contact

# Bulk create (partial success per item)
curl -X POST -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"records":[{"name":"Ana"},{"name":"Bruno"}]}' \
  https://www.selliocrm.com/api/v1/contact/bulk
# → { "results": [ { "index": 0, "ok": true, "id": "..." } ], "created": 1, "failed": 0 }

# Update (partial)
curl -X PATCH -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"source":"referral"}' \
  https://www.selliocrm.com/api/v1/contact/8f3c...

# Delete (soft, goes to the trash; requires the delete scope on the key)
curl -X DELETE -H "Authorization: Bearer sk_live_..." \
  https://www.selliocrm.com/api/v1/contact/8f3c...

Fehlerformat

Fehler werden als JSON in der Form { "error": "message" } mit dem passenden HTTP-Status zurückgegeben:

{ "error": "required field: source" }   # HTTP 400
  • 200 und 201: Erfolg (201 bei Erstellung).
  • 400: Validierung oder Geschäftsregel.
  • 401: fehlender oder ungültiger Schlüssel.
  • 403: keine Berechtigung (RBAC) für das Objekt oder durch den Schlüsselbereich blockiert (nur Lesen, Objekt außerhalb des Bereichs oder Löschen nicht aktiviert).
  • 404: Objekt oder Datensatz nicht gefunden (einschließlich DELETE/PATCH einer nicht existierenden ID).
  • 429: Rate-Limit überschritten (siehe Header Retry-After).

MCP-Server (KI-Agenten)

Sellio stellt einen nativen MCP-Server (Model Context Protocol) bereit, damit Ihr KI-Agent das CRM sicher lesen und schreiben kann. Es ist derselbe API-Key, dasselbe Rate-Limit, dieselben Validierungen und dasselbe RBAC. Die Server-URL lautet https://www.selliocrm.com/api/mcp.

  • list_objects: die Objekte des Tenants auflisten.
  • describe_object: die Felder eines Objekts (erforderlich, Typen, Optionen).
  • list_records: Datensätze auflisten und durchsuchen.
  • get_record: ein Datensatz nach ID.
  • create_record: einen Datensatz erstellen.
  • update_record: Felder aktualisieren.
  • delete_record: löschen (weich, landet im Papierkorb); erfordert den Delete-Scope beim Schlüssel.

Clients, die entferntes MCP über HTTP unterstützen, verwenden die URL mit dem Header Authorization: Bearer. Bei Clients ohne native entfernte HTTP-Unterstützung verwenden Sie die mcp-remote-Bridge:

{
  "mcpServers": {
    "sellio-crm": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://www.selliocrm.com/api/mcp",
        "--header", "Authorization: Bearer sk_live_..."
      ]
    }
  }
}

Rate-Limit

Jeder Schlüssel hat ein Limit pro Minute (Standard 120, konfigurierbar). Antworten enthalten die Header X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset. Bei Überschreitung liefert die API 429 mit Retry-After.

Objektmodell

Jeder Tenant verfügt über Standardobjekte (Kontakt, Unternehmen, Lead, Opportunity und andere) sowie benutzerdefinierte No-Code-Objekte. Ermitteln Sie sie alle mit GET /api/v1/objects und die Felder jedes einzelnen mit GET /api/v1/objects/{object} oder mit describe_object. Das Schema ist immer das Ihres Tenants.

💡 Erzeugen Sie Ihren Schlüssel unter Einstellungen → API & Entwickler und führen Sie in Minuten Ihren ersten Aufruf aus. Das Löschen von Datensätzen ist über die REST-API und MCP möglich, erfolgt aber weich (landet im Papierkorb, umkehrbar) und funktioniert nur mit Schlüsseln, bei denen der Delete-Scope aktiviert ist, was standardmäßig deaktiviert ist.

Open this article inside the system

Read it and want to see it working?

The account is free and the whole manual is available inside the system, with an assistant that answers from this very content.

Kostenloses Konto erstellen
Entwicklerreferenz: REST-API und MCP · Sellio