Le manuel de votre tableau
Une page, trois couloirs : commencez ici, passez le deuxième à qui traite les dossiers, et envoyez le troisième à qui écrit le code.
Pour qui administre
Activez la formule, invitez votre équipe, définissez votre préfixe de dossiers et pilotez la facturation.
Guide de démarrage →Pour qui publie le site
Trois widgets intégrables en une ligne de script : contact, ouverture de dossiers et tableau du client final.
Widgets →Pour qui intègre
API REST avec clés dédiées, webhooks signés et synchronisation incrémentale.
Référence de l’API →Qu’est-ce que le tableau
Un tableau de support multi-marque : vous servez VOS clients, sous VOTRE marque, sur notre infrastructure.
Le tableau de support est une file unique de dossiers pour votre opération : vos clients ouvrent des dossiers depuis votre site (widgets), par API ou par e-mail, et votre équipe les traite depuis un panneau dédié sur dash.elportaldelcliente.com. Chaque dossier entre, avance et escalade même quand tout le monde dort — mais ne se conclut pas sans un nom derrière.
Votre tableau est un locataire isolé : vos dossiers, vos clients finaux et vos agents ne se mélangent avec ceux de personne d’autre. L’isolation fait partie de la conception du système, pas d’une configuration que l’on pourrait oublier. Si notre personnel touche à l’un de vos dossiers en support de dernier niveau, l’accès est consigné et vous pouvez le consulter.
Guide de démarrage
De zéro à opérationnel, en cinq étapes.
- Créez votre compte sur dash.elportaldelcliente.com.
- Activez une formule. Elle se paie avec le solde de votre compte (le même portefeuille pour tout l’écosystème) ; s’il en manque, l’écran vous propose de recharger exactement le montant manquant.
- Invitez vos agents dans l’onglet « Agents » : e-mail et rôle (agent ou administrateur). Vous recevrez un lien d’accès à leur remettre.
- Activez un widget dans « Widgets et API » : enregistrez le domaine de votre site comme origine autorisée, copiez le script et collez-le sur votre site.
- Vous intégrez par le code ? Émettez votre clé
tab_live_dans le même onglet et suivez la référence de l’API sur cette page.
ACME) et vos dossiers seront numérotés ACME-1044. Les dossiers déjà émis ne sont pas renumérotés.Le panneau du tableau
Le panneau du locataire sur dash.elportaldelcliente.com, onglet par onglet.
| Onglet | Ce qu’il fait |
|---|---|
Résumé | État de votre abonnement, échéance, renouvellement et renouvellement automatique. C’est aussi ici que l’on résilie. |
Agents | Inviter par e-mail avec un rôle d’agent ou d’administrateur ; changer les rôles ; retirer l’accès. Le titulaire reste protégé. |
Widgets et API | Préfixe de dossiers, origines autorisées (CORS), les trois widgets avec leur script, et les clés de l’API. |
Accès du fournisseur | L’audit : chaque accès de notre personnel à vos dossiers, avec qui, quoi et quand. |
Les agents que vous invitez voient et traitent les dossiers de votre tableau ; les administrateurs gèrent en plus l’abonnement, l’équipe et les intégrations.
Widgets pour votre site
Trois widgets, une ligne de script chacun. Sans iframes tiers, sans cookies de suivi.
Dans l’onglet « Widgets et API » de votre panneau : activez le widget, enregistrez le domaine de votre site comme origine autorisée et copiez le script généré. Le paramètre data-color accepte votre couleur de marque.
<script src="https://api.elportaldelcliente.com/api/tablero/widget/tablero.js"
data-tenant="su-tablero" data-widget="contacto" data-color="#a177ff"></script>
| data-widget | Ce qu’il fait | Prérequis |
|---|---|---|
contacto | Formulaire de contact : nom, e-mail et message. Crée un dossier dans votre tableau. | Widget activé + origine autorisée |
abrir-caso | Ouverture de dossiers avec objet : renvoie le numéro de dossier au visiteur. | Widget activé + origine autorisée |
tablero | Tableau du client final : il voit ses dossiers, en ouvre de nouveaux et répond depuis votre site. | Ce qui précède + jeton client (ci-dessous) |
Protections du widget
Les widgets anonymes acceptent 10 tentatives par visiteur (IP) toutes les 10 minutes et par tableau. Si le widget est désactivé, si l’origine n’est pas autorisée ou si l’abonnement a expiré, le widget répond 404 widget no disponible — indiscernable à dessein, pour ne pas révéler la configuration de votre tableau.
Le widget « tablero » : identifier votre client
Le widget de tableau montre à chaque client final uniquement ses propres dossiers. Pour cela, votre serveur échange un jeton éphémère par client : appelez POST /v1/clientes/:ref/token-widget avec votre clé d’API (côté serveur, jamais depuis le navigateur) et remettez le jeton au 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_ vit 15 minutes et ne se rafraîchit pas. À son expiration, le widget recevra 401 token_vencido : échangez-en un autre. N’exposez jamais votre clé tab_live_ dans le navigateur — le jeton éphémère existe exactement pour cela.Clés de l’API
Une clé Bearer par intégration, à portée restreinte et révocable.
Les clés s’émettent depuis votre panneau (« Widgets et API » → « Clés de l’API »). Elles ont la forme tab_live_… et ne s’affichent qu’une seule fois : conservez-les dans votre gestionnaire de secrets. Nous n’en stockons que le hash.
curl -H "Authorization: Bearer tab_live_…" \
https://api.elportaldelcliente.com/api/tablero/v1/
À l’émission, vous pouvez restreindre ses scopes. Une clé sans scopes explicites a accès à tout votre tableau :
| Scope | Autorise |
|---|---|
casos.read | Lire les dossiers et leurs réponses |
casos.write | Créer des dossiers, répondre et changer le statut/la priorité |
clientes.read | Lire vos clients finaux |
clientes.write | Créer/désactiver des clients finaux et émettre des jetons de widget |
departamentos.manage | Lire et administrer les départements (boîtes IMAP comprises) |
webhooks.manage | Lire et administrer les webhooks |
accesos.read | Lire l’audit des accès du fournisseur |
- Maximum 5 clés actives par tableau. Révoquez celles que vous n’utilisez plus.
- La clé identifie votre tableau : n’envoyez jamais
tenant_iddans le corps — l’API le rejette avec un 400. - Abonnement expiré : la clé continue de lire (GET) ; toute écriture répond
402 suscripcion_vencida. - Une clé révoquée répond 401 immédiatement sur toutes les routes.
tab_live_ ne va jamais dans le navigateur, dans une app mobile ni dans un dépôt. Pour le navigateur, il y a le jeton éphémère tabw_.Référence de l’API
REST sur HTTPS, JSON dans les deux sens, réponses de la forme {success, data}.
Conventions : les corps s’envoient en Content-Type: application/json ; les dates sont en UTC YYYY-MM-DD HH:MM:SS ; les listes paginées renvoient total, page et limit. Ce qui n’est pas à vous répond 404, jamais 403 : l’API ne confirme pas l’existence de ressources d’autrui.
https://api.elportaldelcliente.com/api/tablero/v1
Racine : identité, formule et usage
GET / est le contrat qui ne peut pas mentir : il renvoie qui vous êtes, les scopes de cette clé, votre formule avec ses limites, l’état de votre abonnement et votre consommation en cours.
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"}}
Clients finaux
Un client final est un client à vous (pas un compte de notre écosystème). Il s’identifie par external_ref : l’ID que ce client porte dans VOTRE système.
| Méthode | Route | Scope | Ce qu’il fait |
|---|---|---|---|
| GET | /clientes | clientes.read | Lister les clients (jusqu’à 500, les plus récents d’abord) |
| POST | /clientes | clientes.write | Créer ou mettre à jour par external_ref (upsert idempotent) |
| GET | /clientes/:ref | clientes.read | Lire un client par son external_ref |
| DELETE | /clientes/:ref | clientes.write | Désactiver (sans supprimer : l’historique des dossiers est conservé) |
| POST | /clientes/:ref/token-widget | clientes.write | Émettre un jeton éphémère pour le widget « tablero » (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 est un upsert par external_ref — répéter l’appel ne duplique pas les clients. À la création de dossiers, en revanche, un réessai réseau crée un nouveau dossier : ne réessayez que si vous n’avez pas reçu de réponse.Dossiers
La ressource centrale. Un dossier a un statut, une priorité, un client final facultatif et une conversation de réponses. Les notes internes des agents ne sont jamais exposées par l’API.
| Méthode | Route | Scope | Ce qu’il fait |
|---|---|---|---|
| GET | /casos | casos.read | Lister avec filtres : statut, client, updated_since, limit (1-100), page |
| POST | /casos | casos.write | Créer un dossier (subject requis ; cliente_ref, priority, department_id, body/body_html facultatifs) |
| GET | /casos/:id | casos.read | Détail avec la conversation complète (réponses ordonnées). Accepte l’ID ou le numéro du dossier (ex. SOLC-1051) indifféremment |
| POST | /casos/:id/respuestas | casos.write | Répondre au nom de votre équipe, ou au nom du client avec en_nombre_de |
| PATCH | /casos/:id | casos.write | Changer status et/ou priority |
Créer un dossier lié à un client final :
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"}}
Lister avec filtres, et synchronisation incrémentale avec updated_since (ISO 8601) : dans ce mode, l’ordre est updated_at croissant, pensé pour avancer page par page sans perdre de changements. Conservez le updated_at le plus élevé traité et utilisez-le comme curseur de la passe suivante.
curl -H "Authorization: Bearer $TABLERO_KEY" \
"https://api.elportaldelcliente.com/api/tablero/v1/casos?estado=open&cliente=cli-842&limit=50&page=1"
# synchronisation incrementale (ordre : updated_at croissant)
curl -H "Authorization: Bearer $TABLERO_KEY" \
"https://api.elportaldelcliente.com/api/tablero/v1/casos?updated_since=2026-08-18T00:00:00Z&limit=100"
estado hors de la liste valide (ou tout paramètre non reconnu) répond 400 avec le détail — jamais ignoré silencieusement, ni renvoyé comme liste complète sans avertissement.Répondre à un dossier. Sans en_nombre_de, la réponse est signée par votre équipe (author_type: agent) ; avec en_nombre_de, elle est signée par ce client final (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"}'
# ...ou au nom du client final :
-d '{"body":"Sigue igual desde mi lado.","en_nombre_de":"cli-842"}'
| Champ | Valeurs |
|---|---|
status | open · pending · resolved · closed |
priority | low · medium · high · urgent |
author_type | client · agent |
Départements
Les files internes de votre tableau (ventes, facturation, technique…). Chacune peut avoir sa propre boîte IMAP : le tableau la sonde et convertit les e-mails entrants en dossiers.
| Méthode | Route | Scope | Ce qu’il fait |
|---|---|---|---|
| GET | /departamentos | departamentos.manage | Lister les départements (configuration e-mail incluse, sans le mot de passe) |
| POST | /departamentos | departamentos.manage | Créer (name requis ; boîte IMAP facultative ; soumis à la limite de la formule) |
| PUT | /departamentos/:id | departamentos.manage | Modifier n’importe quel champ ; email_password vide efface le mot de passe enregistré |
| DELETE | /departamentos/:id | departamentos.manage | Archiver (les dossiers existants restent intacts) |
La boîte parle toujours IMAP (email_protocol: imap) ; le mot de passe est chiffré au repos et jamais renvoyé. Avec email_polling_enabled: 1, le sondage s’exécute automatiquement.
Audit des accès
Chaque accès de notre personnel aux dossiers de votre tableau est consigné. C’est le même audit que l’onglet « Accès du fournisseur », lisible par API :
curl -H "Authorization: Bearer $TABLERO_KEY" \
https://api.elportaldelcliente.com/api/tablero/v1/accesos
Webhooks
Votre système est prévenu à l’instant même : chaque événement part signé vers votre URL HTTPS.
| Événement | Se déclenche quand |
|---|---|
caso.creado | Un dossier naît dans votre tableau — par API, par widget ou par e-mail entrant |
caso.respondido | Quelqu’un répond : votre équipe (depuis le panneau ou l’API), ou votre client final (widget, API ou e-mail) |
caso.estado_cambiado | Le statut d’un dossier change (par votre équipe, par l’API ou par notre système) |
Enregistrez autant que nécessaire avec POST /webhooks : une URL https, les événements voulus et un secret d’au moins 16 caractères avec lequel nous signerons chaque livraison.
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"}'
Chaque livraison est un POST avec l’événement, le moment d’émission et les données minimales pour réagir. La signature couvre timestamp.corps :
POST /hooks/tablero
Content-Type: application/json
X-Tablero-Evento: caso.respondido
X-Tablero-Timestamp: 1765432100
X-Tablero-Firma: 3f1a… # HMAC-SHA256(secret, timestamp + "." + corps)
{"evento":"caso.respondido","emitido_at":"2026-08-18T20:15:00.000Z",
"data":{"caso_id":"…","numero":"SOLC-1051","respuesta_id":"…","autor_tipo":"agent"}}
Vérifier la signature
Rejetez toute livraison dont la signature ne se vérifie pas ou dont le timestamp s’écarte de plus de 5 minutes de l’horloge. Comparez en temps constant.
// 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)
Sémantique de livraison (à lire avant de s’y fier)
- Une tentative par événement, sans réessais. Si votre endpoint ne répond pas 2xx en 10 secondes, cette livraison est perdue — l’état réel reste toujours relisible par l’API.
- Votre filet de sécurité est la synchronisation incrémentale : une passe périodique de
GET /casos?updated_since=…récupère tout événement perdu. GET /webhooksexposefail_count,last_ok_atetlast_error_atpour chaque webhook : consultez-les au débogage.- Les événements s’émettent quelle que soit la voie : API, widgets, le panneau de votre équipe, notre personnel ou l’e-mail entrant de votre client final.
Erreurs
Erreurs JSON avec success:false ; le code HTTP fait foi.
{"success":false,"error":"…"}
| HTTP | Signification |
|---|---|
400 | Requête invalide : un champ requis manque ou une valeur échoue à la validation |
401 | Clé absente, invalide ou révoquée |
402 | Abonnement expiré : lecture seule jusqu’au renouvellement (suscripcion_vencida) |
403 | La clé n’a pas le scope qu’exige l’endpoint |
404 | N’existe pas pour vous : les ressources d’autrui et les routes inexistantes répondent à l’identique |
409 | Conflit : limite de la formule atteinte ou slug déjà utilisé |
429 | Trop de tentatives (widgets anonymes : 10 par IP toutes les 10 minutes) |
500 | Erreur de notre côté ; si elle persiste, écrivez-nous en précisant l’heure exacte |
Les messages d’error sont du texte lisible par des humains et peuvent changer. Aiguillez votre code sur le code HTTP et sur ces slugs stables :
| Slug stable | Signification |
|---|---|
suscripcion_vencida | 402 sur les écritures quand l’abonnement a expiré |
token_vencido | 401 du widget « tablero » quand le jeton tabw_ a expiré : échangez-en un autre |
saldo_insuficiente | 402 du panneau à l’activation/au renouvellement sans solde suffisant |
Formules
Cinq formules annuelles, le même tableau. La différence, c’est combien de personnes et de structure y tiennent.
Les tarifs en vigueur se publient sur la page principale et par API publique (GET /api/public/tablero/plans). Toutes les formules incluent dossiers illimités, widgets, API, webhooks et audit des accès.
| Formule | Agents | Départements | Articles de KB |
|---|---|---|---|
| ZERO | 2 | 2 | 25 |
| BASE | 5 | 5 | 100 |
| PLUS | 10 | 10 | 250 |
| PRO | 20 | 15 | 500 |
| MAX | 50 | 25 | 1000 |
À l’échéance de votre abonnement s’ouvre une période de grâce ; ensuite le tableau passe en lecture seule (les GET continuent de répondre, les écritures renvoient 402). Vos données ne sont pas supprimées.
Limites opérationnelles
- Dossiers : illimités dans toutes les formules. Les listes acceptent un
limitde 1 à 100 par page. - Clients finaux et audit : les listes renvoient jusqu’à 500 lignes (les plus récentes d’abord). Utilisez
GET /clientes/:refpour des lectures ponctuelles. - Clés : jusqu’à 5 actives par tableau.
- Widgets anonymes : 10 tentatives par visiteur (IP) toutes les 10 minutes.
- Pièces jointes : l’API n’accepte pas encore de fichiers ; les pièces jointes des e-mails entrants sont conservées avec le dossier.
L’API principale n’impose pas aujourd’hui de quota rigide d’appels ; opérez à un rythme raisonnable (pauses entre les pages, réessais avec attente exponentielle). Si une intégration a besoin d’un volume garanti, parlons-en d’abord.