Das Handbuch zu Ihrem Board
Eine Seite, drei Spuren: Beginnen Sie hier, geben Sie die zweite an die Person weiter, die die Fälle betreut, und die dritte an die Person, die den Code schreibt.
Für alle, die verwalten
Aktivieren Sie den Plan, laden Sie Ihr Team ein, legen Sie Ihr Fall-Präfix fest und behalten Sie die Abrechnung im Griff.
Erste Schritte →Für alle, die die Website pflegen
Drei einbettbare Widgets mit einer Script-Zeile: Kontakt, Fall-Eröffnung und Endkunden-Board.
Widgets →Für alle, die integrieren
REST-API mit eigenen Zugangsschlüsseln, signierte Webhooks und inkrementelle Synchronisation.
API-Referenz →Was das Board ist
Ein Multi-Marken-Support-Board: Sie betreuen IHRE Kunden, unter IHRER Marke, auf unserer Infrastruktur.
Das Support-Board ist eine einzige Warteschlange von Fällen für Ihren Betrieb: Ihre Kunden eröffnen Fälle über Ihre Website (Widgets), per API oder per E-Mail, und Ihr Team betreut sie in einem eigenen Panel unter dash.elportaldelcliente.com. Jeder Fall geht ein, kommt voran und eskaliert, ohne dass jemand wach sein muss — aber abgeschlossen wird er nur mit einem Namen dahinter.
Ihr Board ist ein isolierter Mandant: Ihre Fälle, Ihre Endkunden und Ihre Agenten vermischen sich mit niemandem sonst. Die Isolation ist Teil des Systemdesigns, keine Einstellung, die man vergessen könnte. Fasst unser Staff einen Ihrer Fälle als Support der letzten Instanz an, wird der Zugriff protokolliert, und Sie können ihn einsehen.
Erste Schritte
Von null auf Betrieb, in fünf Schritten.
- Erstellen Sie Ihr Konto unter dash.elportaldelcliente.com.
- Aktivieren Sie einen Plan. Bezahlt wird mit dem Guthaben Ihres Kontos (dieselbe Geldbörse für das ganze Ökosystem); fehlt etwas, bietet Ihnen der Bildschirm an, genau den Fehlbetrag aufzuladen.
- Laden Sie Ihre Agenten ein im Tab «Agenten»: E-Mail und Rolle (Agent oder Administrator). Sie erhalten einen Zugangslink zum Weitergeben.
- Schalten Sie ein Widget ein unter «Widgets und API»: Registrieren Sie die Domain Ihrer Website als autorisierten Origin, kopieren Sie das Script und fügen Sie es in Ihre Website ein.
- Integrieren Sie per Code? Stellen Sie im selben Tab Ihren
tab_live_-Zugangsschlüssel aus und folgen Sie der API-Referenz auf dieser Seite.
ACME), und Ihre Fälle werden als ACME-1044 nummeriert. Bereits vergebene Fallnummern werden nicht geändert.Das Board-Panel
Das Mandanten-Panel unter dash.elportaldelcliente.com, Tab für Tab.
| Tab | Funktion |
|---|---|
Übersicht | Status Ihres Abonnements, Ablauf, Verlängerung und Auto-Verlängerung. Hier wird auch gekündigt. |
Agenten | Per E-Mail mit Agenten- oder Administratorrolle einladen; Rollen ändern; Zugang entziehen. Der Inhaber bleibt geschützt. |
Widgets und API | Fall-Präfix, autorisierte Origins (CORS), die drei Widgets mit ihrem Script und die API-Zugangsschlüssel. |
Zugriffe des Anbieters | Das Audit: jeder Zugriff unseres Staffs auf Ihre Fälle — wer, was und wann. |
Die Agenten, die Sie einladen, sehen und betreuen die Fälle Ihres Boards; Administratoren verwalten zusätzlich das Abonnement, das Team und die Integrationen.
Widgets für Ihre Website
Drei Widgets, je eine Script-Zeile. Ohne Dritt-Iframes, ohne Tracking-Cookies.
Im Tab «Widgets und API» Ihres Panels: Schalten Sie das Widget ein, registrieren Sie die Domain Ihrer Website als autorisierten Origin und kopieren Sie das generierte Script. Der Parameter data-color akzeptiert Ihre Markenfarbe.
<script src="https://api.elportaldelcliente.com/api/tablero/widget/tablero.js"
data-tenant="su-tablero" data-widget="contacto" data-color="#a177ff"></script>
| data-widget | Funktion | Voraussetzung |
|---|---|---|
contacto | Kontaktformular: Name, E-Mail und Nachricht. Erstellt einen Fall auf Ihrem Board. | Widget eingeschaltet + autorisierter Origin |
abrir-caso | Fall-Eröffnung mit Betreff: gibt dem Besucher die Fallnummer zurück. | Widget eingeschaltet + autorisierter Origin |
tablero | Endkunden-Board: Der Kunde sieht seine Fälle, eröffnet neue und antwortet direkt auf Ihrer Website. | Wie oben + Kunden-Token (siehe unten) |
Schutzmechanismen des Widgets
Anonyme Widgets akzeptieren 10 Versuche pro Besucher (IP) alle 10 Minuten und Board. Ist das Widget ausgeschaltet, der Origin nicht autorisiert oder das Abonnement abgelaufen, antwortet das Widget mit 404 widget no disponible — absichtlich ununterscheidbar, um die Konfiguration Ihres Boards nicht preiszugeben.
Das Widget «tablero»: Ihren Kunden identifizieren
Das «tablero»-Widget zeigt jedem Endkunden nur seine eigenen Fälle. Dafür tauscht Ihr Server pro Kunde einen kurzlebigen Token ein: Rufen Sie POST /v1/clientes/:ref/token-widget mit Ihrem API-Zugangsschlüssel auf (server-seitig, niemals aus dem Browser) und übergeben Sie den Token an das Widget.
curl -X POST https://api.elportaldelcliente.com/api/tablero/v1/clientes/cli-842/token-widget \
-H "Authorization: Bearer $TABLERO_KEY"
HTTP/1.1 201
{"success":true,"data":{"token":"tabw_…","expires_at":"2026-08-18 21:15:00"}}
window.TableroPortal.setToken(token);
tabw_-Token lebt 15 Minuten und wird nicht verlängert. Läuft er ab, erhält das Widget 401 token_vencido: Tauschen Sie einen neuen ein. Geben Sie Ihren tab_live_-Schlüssel niemals im Browser preis — genau dafür existiert der kurzlebige Token.API-Zugangsschlüssel
Ein Bearer-Zugangsschlüssel pro Integration, mit begrenztem Umfang und widerrufbar.
Die Zugangsschlüssel werden in Ihrem Panel ausgestellt («Widgets und API» → «API-Zugangsschlüssel»). Sie haben die Form tab_live_… und werden nur ein einziges Mal angezeigt: Bewahren Sie sie in Ihrem Secrets-Manager auf. Wir speichern nur ihren Hash.
curl -H "Authorization: Bearer tab_live_…" \
https://api.elportaldelcliente.com/api/tablero/v1/
Beim Ausstellen können Sie die Scopes einschränken. Ein Schlüssel ohne explizite Scopes hat Zugriff auf Ihr gesamtes Board:
| Scope | Erlaubt |
|---|---|
casos.read | Fälle und ihre Antworten lesen |
casos.write | Fälle erstellen, antworten und Status/Priorität ändern |
clientes.read | Ihre Endkunden lesen |
clientes.write | Endkunden anlegen/deaktivieren und Widget-Tokens ausstellen |
departamentos.manage | Abteilungen lesen und verwalten (inklusive IMAP-Postfächer) |
webhooks.manage | Webhooks lesen und verwalten |
accesos.read | Das Zugriffs-Audit des Anbieters lesen |
- Maximal 5 aktive Zugangsschlüssel pro Board. Widerrufen Sie, was Sie nicht mehr nutzen.
- Der Schlüssel identifiziert Ihr Board: Senden Sie niemals
tenant_idim Body — die API lehnt das mit 400 ab. - Bei abgelaufenem Abonnement kann der Schlüssel weiterhin lesen (GET); jede Schreiboperation antwortet mit
402 suscripcion_vencida. - Ein widerrufener Schlüssel antwortet sofort auf allen Routen mit 401.
tab_live_-Schlüssel gehört niemals in den Browser, in eine Mobile-App oder in ein Repository. Für den Browser gibt es den kurzlebigen tabw_-Token.API-Referenz
REST über HTTPS, JSON in beide Richtungen, Antworten in der Form {success, data}.
Konventionen: Request-Bodys gehen als Content-Type: application/json; Datumsangaben sind UTC YYYY-MM-DD HH:MM:SS; paginierte Listen liefern total, page und limit. Was nicht Ihnen gehört, antwortet 404, niemals 403: Die API bestätigt die Existenz fremder Ressourcen nicht.
https://api.elportaldelcliente.com/api/tablero/v1
Root: Identität, Plan und Nutzung
GET / ist der Vertrag, der nicht lügen kann: Er liefert, wer Sie sind, welche Scopes dieser Schlüssel hat, Ihren Plan mit seinen Limits, den Status Ihres Abonnements und Ihren bisherigen Verbrauch.
curl -H "Authorization: Bearer $TABLERO_KEY" \
https://api.elportaldelcliente.com/api/tablero/v1/
{"success":true,"data":{
"tenant":{"slug":"su-tablero","nombre":"Su Marca"},
"scopes_de_esta_credencial":["casos.read","casos.write"],
"plan":{"id":"tablero-base","nombre":"BASE","limites":{"max_agentes":5,"max_departamentos":5,"max_articulos_kb":100}},
"suscripcion":{"estado":"active","current_period_end":"2027-08-18"},
"uso":{"agentes":3,"departamentos":2},
"recursos":["/casos","/clientes","/departamentos","/accesos","/webhooks"],
"version":"v1"}}
Endkunden
Ein Endkunde ist ein Kunde von Ihnen (kein Konto unseres Ökosystems). Er wird über external_ref identifiziert: die ID, die dieser Kunde in IHREM System hat.
| Methode | Route | Scope | Funktion |
|---|---|---|---|
| GET | /clientes | clientes.read | Kunden auflisten (bis zu 500, neueste zuerst) |
| POST | /clientes | clientes.write | Per external_ref anlegen oder aktualisieren (idempotentes Upsert) |
| GET | /clientes/:ref | clientes.read | Einen Kunden über seine external_ref lesen |
| DELETE | /clientes/:ref | clientes.write | Deaktivieren (löscht nicht: die Fall-Historie bleibt erhalten) |
| POST | /clientes/:ref/token-widget | clientes.write | Kurzlebigen Token für das Widget «tablero» ausstellen (15 Min.) |
curl -X POST https://api.elportaldelcliente.com/api/tablero/v1/clientes \
-H "Authorization: Bearer $TABLERO_KEY" \
-H "Content-Type: application/json" \
-d '{"external_ref":"cli-842","email":"[email protected]","name":"Maria Rojas"}'
POST /clientes ist ein Upsert per external_ref — ein wiederholter Aufruf dupliziert keine Kunden. Beim Erstellen von Fällen dagegen erzeugt ein Netzwerk-Retry einen neuen Fall: Wiederholen Sie nur, wenn Sie keine Antwort erhalten haben.Fälle
Die zentrale Ressource. Ein Fall hat Status, Priorität, optional einen Endkunden und eine Konversation aus Antworten. Interne Notizen der Agenten werden über die API niemals offengelegt.
| Methode | Route | Scope | Funktion |
|---|---|---|---|
| GET | /casos | casos.read | Auflisten mit Filtern: Status, Kunde, updated_since, limit (1-100), page |
| POST | /casos | casos.write | Einen Fall erstellen (subject erforderlich; cliente_ref, priority, department_id, body/body_html optional) |
| GET | /casos/:id | casos.read | Detail mit der vollständigen Konversation (Antworten geordnet). Akzeptiert die ID oder die Fallnummer (z. B. SOLC-1051) gleichermaßen |
| POST | /casos/:id/respuestas | casos.write | Als Ihr Team antworten, oder als der Kunde mit en_nombre_de |
| PATCH | /casos/:id | casos.write | status und/oder priority ändern |
Einen Fall erstellen, verknüpft mit einem Endkunden:
curl -X POST https://api.elportaldelcliente.com/api/tablero/v1/casos \
-H "Authorization: Bearer $TABLERO_KEY" \
-H "Content-Type: application/json" \
-d '{"subject":"No puedo entrar al panel","cliente_ref":"cli-842","priority":"high",
"body":"Al iniciar sesion la pagina queda en blanco."}'
HTTP/1.1 201
{"success":true,"data":{"id":"…","numero":"SOLC-1051"}}
Auflisten mit Filtern, und inkrementelle Synchronisation mit updated_since (ISO 8601): In diesem Modus ist die Reihenfolge updated_at aufsteigend — gedacht, um Seite für Seite voranzugehen, ohne Änderungen zu verlieren. Speichern Sie das höchste verarbeitete updated_at und verwenden Sie es als Cursor für den nächsten Durchlauf.
curl -H "Authorization: Bearer $TABLERO_KEY" \
"https://api.elportaldelcliente.com/api/tablero/v1/casos?estado=open&cliente=cli-842&limit=50&page=1"
# inkrementelle Synchronisation (Reihenfolge: updated_at aufsteigend)
curl -H "Authorization: Bearer $TABLERO_KEY" \
"https://api.elportaldelcliente.com/api/tablero/v1/casos?updated_since=2026-08-18T00:00:00Z&limit=100"
estado außerhalb der gültigen Liste (oder jeder nicht erkannte Parameter) antwortet mit 400 und dem Detail — nie wird es stillschweigend ignoriert oder die vollständige Liste ohne Warnung zurückgegeben.Auf einen Fall antworten. Ohne en_nombre_de zeichnet die Antwort als Ihr Team (author_type: agent); mit en_nombre_de zeichnet sie als dieser Endkunde (author_type: client):
curl -X POST https://api.elportaldelcliente.com/api/tablero/v1/casos/$CASO_ID/respuestas \
-H "Authorization: Bearer $TABLERO_KEY" \
-H "Content-Type: application/json" \
-d '{"body":"Ya lo revisamos: intente de nuevo.","autor_nombre":"Soporte Acme"}'
# ...oder im Namen des Endkunden:
-d '{"body":"Sigue igual desde mi lado.","en_nombre_de":"cli-842"}'
| Feld | Werte |
|---|---|
status | open · pending · resolved · closed |
priority | low · medium · high · urgent |
author_type | client · agent |
Abteilungen
Interne Warteschlangen Ihres Boards (Vertrieb, Abrechnung, Technik…). Jede kann ein eigenes IMAP-Postfach haben: Das Board fragt es ab und wandelt eingehende E-Mails in Fälle um.
| Methode | Route | Scope | Funktion |
|---|---|---|---|
| GET | /departamentos | departamentos.manage | Abteilungen auflisten (inklusive E-Mail-Konfiguration, ohne das Passwort) |
| POST | /departamentos | departamentos.manage | Erstellen (name erforderlich; IMAP-Postfach optional; unterliegt dem Plan-Limit) |
| PUT | /departamentos/:id | departamentos.manage | Beliebiges Feld bearbeiten; ein leeres email_password löscht die Zugangsdaten |
| DELETE | /departamentos/:id | departamentos.manage | Archivieren (bestehende Fälle bleiben unberührt) |
Das Postfach spricht immer IMAP (email_protocol: imap); das Passwort wird im Ruhezustand verschlüsselt und nie zurückgegeben. Mit email_polling_enabled: 1 läuft die Abfrage automatisch.
Zugriffs-Audit
Jeder Zugriff unseres Staffs auf Fälle Ihres Boards wird protokolliert. Es ist dasselbe Audit wie im Tab «Zugriffe des Anbieters», per API lesbar:
curl -H "Authorization: Bearer $TABLERO_KEY" \
https://api.elportaldelcliente.com/api/tablero/v1/accesos
Webhooks
Ihr System erfährt es im selben Moment: Jedes Ereignis geht signiert an Ihre HTTPS-URL.
| Ereignis | Wird ausgelöst, wenn |
|---|---|
caso.creado | Ein Fall entsteht auf Ihrem Board — per API, per Widget oder per eingehender E-Mail |
caso.respondido | Jemand antwortet: Ihr Team (über das Panel oder die API) oder Ihr Endkunde (Widget, API oder E-Mail) |
caso.estado_cambiado | Der Status eines Falls ändert sich (durch Ihr Team, die API oder unser System) |
Registrieren Sie mit POST /webhooks, so viel Sie brauchen: eine https-URL, die gewünschten Ereignisse und ein Secret von mindestens 16 Zeichen, mit dem wir jede Zustellung signieren.
curl -X POST https://api.elportaldelcliente.com/api/tablero/v1/webhooks \
-H "Authorization: Bearer $TABLERO_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://su-sistema.com/hooks/tablero",
"eventos":["caso.creado","caso.respondido","caso.estado_cambiado"],
"secret":"un-secreto-de-al-menos-16-caracteres"}'
Jede Zustellung ist ein POST mit dem Ereignis, dem Zeitpunkt der Emission und den minimalen Daten zum Reagieren. Die Signatur deckt timestamp.cuerpo ab:
POST /hooks/tablero
Content-Type: application/json
X-Tablero-Evento: caso.respondido
X-Tablero-Timestamp: 1765432100
X-Tablero-Firma: 3f1a… # HMAC-SHA256(secret, timestamp + "." + cuerpo)
{"evento":"caso.respondido","emitido_at":"2026-08-18T20:15:00.000Z",
"data":{"caso_id":"…","numero":"SOLC-1051","respuesta_id":"…","autor_tipo":"agent"}}
Die Signatur prüfen
Weisen Sie jede Zustellung zurück, deren Signatur nicht verifiziert oder deren Timestamp mehr als 5 Minuten von der Uhr abweicht. Vergleichen Sie in konstanter Zeit.
// Node.js
const crypto = require('node:crypto');
function verificarFirma(rawBody, headers, secret) {
const ts = headers['x-tablero-timestamp'];
const sig = headers['x-tablero-firma'];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const esperado = crypto.createHmac('sha256', secret)
.update(ts + '.' + rawBody).digest('hex');
return sig.length === esperado.length &&
crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(sig));
}
# Python
import hashlib, hmac, time
def verificar_firma(raw_body: bytes, headers: dict, secret: str) -> bool:
ts = headers.get("x-tablero-timestamp", "")
sig = headers.get("x-tablero-firma", "")
if abs(time.time() - float(ts or 0)) > 300:
return False
esperado = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body,
hashlib.sha256).hexdigest()
return hmac.compare_digest(esperado, sig)
Zustellsemantik (lesen Sie das, bevor Sie sich darauf verlassen)
- Ein Versuch pro Ereignis, ohne Wiederholungen. Antwortet Ihr Endpoint nicht innerhalb von 10 Sekunden mit 2xx, ist diese Zustellung verloren — der reale Zustand ist über die API jederzeit erneut lesbar.
- Ihre Absicherung ist die inkrementelle Synchronisation: Ein periodischer Durchlauf von
GET /casos?updated_since=…holt jedes verlorene Ereignis nach. GET /webhookszeigtfail_count,last_ok_atundlast_error_atjedes Webhooks: Prüfen Sie sie beim Debuggen.- Die Ereignisse werden unabhängig vom Weg ausgelöst: API, Widgets, das Panel Ihres Teams, unser Staff oder die eingehende E-Mail Ihres Endkunden.
Fehler
JSON-Fehler mit success:false; der HTTP-Code ist maßgeblich.
{"success":false,"error":"…"}
| HTTP | Bedeutung |
|---|---|
400 | Ungültige Anfrage: Ein Pflichtfeld fehlt oder ein Wert besteht die Validierung nicht |
401 | Zugangsschlüssel fehlt, ist ungültig oder widerrufen |
402 | Abonnement abgelaufen: nur Lesen bis zur Verlängerung (suscripcion_vencida) |
403 | Der Schlüssel hat nicht den Scope, den der Endpoint verlangt |
404 | Existiert nicht für Sie: Fremde Ressourcen und nicht vorhandene Routen antworten identisch |
409 | Konflikt: Plan-Limit erreicht oder Slug bereits vergeben |
429 | Zu viele Versuche (anonyme Widgets: 10 pro IP alle 10 Minuten) |
500 | Unser Fehler; falls er anhält, schreiben Sie uns mit der genauen Uhrzeit |
Die error-Meldungen sind menschenlesbarer Text und können sich ändern. Verzweigen Sie Ihren Code nach dem HTTP-Code und nach diesen stabilen Slugs:
| Stabiler Slug | Bedeutung |
|---|---|
suscripcion_vencida | 402 bei Schreiboperationen mit abgelaufenem Abonnement |
token_vencido | 401 des Widgets «tablero», wenn der tabw_-Token abgelaufen ist: Tauschen Sie einen neuen ein |
saldo_insuficiente | 402 des Panels beim Aktivieren/Verlängern ohne ausreichendes Guthaben |
Pläne
Fünf Jahrespläne, dasselbe Board. Der Unterschied ist, wie viele Menschen und wie viel Struktur hineinpassen.
Die aktuellen Preise werden auf der Startseite und über die öffentliche API (GET /api/public/tablero/plans) veröffentlicht. Alle Pläne enthalten unbegrenzte Fälle, Widgets, API, Webhooks und das Zugriffs-Audit.
| Plan | Agenten | Abteilungen | KB-Artikel |
|---|---|---|---|
| ZERO | 2 | 2 | 25 |
| BASE | 5 | 5 | 100 |
| PLUS | 10 | 10 | 250 |
| PRO | 20 | 15 | 500 |
| MAX | 50 | 25 | 1000 |
Nach Ablauf Ihres Abonnements gibt es eine Karenzzeit; danach wechselt das Board in den Nur-Lese-Modus (GETs antworten weiter, Schreiboperationen liefern 402). Ihre Daten werden nicht gelöscht.
Betriebslimits
- Fälle: unbegrenzt in allen Plänen. Listen akzeptieren ein
limitvon 1 bis 100 pro Seite. - Endkunden und Audit: Listen liefern bis zu 500 Zeilen (neueste zuerst). Nutzen Sie
GET /clientes/:reffür punktuelle Lesezugriffe. - Zugangsschlüssel: bis zu 5 aktive pro Board.
- Anonyme Widgets: 10 Versuche pro Besucher (IP) alle 10 Minuten.
- Anhänge: Die API akzeptiert noch keine Dateien; Anhänge eingehender E-Mails werden beim Fall aufbewahrt.
Die Trunk-API erzwingt heute keine starre Aufrufquote; arbeiten Sie in einem vernünftigen Rhythmus (Pausen zwischen den Seiten, Wiederholungen mit exponentiellem Backoff). Braucht eine Integration garantiertes Volumen, sprechen Sie vorher mit uns.