# Capibara > Capibara est une suite d'applications de gestion (ERP/CRM) pour > TPE, PME et indépendants, avec un constructeur de site web intégré. Tout > le business dans un seul outil : facturation et devis conformes (France), > comptabilité, CRM, boutique en ligne, stock, projets, planning de > rendez-vous, support, blog, newsletter, RH, gestion de formation > (organismes QUALIOPI), messagerie et site vitrine — modulaire, activez ce > dont vous avez besoin. Hébergé en France, multilingue (fr d'abord). > Édité par Forge Network. Application : https://capibara.fr. > Capibara est propulsé par le moteur Colibri (« Colibri Engine ») ; > sa partie ouverte, OpenColibriEngine (« OpenColibri », OCE), est en > préparation — présentation : https://capibara.fr/colibri. ## Comment ça marche - On crée un compte, on choisit un profil (indépendant, e-commerce, association…) et un bouquet d'apps + un modèle de site est activé, tout reste modifiable. - Chaque organisation (tenant) a son espace isolé, ses utilisateurs et rôles, ses données. - Les apps sont connectées : une vente crée un client CRM et sort du stock, un devis accepté devient une facture, etc. - Offres : Free / Pro / Business + modules à la carte. Le site vitrine se publie sur `.capibara.fr` ou un domaine personnalisé. - Un portail développeur permet de créer des add-ons (marketplace). --- # Centre d'aide (documentation utilisateur) --- ## Activer la double authentification ## Pourquoi activer la 2FA ? Un mot de passe seul peut être compromis (réutilisation, phishing). La 2FA ajoute un **code à 6 chiffres temporaire** généré par votre téléphone. ## Comment l'activer 1. Allez dans **Mon compte > Sécurité du compte**. 2. Cliquez sur **« Activer »** sur la ligne 2FA. 3. Scannez le QR code avec Google Authenticator, Authy ou 1Password. 4. Saisissez le code à 6 chiffres pour confirmer. 5. **Notez précieusement les 10 codes de récupération** — ils vous sauveront si vous perdez votre téléphone. --- ## E-mails et délivrabilité Capibara envoie beaucoup d’e-mails pour vous : confirmations de commande, factures et relances, réponses au support, newsletters, invitations… La « délivrabilité » désigne la probabilité que ces messages atteignent réellement la boîte de réception de vos destinataires. Elle dépend de deux choses : l’adresse depuis laquelle vous envoyez, et la façon dont votre domaine est authentifié. ## L’expéditeur de votre société Vos e-mails partent depuis une adresse dédiée à votre société, pas depuis une adresse générique. Dans Paramètres › E-mails, vous personnalisez le nom d’expéditeur affiché (par exemple « Maison Lumen ») et l’adresse de réponse — celle où atterrissent les réponses de vos clients. Tant que vous n’avez pas branché votre propre domaine, l’adresse d’envoi reste hébergée par Capibara sur une infrastructure déjà authentifiée : vous n’avez rien à configurer et la délivrabilité est bonne dès le départ. ## SPF, DKIM, DMARC : la carte d’identité de vos e-mails Ces trois réglages, posés dans les DNS de votre domaine, prouvent aux fournisseurs (Gmail, Outlook…) que vos e-mails sont légitimes : - SPF : déclare quels serveurs ont le droit d’envoyer en votre nom. - DKIM : signe chaque e-mail de façon infalsifiable ; le destinataire vérifie la signature. - DMARC : dit quoi faire d’un e-mail qui échoue aux contrôles (le mettre en quarantaine, par exemple) et vous en donne des rapports. - Sur votre propre domaine, l’assistant DNS de Capibara vous fournit les enregistrements exacts à coller — et vérifie qu’ils sont bien en place avant de basculer vos envois sous votre marque. ## Bonnes pratiques - Renseignez une adresse de réponse valide et surveillée : un expéditeur « fantôme » nuit à la réputation. - Pour vos newsletters, n’écrivez qu’à des personnes qui ont accepté (double opt-in) — les plaintes pour spam pèsent lourd. - Évitez les envois massifs d’un coup au démarrage : une montée en charge progressive « chauffe » la réputation d’envoi. - Un contenu propre (pas trop d’images ni de liens douteux, un lien de désinscription clair) améliore le classement en boîte de réception. ## En cas de problème Un outil de diagnostic (réservé aux personnes qui en ont le droit) teste votre configuration et signale ce qui manque. Si des e-mails partent en spam malgré tout, vérifiez d’abord SPF/DKIM/DMARC via l’assistant, puis la qualité du contenu et de vos listes. --- ## Utilisateurs et droits d’accès Dès que vous n’êtes plus seul à utiliser Capibara, la question n’est plus « qui peut se connecter » mais « qui peut faire quoi ». Un commercial n’a pas besoin de toucher à la comptabilité ; un stagiaire peut consulter sans supprimer. Les rôles servent exactement à ça : donner à chacun les bons accès, ni plus, ni moins. ## Inviter un membre Ouvrez Paramètres › Utilisateurs, puis « Inviter ». Vous saisissez l’adresse e-mail, choisissez un rôle (et éventuellement une ou plusieurs équipes), et la personne reçoit un lien pour définir elle-même son mot de passe. Tant qu’elle n’a pas accepté, l’invitation apparaît « en attente » et peut être renvoyée ou révoquée. Le nombre de personnes que vous pouvez inviter dépend de votre offre : 3 utilisateurs en Free, 25 en Pro, 500 en Business. Le plafond et le changement d’offre se lisent dans « Mon organisation › Abonnement ». ## Les rôles fournis - Propriétaire : le compte qui a créé la société. Il a tous les droits et ne peut pas être retiré — c’est le responsable au sens facturation/juridique. Il est unique. - Administrateur : les mêmes droits techniques que le propriétaire (gérer l’équipe, les modules, les réglages), sans le statut de propriétaire. - Manager : gère les opérations de son périmètre (contacts, ventes, projets…) sans toucher à l’abonnement ni aux réglages sensibles. - Employé : travaille au quotidien (créer et modifier) avec des droits volontairement limités. ## Des rôles sur mesure Avec les offres Pro et Business, vous créez vos propres rôles depuis Mon organisation › Rôles. L’éditeur regroupe les permissions en une carte par application. Les trois actions de base — Consulter (lecture), Modifier (écriture) et Supprimer — sont indépendantes : un rôle peut consulter sans modifier, ou ajouter sans supprimer. Le bouton « Tout cocher / décocher » d’une carte fait le tour de ses cases d’un clic. ## Des droits « au petit oignon » Au-delà des trois actions de base, chaque carte peut exposer des droits fins que vous accordez isolément — par exemple confier la modération des avis à quelqu’un sans lui ouvrir tout le site. Quelques exemples : - Site : modérer les avis, modérer le fil communautaire, gérer les sondages, les membres du site, les cartes (My Maps) ou la billetterie — chacun séparément. - CRM : gérer les cadences de relance (qui envoient de vrais e-mails), importer des contacts en masse, configurer la boîte e-mail CRM. - Stockage : importer des fichiers, partager, déplacer entre espaces — sans ouvrir l’écriture complète. ## Les actions sensibles sont isolées Certaines actions touchent à l’argent, à la paie ou à des données très sensibles. Pour éviter qu’un rôle large en hérite « en douce », elles sont volontairement séparées : même un rôle qui gère toute une application ne les a PAS tant que vous ne les accordez pas explicitement (le Propriétaire et l’Administrateur, eux, les ont toujours). En clair : - RH : voir et traiter la paie (export des variables, masse salariale) est un droit à part — un rôle qui gère les salariés, congés et contrats ne voit pas la paie sans lui. - CRM : exporter toute la base clients (fichier RGPD) est un droit dédié, retirable même à un gestionnaire du CRM. - Stockage : publier dans la bibliothèque de l’Organisation (l’espace commun) est un droit à part — sans lui, un membre range ses fichiers dans « Mon espace » ou une équipe, jamais dans l’espace commun. - Site : rembourser des billets, résilier un abonné payant, acheter des crédits IA — chacun est un droit « argent » séparé du reste de l’édition du site. ## Gérer un membre au fil du temps - Changer son rôle ou ses équipes à tout moment. - Suspendre un accès : la personne ne peut plus se connecter et ses sessions actives sont coupées immédiatement (utile lors d’un départ). - Retirer un membre : des garde-fous sont en place — impossible de retirer le propriétaire ou le dernier administrateur. - RGPD : chaque membre peut exporter ses données ou demander leur suppression depuis son espace ; un administrateur peut aussi le faire pour lui. ## Bonne pratique Appliquez le principe du moindre privilège : partez d’un rôle restreint et ajoutez des droits au besoin. Créez un rôle par métier (« Compta », « Vente », « Support ») plutôt qu’un rôle « presque admin » pour tout le monde — c’est plus clair et plus sûr. --- ## Données et sécurité Vos données de gestion (clients, factures, documents, échanges…) sont sensibles. Voici, en clair, comment Capibara les protège et ce que vous pouvez en faire. ## Vos données sont isolées Chaque société dispose de son propre espace de base de données et de son propre dossier de stockage, cloisonnés des autres. Vos données ne sont jamais mélangées avec celles d’une autre organisation. Un fichier n’est servi qu’aux personnes autorisées, et l’accès est revérifié à chaque requête. ## Hébergement et sauvegardes - Hébergement en France : l’infrastructure est opérée chez un hébergeur français, sans transfert de vos données de gestion hors de l’Union européenne. - Sauvegardes régulières : la base et le stockage sont sauvegardés de façon récurrente, avec une copie hors-site, pour pouvoir restaurer en cas d’incident. - Connexions chiffrées : tout transite en HTTPS/TLS ; les mots de passe sont hachés (jamais stockés en clair) et les secrets sensibles sont chiffrés au repos. ## Traçabilité Un journal d’activité conserve les actions importantes (créations, modifications, suppressions, partages) avec leur auteur et leur date. Côté sécurité de compte, vous pouvez consulter vos sessions actives et les révoquer, et l’authentification à deux facteurs est disponible. ## Vos droits RGPD - Accès et portabilité : vous exportez vos données à tout moment (un export structuré est proposé dans votre espace). - Rectification : vous corrigez vos informations directement dans l’application. - Effacement (droit à l’oubli) : sur une fiche contact, l’anonymisation efface les données personnelles tout en gardant l’ancrage comptable/légal nécessaire. - Sous-traitants : la liste des prestataires techniques (paiement, e-mail…) et le registre des traitements sont publiés dans les pages légales. ## Conservation et suppression En cas de résiliation, votre espace est conservé un temps limité (pour vous permettre un dernier export ou un retour) puis supprimé. Les données de facturation sont, elles, conservées selon les durées imposées par la loi (obligations comptables et fiscales). --- ## Support client : tickets suivis sur votre site et chat en direct L'app Support client donne à votre site une vraie porte d'entrée SAV : une page /support où vos clients ouvrent une demande (un « ticket »), et un fil de conversation qu'ils suivent depuis le lien reçu par e-mail. Chaque réponse de votre équipe leur parvient par e-mail, à votre marque, avec ce lien de suivi. Personne n'a besoin de compte Capibara : le lien du ticket suffit. Si les comptes membres de votre site sont actifs, la demande passe par le compte : l'identité vient du compte (pas de champs nom/e-mail à retaper), et le membre retrouve toutes ses demandes dans SON espace « Mes tickets » (menu de son avatar, sous « Mon profil ») — liste de ses tickets d'un côté, ouverture d'une nouvelle demande de l'autre, et pour chaque ticket la conversation complète avec les informations et actions à côté. ## Le cycle d'une demande - Le client envoie sa demande → la confirmation s'affiche À L'ÉCRAN avec sa référence (TCK2026-0001) et un bouton « Suivre ma demande ». Aucun e-mail d'accusé de réception : les e-mails ne partent que pour une MISE À JOUR. - Chaque nouvelle demande est annoncée par e-mail aux responsables de l'organisation (avec la référence, l'expéditeur, le message et un bouton vers le ticket — y répondre écrit directement au client). Chacun peut couper ces e-mails pour lui-même dans Paramètres → Notifications, sans priver les autres ; la notification in-app (cloche) reste dans tous les cas. - Vous répondez depuis Support client → il reçoit votre réponse par e-mail (avec le lien de suivi) et peut répondre depuis la page de suivi (avec des pièces jointes : images, PDF, documents — 3 par message, 5 Mo chacun). Les liens écrits dans les messages sont cliquables. - Vous marquez la demande « Résolue » → il est invité à noter l'échange (1 à 5). S'il répond après coup, la demande se rouvre toute seule — rien ne se perd. - Les notes INTERNES (case « Note interne ») ne partent jamais au client : elles restent entre collègues, sur fond ambre dans le fil. ## Délais de première réponse (SLA) Dans Support client, dépliez « Délais SLA de première réponse » pour fixer un objectif par priorité (en heures). L'échéance s'affiche sur chaque ticket ; si elle est dépassée sans qu'aucun agent n'ait répondu, l'assigné (sinon toute l'équipe) reçoit une alerte — une seule fois. L'onglet « À traiter » trie les tickets les plus urgents en premier. ## Le chat en direct (offre Pro) Depuis Support client → « Chat en direct », activez la bulle de chat de votre site : vos visiteurs vous écrivent en direct (prénom obligatoire, e-mail facultatif), vous répondez depuis l'écran dédié. Le visiteur voit quand un agent est en ligne et quand il écrit. Un visiteur abusif peut être bloqué 24 h ; les conversations sont automatiquement supprimées après 90 jours. Quand le chat est désactivé (ou sur l'offre Gratuit), la bulle n'apparaît pas — vos clients passent par le formulaire de la page /support, qui reste toujours disponible. ## L'assistant IA du chat (option) Sur l'écran Chat en direct, cochez « Assistant IA quand personne n'est en ligne » : si aucun membre de votre équipe n'a l'écran de chat ouvert, un assistant automatique répond à vos visiteurs à votre place. Il s'appuie UNIQUEMENT sur votre wiki (les livres de l'espace Organisation — jamais un livre personnel ou d'équipe) : plus votre wiki est fourni, mieux il répond. Quand il ne sait pas, il le dit et oriente vers le formulaire de la page Support. Ses réponses sont clairement marquées « Assistant IA » — il ne se fait jamais passer pour un humain. Dès qu'un membre de l'équipe ouvre l'écran de chat, l'assistant se tait et vous laisse la main. Chaque réponse consomme le quota IA mensuel de votre organisation (le même que les autres fonctions IA) ; quota épuisé, l'assistant se met simplement en veille. ## Sur votre site - Une entrée « Aide » apparaît automatiquement dans le menu de votre site quand l'app est active (menu en mode automatique — désactivable dans Mon site → Navigation). - Chaque demande crée (ou complète) la fiche du client dans le CRM, et son historique de tickets s'affiche sur sa fiche. --- ## Boîte e-mail CRM : archiver vos échanges et suivre les réponses La « Boîte e-mail CRM » est une adresse dédiée à votre organisation (par exemple crm.votreslug@capibara.fr). Elle a deux usages : classer automatiquement un e-mail dans la fiche du bon client, et arrêter une relance (cadence) dès que le contact répond. Vous gardez la main : rien n'est envoyé ni modifié à votre place, l'adresse ne fait que RECEVOIR. Point important : Capibara ne lit JAMAIS vos boîtes personnelles ni celles de votre équipe. Seule cette boîte dédiée, à vous, est relevée. Un e-mail qui n'y arrive pas n'est jamais vu. ## L'activer - Ouvrez le module CRM. Sur le tableau de bord, repérez la carte « Boîte e-mail CRM ». - Cliquez sur « Activer la boîte CRM ». L'adresse dédiée s'affiche. - Copiez cette adresse : c'est elle que vous utiliserez dans les deux usages ci-dessous. - Elle n'apparaît pas dans la liste de vos boîtes e-mail classiques : c'est une boîte technique, pas une boîte à consulter. ## Usage 1 — archiver un e-mail dans une fiche Quand vous écrivez (ou répondez) à un client depuis votre messagerie habituelle, ajoutez l'adresse CRM en copie cachée (Cci / Bcc). L'e-mail arrive dans la boîte CRM, Capibara reconnaît le destinataire et ajoute l'échange à l'historique de sa fiche. - Le contact est retrouvé par son adresse e-mail ; s'il n'existe pas encore, une fiche est créée. - Mettez l'adresse en copie CACHÉE (Cci) : votre client ne la voit pas. - Cela marche pour un e-mail que VOUS envoyez (le client est le destinataire) comme pour un e-mail entrant que vous transférez. ## Usage 2 — savoir quand un prospect répond à une relance Quand vous enrôlez un contact dans une cadence de relance, chaque e-mail de la cadence part avec une adresse de réponse spéciale : si le prospect clique sur « Répondre », sa réponse n'arrive PAS dans votre boîte perso, mais dans la boîte CRM. (Rien à configurer, c'est automatique pour les e-mails de cadence.) Là, Capibara fait trois choses tout seul : (1) il ARRÊTE la cadence — on ne relance jamais quelqu'un qui a déjà répondu ; (2) il ajoute la réponse, AVEC SON CONTENU, à l'historique de la fiche du contact — vous pouvez donc LIRE le message directement sur la fiche ; (3) il notifie la personne qui avait enrôlé le contact. Il suffit que la boîte CRM soit activée AVANT de lancer vos cadences. Sans elle, les réponses arrivent normalement dans votre boîte e-mail, mais la cadence ne s'arrête pas d'elle-même et la réponse n'est pas classée dans la fiche. ## Bien l'utiliser - Activez-la AVANT de lancer vos premières cadences, pour que la détection de réponse fonctionne dès le départ. - Prenez l'habitude de mettre l'adresse en Cci de vos e-mails clients importants (devis, propositions, suivis) : votre fiche client devient un historique complet, consultable par toute l'équipe. - Enregistrez l'adresse dans les contacts de votre logiciel de messagerie sous un nom simple (« CRM ») pour l'ajouter en un clic. - Astuce : si votre messagerie (y compris le webmail Capibara) permet de définir un Cci automatique ou par défaut, réglez-le une fois vers cette adresse — chaque e-mail que vous envoyez sera alors archivé dans la CRM sans que vous ayez à y penser. C'est le petit réglage qui change tout. - La réponse d'un prospect arrive dans la fiche (pas dans votre boîte perso), AVEC son contenu : fiez-vous à la notification et lisez la réponse directement sur la fiche. ## Pour l'équipe - Une seule adresse pour toute l'organisation : chaque commercial peut la mettre en copie, tous les échanges se centralisent au bon endroit. - Chacun voit l'historique complet d'un client sur sa fiche, même les e-mails envoyés par un collègue — fini les informations éparpillées dans les boîtes individuelles. - Personne n'a besoin d'un accès à la boîte CRM elle-même : on travaille dans les fiches, pas dans la boîte. ## Sécurité et vie privée La boîte CRM est relevée en lecture seule, à l'écart du circuit d'envoi de vos e-mails : même en cas de souci technique, un vrai e-mail ne peut jamais être perdu ni retardé — au pire, une copie n'est pas classée. Vos boîtes personnelles et celles de votre équipe ne sont jamais lues. Vous pouvez désactiver la boîte CRM à tout moment depuis la même carte. Pas de stockage inutile : une fois un e-mail classé dans la fiche, sa copie brute est SUPPRIMÉE de la boîte CRM. Seul le contenu utile reste dans l'historique du contact — la boîte ne se remplit pas au fil du temps. ## Bon à savoir - Le classement se fait par relève régulière : comptez quelques minutes entre l'envoi et l'apparition dans la fiche (ce n'est pas instantané). - Un même e-mail n'est jamais classé deux fois. - Cette boîte sert à CLASSER et à DÉTECTER les réponses ; ce n'est pas une messagerie à consulter. Pour lire/écrire vos e-mails, utilisez votre webmail habituel. --- ## Cadences : des relances automatiques qui s'arrêtent toutes seules Une cadence, c'est une suite d'étapes (e-mails et rappels) envoyées à un contact avec des délais entre chacune — par exemple : jour 0 un e-mail, jour 3 un rappel, jour 7 une tâche « appeler ». Vous la construisez une fois, elle tourne toute seule pour chaque contact que vous y mettez. Tout est pensé pour ne JAMAIS spammer : une seule étape part par cycle (jamais de rafale), et la cadence s'arrête d'elle-même dès qu'un contact répond, se désinscrit, que l'affaire est gagnée, ou que l'objectif que vous avez fixé est atteint. ## Créer une cadence - Ouvrez le CRM puis « Cadences de relance » et cliquez sur « Nouvelle cadence ». - Donnez-lui un nom (par exemple « Relance après devis »). - Ajoutez des étapes : E-mail (sujet + message), Tâche (un rappel pour vous ou un collègue), ou Attente (une simple pause). Chaque étape a un délai en jours. - Enregistrez : la cadence est prête. Vous pouvez l'archiver ou la réactiver à tout moment. ## La démarrer : à la main ou automatiquement Par défaut une cadence est MANUELLE : vous enrôlez un contact depuis sa fiche (carte « Cadences de relance »). C'est bien pour un usage ponctuel. Pour qu'elle démarre TOUTE SEULE, choisissez un déclencheur dans « Démarrer automatiquement » lors de la création. Dès que l'événement se produit pour un contact, il est enrôlé sans que vous ayez rien à faire. - Quand un devis est envoyé — pour relancer un devis resté sans réponse. - Quand un devis est accepté — pour enchaîner (remerciement, prochaines étapes). - Quand une facture est envoyée — pour accompagner le règlement. - Quand un rendez-vous est pris — pour préparer ou confirmer. - Quand un nouveau contact est créé — pour un message de bienvenue. ## L'objectif : s'arrêter quand c'est gagné Le réglage « Arrêter quand l'objectif est atteint » indique le but de la cadence. Dès que le but est atteint, la relance s'arrête immédiatement (avant le prochain envoi) et l'enrôlement est marqué « Objectif atteint ✓ » sur la fiche du contact. Par exemple : une cadence déclenchée par « devis envoyé » avec l'objectif « le devis est accepté » relance le client tant qu'il n'a pas signé, et s'arrête à la seconde où il signe. Vous ne relancez jamais quelqu'un pour rien. - Le devis est accepté. - La facture est payée. - La facture est envoyée. - Un rendez-vous est pris. ## Personnaliser les e-mails avec des variables Dans le texte de vos e-mails, écrivez des variables entre accolades : elles sont remplacées automatiquement par les infos du contact au moment de l'envoi. - {prénom}, {nom}, {société} — l'identité du contact. - {montant}, {numéro} — le montant et le numéro du devis ou de la facture (uniquement quand la cadence est déclenchée par un devis ou une facture). - Exemple : « Bonjour {prénom}, votre devis {numéro} de {montant} est toujours en attente. » ## Bien s'en servir en équipe - Commencez simple : 2-3 étapes suffisent. Vous ajusterez ensuite. - Gardez un ton courtois : la cadence n'est pas là pour harceler mais pour ne pas oublier de relancer. - Activez la Boîte e-mail CRM avant de lancer vos cadences : les réponses des prospects arrivent alors directement sur leur fiche et arrêtent la relance (voir l'article « Boîte e-mail CRM »). - Un contact désinscrit n'est jamais enrôlé ni relancé : la désinscription est respectée partout. --- ## Projets : tableau, temps passé et facturation L'app Projets sert à piloter un chantier (« Refonte site client X ») avec votre équipe : qui fait quoi, pour quand, combien de temps ça prend, et ce que ça rapporte. Chaque projet a son tableau, ses tâches, son temps et ses finances. ## Créer un projet - Projets → « Nouveau projet » : un nom, un client (optionnel, modifiable ensuite) et le mode de facturation (au temps passé, au forfait, ou sans facturation pour un projet interne). - Chaque projet reçoit une référence PRJ2026-0001 et démarre avec quatre colonnes : Nouveau, En cours, En validation, Terminé. Renommez-les, ajoutez-en, changez leur ordre : la colonne cochée « Terminé » marque les tâches comme faites. - Dans Réglages : responsable, dates, couleur, devis d’origine, forfait ou taux horaire, temps prévu global. ## Le tableau et les tâches - Ajoutez une tâche directement dans une colonne (« Ajouter une tâche ») et glissez les cartes d’une colonne à l’autre. Le rond à gauche d’une carte la termine (ou la rouvre) d’un clic. - Ouvrez une carte : importance et complexité (deux tags prédéfinis, présents dans tous les projets — Faible / Normale / Haute et Simple / Normale / Complexe), échéance, colonne, responsable, temps prévu, participants, étiquettes (partagées par toute l’organisation), description, pièces jointes. - La CHECKLIST : des étapes à cocher dans la tâche (« Maquette validée », « Textes reçus »…). Quand tout est coché, la tâche propose de se terminer — rien ne se termine tout seul. - L’onglet Liste montre toutes les tâches du projet triées par urgence, avec l’édition en ligne : un clic sur un tag change l’importance ou la complexité ; échéance, responsable et colonne se règlent dans la ligne. - Le fil de discussion de la tâche accepte les pièces jointes et les mentions @ : la personne mentionnée reçoit une notification, le responsable aussi à chaque nouveau commentaire. - Une tâche datée apparaît dans le calendrier de son responsable ; une tâche en retard lui est rappelée une fois. ## Avancement et urgence : calculés, jamais saisis - L’avancement d’une tâche se déduit de ce que vous saisissez : terminée = 100 % ; sinon la part de la checklist cochée ; sinon le temps passé rapporté au temps prévu (plafonné à 95 % tant que la tâche n’est pas dite finie) ; sinon la position de sa colonne dans le tableau. - L’avancement du projet est la moyenne des tâches pondérée par leur complexité (une tâche complexe pèse trois fois une tâche simple). Il s’affiche en tête du projet, avec le temps passé sur le prévu, la prochaine échéance et le nombre de tâches bloquées. - « Mes tâches » (onglet du hub) classe ce dont vous êtes responsable ou participant en quatre sections : à traiter en premier (échéance proche ou dépassée, importance haute), cette semaine, plus tard, bloquées. Le score d’urgence combine l’échéance, l’importance et la complexité d’une tâche pas encore commencée — il sert à trier, jamais à décider à votre place. ## Dépendances : « bloquée par » - Dans une tâche, « Bloquée par » désigne les tâches du même projet qui doivent être terminées avant (dix au plus, jamais de boucle). Une tâche bloquée se voit sur sa carte et sort de la file de « Mes tâches » jusqu’à ce que ce qui la bloque soit terminé. - Quand le dernier bloqueur est terminé, le responsable de la tâche débloquée reçoit une notification — une seule. - C’est la seule forme de dépendance : pas de diagramme, pas de chemin critique. La tâche qui bloque sait ce qu’elle débloque (« Débloque : … » dans son panneau). ## Répartir les tâches à l’équipe - « Répartir » (en tête du projet) présente les tâches sans responsable face à la liste des membres : vous posez tout d’un coup, et chaque personne reçoit une seule notification avec la liste de ce qui lui est confié. ## Transformer une facture payée en projet - Quand l’app Projets est active, la fiche d’une facture PAYÉE (Facturation › Documents) propose « Transformer en projet » : un projet au forfait du montant vendu, rattaché au client, avec une tâche par ligne de la facture (le temps prévu est repris quand la ligne parle d’heures). Vous le renommez et répartissez les tâches ensuite. - La facture est rattachée au projet : il ne refacture rien depuis Projets (le travail supplémentaire se facture dans Facturation, comme toute vente). Une facture convertie d’un devis dont le projet existe déjà est rattachée à ce projet, jamais dupliquée. ## Le temps - Depuis une tâche (« Ajouter » dans Temps passé) ou depuis l’onglet Temps du projet : durée (« 1h30 », « 45min », « 1,5 »), date, note, case « facturable ». - L’onglet Temps compare le prévu et le passé par tâche, et répartit le temps par personne. - Ces heures alimentent aussi le récapitulatif de paie de l’app RH pour les personnes qui y ont une fiche. ## Facturer - Au temps passé : « Facturer le temps passé » (onglet Finances) crée un BROUILLON de facture — une ligne par tâche, en heures, au taux de vente de la personne (sinon celui du projet). Vous relisez et émettez dans Facturation, comme n’importe quelle facture. Rien n’est jamais émis automatiquement. - Les heures reprises sont marquées « Facturé » ; supprimer le brouillon les rend facturables à nouveau. - Au forfait : « Facturer le forfait » facture ce qui reste (forfait moins ce qui a déjà été facturé sur le projet). Si le projet est rattaché à un devis, la conversion du devis en facture existe aussi. - Les factures et devis rattachés au projet sont listés dans Finances. ## Marge et rentabilité - Revenu : le temps facturable au taux de vente (mode temps passé) ou le forfait (mode forfait). - Coûts : le temps au COÛT horaire (saisi dans « Taux horaires », par personne ou par défaut — jamais déduit de la paie), plus les dépenses et bons de commande rattachés au projet (achats, sous-traitance), plus les sorties de stock rattachées. - Marge = revenu − coûts ; rentabilité = marge / revenu. C’est une estimation : elle vaut ce que valent les coûts horaires saisis. - L’onglet Finances (et les taux) sont réservés au droit « Projets — finances » : un membre de l’équipe sans ce droit voit le tableau et le temps, jamais les coûts ni la marge. ## Rattacher achats, sous-traitance et stock - Quand l’app Projets est active, un champ « Projet » apparaît à la création d’une dépense (Comptabilité), d’un bon de commande fournisseur (Stock › Achats) et d’un mouvement de stock. - Une prestation sous-traitée = une dépense (facture fournisseur) rattachée au projet : pas d’objet à part. ## Droits - Projets : voir, gérer les projets (colonnes, étiquettes, réglages), gérer les tâches (commenter, enregistrer du temps), supprimer. - Projets — finances : droit séparé pour la marge, les taux et la facturation (facturer exige aussi le droit d’écrire des documents de vente). --- ## Planning : calendrier, réservations et rappels L'app Planning rassemble automatiquement ce qui se passe dans votre organisation : réunions et visioconférences, réservations de ressources, congés approuvés, anniversaires des salariés, sessions de formation, tâches CRM et annonces Capibara programmées. Vous n'avez rien à ressaisir. ## Les quatre onglets - Aujourd'hui — le déroulé du jour (et un aperçu de demain) : qui fait quoi, ce qui est en cours. - Calendrier — la grille mois ou semaine. Cliquez un jour (ou double-cliquez en vue semaine) pour créer un événement. - Réservations — vos rendez-vous et ressources réservées : filtres, édition, assignation à un membre. - Ressources — salles, matériel ou personnes réservables, avec leurs horaires et la réservation en ligne. ## Créer un événement et choisir qui le voit Un événement peut être Privé (vous et vos invités), Ciblé (une ou plusieurs équipes et/ou rôles) ou visible par toute l'Organisation. Publier au-delà du privé demande la permission « Publier des événements » (rôles Manager et Administrateur par défaut). Les invités reçoivent une notification et retrouvent l'événement dans leur agenda. Ajoutez un rappel (10 minutes, 1 heure ou 1 jour avant) : chaque participant est prévenu au bon moment. ## Réservations en ligne Si une ressource est « réservable en ligne », vos clients réservent depuis la page publique de votre site. Ils reçoivent un e-mail de confirmation avec un lien d'annulation en un clic — le créneau se libère immédiatement et votre équipe est prévenue. Un client connecté à son compte membre est automatiquement relié à sa fiche. Rappel automatique : environ 24 h avant l'heure du rendez-vous, le client rattaché reçoit un e-mail « votre rendez-vous approche » (avec le même lien d'annulation), et le membre de l'équipe assigné reçoit une notification (et une notification push s'il l'a activée). Aucun réglage à faire — un seul rappel par réservation, jamais de doublon. ## Voir votre planning dans Google, Outlook ou Apple Dans l'onglet Calendrier, « S'abonner » vous donne un lien personnel à coller dans votre agenda habituel (Google Agenda : « Ajouter un agenda › À partir de l'URL »). La synchronisation est en lecture seule et respecte vos droits de visibilité. Le lien est personnel : s'il fuite, régénérez-le — l'ancien cesse aussitôt de fonctionner. --- ## Activer et gérer les modules Plutôt qu’un logiciel unique où tout est mélangé, Capibara est une collection d’applications que vous composez comme un jeu de briques. Le compte, le site et un socle d’applications de base sont gratuits ; le reste s’active à la demande selon vos besoins. Vous ne payez que ce que vous utilisez, et vous pouvez tout activer ou résilier à tout moment. ## Ce qui est toujours inclus (gratuit) Ces applications sont disponibles dès la création de votre compte, sans surcoût : - Site web — le constructeur de site/landing, avec ses styles, ses blocs et vos pages publiques. - Communications — le chat interne, les appels audio/vidéo et la visioconférence de votre équipe. - CRM — contacts, sociétés, opportunités et pipeline de vente. - Boutique — catalogue, panier et paiement en ligne. - Blog — articles et actualités publiés sur votre site. - Newsletter — listes d’abonnés et campagnes e-mail. - Projets & tâches — organisation en mode kanban. - Planning — calendrier, réservations et rappels. - Support client — tickets et demandes de vos clients. - Médias & Stockage — vos images, fichiers et documents partagés. ## Débloqué par les forfaits Pro et Business Certaines applications, plus avancées, nécessitent un forfait (facturé par utilisateur). Le forfait s’active pour toute l’organisation ; les applications qu’il débloque apparaissent alors dans votre menu. - Pro — Facturation & Devis (documents aux normes françaises), Comptabilité, et la Formation (organisme de formation / QUALIOPI). Pro apporte aussi le constructeur avancé et l’assistance de l’IA. - Business — RH & Employés, en plus de tout Pro (le Stock de base est inclus gratuitement ; le multi-entrepôts, l’inventaire physique et « À racheter » sont Business). Business ajoute le portail de connexion à votre marque (SSO), davantage d’utilisateurs inclus et un support prioritaire. ## Le marketplace : bien plus de modules, gratuits ou payants Oui, Capibara a un marketplace — et il est bien plus riche que les applications de base. C’est un catalogue de modules supplémentaires, publiés par Capibara ou par des développeurs indépendants (la communauté) : des versions plus complètes ou spécialisées d’une application de base (par exemple un module de devis taillé pour un métier précis, avec ses propres modèles et règles), des intégrations, des widgets pour votre tableau de bord… Si vous cherchez une fonction que l’application de base ne fait pas, ou une variante pensée pour votre secteur, c’est là qu’elle se trouve. Vous y accédez depuis « Modules » dans votre espace : l’onglet « Modules » regroupe les applications Capibara, l’onglet « Apps » les apps publiées par les développeurs (vos apps installées d’abord, puis le catalogue) — avec une recherche et des filtres, sans quitter votre espace. Un module s’installe en un clic et apparaît aussitôt dans votre menu ; il se retire aussi simplement. Gratuit ou payant : chaque module affiche clairement son prix. Les applications Capibara réservées à un forfait sont incluses dans Pro et Business sans rien payer en plus (elles sont marquées « Inclus Pro » ou « Inclus Business »). Les modules payants publiés par des développeurs indépendants se règlent à l’unité, quel que soit votre forfait — c’est ce qui rémunère leur auteur à chaque installation. ## Activer un module Ouvrez « Modules », choisissez l’application ou le module, sa périodicité (mensuelle ou annuelle — l’annuel est moins cher), et validez. Le paiement passe par Stripe ; vos coordonnées bancaires ne sont jamais stockées par Capibara. Les écrans et l’entrée de menu du module apparaissent immédiatement, sans redémarrage. ## Désactiver un module Vous résiliez une application ou un module à tout moment, en quelques clics, sans justification. Aucun nouveau prélèvement n’a lieu après la période déjà réglée, et vous gardez l’accès jusqu’à la fin de cette période. Ensuite, l’application est masquée mais vos données sont conservées : si vous la réactivez plus tard, vous les retrouvez. ## Les apps de développeurs : pause, accès par rôle, journal Chaque app installée depuis l’onglet « Apps » a sa propre page (Modules › Apps › l’app). On y trouve sa version, ses réglages, et quatre commandes qui répondent aux questions du quotidien : « on l’arrête un moment ? », « qui a le droit de l’ouvrir ? », « est-ce que ça marche ? », « on la retire ? ». - Mettre en pause / Reprendre — une app en pause disparaît des menus, des fiches et de votre site ; ses planifications, ses événements et ses appels s’arrêtent. Ses données, ses réglages, sa version épinglée et vos choix de rôles sont conservés tels quels : la reprise remet tout en place d’un clic, sans rien reconfigurer. - Qui peut l’utiliser — par défaut, les rôles Manager et Employé peuvent ouvrir l’app (les administrateurs le peuvent toujours). La carte liste vos rôles et accorde ou retire l’accès rôle par rôle. Ce choix est le vôtre : une mise à jour de l’app n’y touche jamais. - Journal & santé — les exécutions des 7 derniers jours (réussies, en erreur, temps de réponse), les e-mails et notifications envoyés par l’app avec leur quota du jour, ses planifications et l’état de son hébergement, résumés en un verdict : « fonctionne », « en erreur », « en pause », « consentement à mettre à jour »… Réservé aux administrateurs. - Désinstaller — les données de l’app sont conservées 30 jours puis effacées ; « Effacer maintenant » n’attend pas. Une réinstallation dans l’intervalle retrouve tout (données, réglages, accès). ## D’où vient une app : hébergée chez Capibara ou chez son éditeur Chaque fiche d’app, dans le catalogue comme à l’installation, porte une mention d’hébergement calculée depuis sa déclaration — jamais rédigée par l’éditeur. « Tourne chez Capibara » : son code s’exécute dans un bac à sable de la plateforme, sans accès réseau (ou, s’il appelle des services tiers, la mention nomme lesquels). « Backend chez l’éditeur (hôte) » : les écrans, actions et événements que vous lui confiez sont envoyés au serveur de son éditeur, hors de Capibara — consultez sa politique de confidentialité avant d’accepter ; ces apps passent toujours par une relecture humaine avant publication, et vos données restent stockées chez Capibara (l’app y accède uniquement avec les accès affichés). « Pages hébergées par l’éditeur » : ses écrans sont affichés dans un cadre isolé depuis son site. Une app peut aussi vous faire encaisser : elle remet à votre client un lien vers VOTRE page de paiement (celle de votre TPE virtuel ou d’une facture émise, sur votre site), réglée sur votre compte Stripe avec la commission de votre formule — l’app ne touche jamais l’argent ni le montant. Après le règlement, le client peut retourner sur le site de l’app, uniquement vers les domaines qu’elle a déclarés. ## La facturation par utilisateur (siège) Les forfaits Pro et Business sont facturés par « siège », c’est-à-dire par utilisateur actif de votre organisation. Vous ajoutez ou retirez des sièges selon la taille de votre équipe ; le montant s’ajuste au prorata. Les prix à jour et le comparatif « qui inclut quoi » sont affichés sur la page Abonnement de votre espace, toujours avant toute validation. --- ## Les apps du marketplace : installer, autoriser, suivre En plus des applications Capibara, votre espace accueille des apps écrites par des développeurs indépendants (le programme « Capibara for Developers »). Elles s’installent depuis Modules › Apps, s’exécutent dans un bac à sable de la plateforme ou chez leur éditeur, et n’accèdent à vos données que dans les limites que vous avez acceptées. Cet article explique ce que vous voyez à chaque étape et quels leviers vous gardez. ## Trouver et installer une app Ouvrez Modules puis l’onglet « Apps » : vos apps installées d’abord, puis le catalogue. Chaque fiche indique l’éditeur, la description, la version, le prix (gratuite, achat unique ou abonnement réglé par Stripe), une mention d’hébergement et la liste des permissions demandées, écrites en phrases humaines (« lire vos contacts », « créer des documents de vente »). Installer, c’est consentir à cette liste — et à rien d’autre. Une app reçoit un compte de service à son nom (« app:… ») qui n’a que ces droits ; tout ce qu’elle fait est inscrit au journal d’activité comme le serait l’action d’une personne. Le droit « utiliser l’app » est posé sur les rôles Manager et Employé à l’installation ; les administrateurs l’ont toujours. ## Ce qu’une app peut voir et faire Les permissions sont précises : une app autorisée à lire vos contacts ne voit ni vos factures ni vos salariés. Elle ne peut pas contourner ces limites, même si son code le demandait : la plateforme vérifie chaque appel. Quand une mise à jour réclame de nouvelles permissions, l’app est suspendue jusqu’à ce que vous les acceptiez ; les nouveautés sont marquées « nouveau » sur l’écran de consentement. Ce qu’une app peut vous apporter : une entrée de menu avec sa page, des widgets sur l’accueil, des panneaux sur les fiches contact et société, des blocs et des pages sur votre site public, des automatisations déclenchées par vos événements (vente encaissée, contact créé…) ou planifiées, des e-mails transactionnels, des notifications, des entrées au calendrier et des fiches dans la recherche. ## D’où vient une app La mention d’hébergement est calculée depuis la déclaration de l’app, jamais rédigée par l’éditeur. « Tourne chez Capibara » : le code s’exécute dans un bac à sable de la plateforme, en France, sans accès au réseau hors des sites que l’app a déclarés. « Backend chez l’éditeur » : chaque interaction est transmise au serveur du développeur, hors de Capibara — l’écran de consentement le dit en toutes lettres, et ces apps sont toujours relues par une personne avant publication. « Pages hébergées par l’éditeur » : l’app affiche ses propres pages dans un cadre isolé. ## Réglages, pause et accès par rôle La page d’une app (Modules › Apps › l’app) regroupe ses réglages (les secrets, comme une clé d’un service tiers, ne sont jamais réaffichés une fois enregistrés), sa version, et trois commandes : « Mettre en pause » (l’app disparaît des menus, des fiches et de votre site, ses automatisations s’arrêtent, ses données et réglages restent), « Reprendre », et « Qui peut l’utiliser » pour accorder ou retirer l’accès rôle par rôle. Une mise à jour de l’app ne modifie jamais vos choix de rôles. ## Journal et santé La carte « Journal & santé » résume les 7 derniers jours : exécutions réussies ou en erreur, temps de réponse, e-mails et notifications envoyés par l’app face à son quota du jour, planifications, état de son hébergement, et un verdict en un mot. Une app qui échoue trop souvent est automatiquement mise en attente quelques minutes ; vous n’avez rien à faire. ## Vos données dans une app Une app peut tenir ses propres données (par exemple des favoris, des paramètres, des fichiers) : elles sont stockées dans l’espace de votre organisation, pas chez l’éditeur, et figurent dans votre export de données. À la désinstallation, elles sont conservées 30 jours — une réinstallation retrouve tout — puis effacées ; « Effacer maintenant » n’attend pas. Les e-mails qu’une app envoie sont transactionnels, adressés uniquement à des personnes déjà liées à votre organisation, plafonnés par jour, et chaque destinataire peut les couper depuis le centre de préférences. Une app ne fait jamais de campagne. ## Les apps sur votre site public Dans le constructeur de site, le groupe « Vos apps » propose les blocs déclarés par vos apps installées ; « Mon site › Apps » active leurs pages à l’adresse de votre choix. Sur le site, l’app ne connaît du visiteur que son statut de membre connecté et son nom d’affichage, jamais son e-mail, et n’a aucun accès à votre espace de gestion. ## Paiements déclenchés par une app Une app peut créer un encaissement ou remettre à un client le lien de paiement d’une facture. Le règlement se fait toujours sur votre page de paiement (celle de votre TPE virtuel ou de la facture), sur votre compte Stripe, avec la commission de votre formule ; le client revient ensuite sur le site de l’app par un bouton explicite. Aucune carte n’est saisie chez l’éditeur. ## Désinstaller ou signaler Désinstaller se fait depuis la page de l’app ; ses données suivent la règle des 30 jours. Si une app se comporte mal, ouvrez un ticket au support Capibara : l’équipe peut couper une app pour toutes les organisations en cas d’incident, et vous en êtes prévenu. Les obligations des éditeurs (finalité des données, notification d’incident sous 48 heures, effacement après désinstallation) figurent dans les CGV du marketplace. --- ## Chat, appels et visioconférence Le module Communications réunit la messagerie interne de votre organisation : des salons thématiques (façon canaux), des messages privés et des groupes, des appels audio et vidéo, et un statut de présence. Tout est en temps réel et reste dans votre espace — rien ne transite par un service tiers de messagerie. ## Salons, messages privés et groupes Depuis « Chat », la colonne de gauche liste vos messages directs (personnes et groupes, les plus récents en haut) et vos salons rangés par catégories. Un salon peut être public (visible de toute l’organisation) ou privé (réservé à ses membres). Un message privé ou un groupe « supprimé » de votre liste réapparaît automatiquement au message suivant. - Créer un salon ou un groupe : bouton « + » en haut de la liste. - Réactions, réponse citée, fil de discussion et épinglage : au survol d’un message. - Ouvrir une conversation en fenêtre flottante : icône dédiée dans l’en-tête — la fenêtre survit à la navigation et se réduit en pastille. ## Réactions, non-lus et « en train d’écrire » Au survol d’un message, un sélecteur propose une palette de réactions ; elles se regroupent sous le message avec leur compteur, et un clic ajoute ou retire la vôtre. Chaque salon ou conversation non lu affiche une pastille indiquant le nombre de messages en attente ; l’ouvrir remet le compteur à zéro. Quand une personne rédige, la mention « … écrit » apparaît en bas de la conversation. ## Fenêtres de messages flottantes Comme sur une messagerie grand public, vous pouvez détacher un message direct en fenêtre flottante (icône dédiée dans son en-tête). Les fenêtres s’empilent en bas à droite de l’écran — jusqu’à trois à la fois — survivent au changement de page et se réduisent en pastille d’un clic. Chaque fenêtre affiche l’avatar et le statut de présence en direct de votre interlocuteur ainsi que ses messages non lus. Un nouveau message joue un son léger si la fenêtre est masquée ou réduite ; un bouton coupe le son par conversation, et le mode « Ne pas déranger » le coupe partout. Ces fenêtres ne s’affichent pas sur mobile. ## Mentions : prévenir la bonne personne Tapez un signe pour ouvrir le sélecteur, puis choisissez dans la liste : - @prénom — mentionne une personne (elle reçoit une notification). - //rôle ou //équipe — mentionne tous les membres d’un rôle ou d’une équipe. - #salon — insère un lien cliquable vers un salon. - Dans un salon, vous n’êtes alerté que si l’on vous mentionne (les messages ordinaires n’ouvrent pas de pastille). ## Envoyer sans notifier : @silent Commencez votre message par @silent (ou @muet) pour le publier sans déclencher de notification ni de son chez les destinataires. Le message s’affiche normalement dans la conversation ; il est simplement discret. Pratique pour un complément d’information tardif ou un message hors sujet. ## Commandes rapides Tapez « / » en début de message pour afficher les commandes disponibles dans la conversation courante : - /visio — démarre un appel vidéo. - /appel — démarre un appel audio. - /sujet Mon nouveau sujet — change le sujet du salon (réservé aux modérateurs). ## Partager un message précis Au survol d’un message, l’icône « lien » copie un permalien. Collé dans une autre conversation ou un e-mail, il ouvre la conversation et met le message en surbrillance. Les permaliens fonctionnent pour les messages récents de la conversation. ## Appels audio et vidéo Depuis l’en-tête d’une conversation, les boutons d’appel lancent une visio ou un appel audio (visioconférence hébergée, sans logiciel à installer). Les personnes concernées reçoivent une sonnerie et peuvent rejoindre en un clic. Un appel en cours affiche un bouton vert : cliquer relance les absents. Vous pouvez quitter la page tout en restant dans l’appel — il se replie en fenêtre. Les boutons d’appel n’apparaissent que si la visioconférence est activée sur votre instance et si vous en avez le droit. Pour inviter une personne extérieure à l’organisation, utilisez un lien d’invitation depuis l’espace Visio. ## Statut de présence Votre statut (En ligne, Inactif, Absent, Ne pas déranger, Hors ligne) est visible par vos collègues à côté de votre nom. Choisissez un mode manuel depuis le menu de votre profil. En « Ne pas déranger », vous continuez de recevoir les messages, mais sans notification sonore ni poussée. La fiche d’un membre indique aussi sa dernière activité. ## Réglages et notifications Chaque conversation peut être mise en sourdine temporairement. Les fenêtres flottantes ont un bouton de coupure du son. Les notifications respectent votre statut : rien n’est poussé lorsque vous êtes en « Ne pas déranger ». --- ## Visioconférence et invitations La visioconférence est hébergée sur votre instance Capibara : aucun logiciel à installer, aucun compte tiers. Les boutons d’appel apparaissent lorsque la visioconférence est activée sur votre instance et selon vos droits. ## Lancer ou rejoindre un appel Depuis l’en-tête d’une conversation ou d’un salon, les boutons « Appel audio » et « Visio » démarrent immédiatement un appel avec les participants. Les personnes concernées reçoivent une sonnerie et rejoignent en un clic. Vous pouvez quitter la page en restant dans l’appel : il se replie en fenêtre, et un bouton vert permet de relancer les absents. ## Réunions planifiées Une réunion créée à l’avance apparaît dans l’agenda de ses participants avec un bouton « Rejoindre » ; l’heure venue, tout le monde entre dans la même salle. Chaque salle est cloisonnée à votre organisation — personne d’autre ne peut y accéder sans invitation. ## Inviter une personne extérieure Depuis l’espace Visio, créez un lien d’invitation à partager par e-mail ou messagerie. L’invité rejoint sans compte : il saisit simplement son nom sur la page du lien. Trois types de liens : - Usage unique — valable pour une seule entrée, puis expire. - Usage limité — un nombre d’entrées défini (par exemple dix). - Permanent — réutilisable jusqu’à ce que vous le révoquiez. - Option « audio seulement » pour un simple appel vocal. Chaque lien se révoque à tout moment. ## Liens à vos couleurs Si votre organisation a branché un domaine personnalisé, les liens d’invitation peuvent utiliser une adresse à votre marque (par exemple visio.mondomaine.fr) au lieu de l’adresse Capibara. L’habillage de la salle aux couleurs de votre organisation est une option des offres avancées. ## Bon à savoir - Le nombre de participants simultanés peut dépendre de votre offre. - L’enregistrement des réunions n’est pas proposé. - Les appels et invitations restent hébergés chez Capibara, sans service de visio tiers. --- ## Validations et approbations Dans une équipe, certaines opérations ne doivent pas être décidées par une seule personne : engager une dépense, valider un devis fournisseur… Les validations ajoutent une étape d’accord, sans transformer chaque action en usine à gaz. La demande part, la bonne personne l’approuve ou la refuse, et l’action se poursuit (ou non). ## Quand une validation est demandée Une demande apparaît lorsqu’un flux le prévoit — par exemple un bon de commande d’achat qui attend un feu vert avant d’être envoyé au fournisseur. Chaque demande porte son contexte : ce qui est demandé, par qui, et le montant ou l’élément concerné. ## La cloche de validation Une icône en forme de coche, à gauche de la cloche de notifications, affiche une pastille dès qu’une demande vous attend. Le menu déroulant liste les demandes en cours : vous approuvez ou refusez sur place, sans changer de page. Tout se met à jour en temps réel — si un collègue traite une demande avant vous, elle disparaît de votre liste. ## Qui peut approuver Vous ne voyez et ne traitez que les validations que vos droits autorisent : l’autorisation d’approuver dépend du type de demande (le droit d’écriture sur le module concerné, par exemple les achats pour un bon de commande). Une personne sans le bon droit ne voit tout simplement pas ces demandes. ## Vue complète et historique Le bouton « Tout voir » ouvre la page Validations, qui conserve l’historique et le détail de chaque demande : qui a demandé quoi, quand, et la décision prise. Pratique pour retrouver une trace ou comprendre pourquoi une action a été bloquée. --- ## Boîtes e-mail et webmail En plus de la messagerie interne (le chat), Capibara peut héberger de vraies boîtes e-mail pour votre organisation, consultables depuis un webmail ou votre logiciel habituel (Thunderbird, Outlook, mobile). ## Deux façons d’avoir une adresse - Adresse incluse — de la forme libellé.votre-societe@capibara.fr (par exemple contact.mon-resto@capibara.fr). Le libellé est libre : contact, support, compta… Ces adresses partent depuis l’infrastructure authentifiée de Capibara : rien à configurer, bonne délivrabilité immédiate. - Votre propre domaine — de la forme libellé@mondomaine.fr, une fois votre nom de domaine branché et vérifié (voir « Brancher votre nom de domaine »). Vous envoyez et recevez sous votre marque. ## Créer et gérer les boîtes Depuis « Messagerie », un gestionnaire crée les boîtes, attribue chacune à un membre, réinitialise un mot de passe et gère les alias et transferts. La configuration (assistant DNS pour un domaine personnalisé) et les outils de diagnostic sont regroupés à part, réservés aux personnes qui en ont le droit. Deux sortes d’alias : l’alias vers une BOÎTE (contact@ délivre dans une boîte et devient une identité d’envoi dans son webmail) et l’alias d’ÉQUIPE (support@ défini sur une équipe : chaque membre reçoit les messages dans sa propre boîte, les signatures par défaut sont recomposées avec l’équipe et l’adresse commune, et la liste suit automatiquement les entrées et sorties de l’équipe — les réponses partent alors de l’adresse personnelle de chacun). ## Consulter son courrier Une personne qui dispose d’une boîte accède directement à son webmail (« Ouvrir la webmail »). Sans boîte, un message l’invite à en demander une à un administrateur. Le webmail s’utilise sans installation ; vous pouvez aussi configurer votre boîte dans un client de messagerie classique. ## Filtres, réponse automatique et transfert Dans le webmail, « Paramètres » propose trois sections gérées côté serveur — elles s’appliquent donc aussi quand vous lisez votre courrier depuis un téléphone ou un logiciel de messagerie : « Filtres » (des règles qui rangent, marquent ou rejettent automatiquement les messages selon l’expéditeur, l’objet ou un mot du message), « Réponse automatique » (un message d’absence envoyé aux personnes qui vous écrivent, avec dates de début et de fin) et « Transfert » (réexpédier votre courrier vers une autre adresse, en gardant ou non une copie). ## Courrier indésirable Le bouton « Indésirable » signale un message comme spam : il est déplacé dans le dossier des indésirables et le serveur apprend de ce classement pour mieux filtrer les suivants. L’inverse existe (« Légitime ») pour un message classé à tort. Aucun réglage n’est nécessaire. --- ## CRM : contacts, sociétés et pipeline de vente Le CRM (menu « CRM ») est le carnet d’adresses intelligent de votre organisation. Il réunit vos contacts (personnes) et vos sociétés, vos opportunités de vente et toutes les interactions — pour ne plus jamais perdre le fil d’une relation. ## Les formulaires de votre site alimentent le CRM - Dans l’éditeur de votre site, « Ajouter une section » propose deux formulaires. « Contact » (groupe Sections) envoie un message dans vos formulaires reçus et vous notifie. « Formulaire CRM » (groupe « Branchés sur vos apps ») fait la même chose ET crée une fiche contact dans le CRM — ou complète la fiche existante si l’adresse e-mail est déjà connue, sans jamais faire de doublon. - La fiche créée porte la source « formulaire du site », les champs remplis (prénom, nom, e-mail, téléphone) et le message en note. La notification « Nouveau prospect » ouvre directement la fiche. - Le cycle de vente part de là : sur la fiche du contact ou de la société, « Créer une opportunité » ouvre une affaire au stade Nouveau, pré-remplie ; depuis l’affaire, « Créer un devis » prépare un devis v2 lié. Le devis accepté passe l’affaire en Gagnée. - Les demandes de devis des pages Formation et les inscriptions à vos sessions créent aussi leur contact CRM, avec leur propre source. ## Contacts et sociétés Créez une fiche à la main, ou laissez la recherche d’entreprise (annuaire officiel) pré-remplir le nom, le SIRET, la TVA et l’adresse à partir du nom ou du numéro. Capibara évite les doublons : si une fiche existe déjà pour la même adresse e-mail, il la complète au lieu d’en créer une seconde. ## La fiche 360° Chaque tiers a une fiche « 360° » qui rassemble, selon vos droits sur les modules concernés, tout ce qui le relie à vous : devis, factures, commandes, tickets de support, projets, rendez-vous… Vous voyez d’un coup d’œil l’état d’une relation. Une timeline retrace les échanges, alimentée automatiquement par les événements (devis envoyé, facture payée, réservation…). ## Le pipeline Les opportunités se suivent dans un pipeline en colonnes (glisser-déposer d’une étape à l’autre). Chaque affaire a un propriétaire, un montant et une probabilité ; les prévisions pondérées se calculent toutes seules. Une carte « à relancer » signale les affaires qui dorment. ## Tâches et relances Créez des tâches avec échéance et rappel, assignées à un commercial. Pour automatiser le suivi, les cadences envoient des séquences de relances qui s’arrêtent d’elles-mêmes dès que le prospect répond ou que l’affaire est gagnée (voir l’article « Cadences »). ## Import, export et RGPD - Import : chargez un fichier CSV ; un écran de correspondance associe vos colonnes aux champs, avec un aperçu avant validation. - Export : réservé à un droit dédié — exporter toute la base est un acte sensible. - RGPD : consentement, fusion de doublons et droit à l’oubli (anonymisation) se gèrent depuis la fiche. --- ## Boutique : vendre vos produits en ligne La Boutique publie un catalogue sur votre site et encaisse les commandes en ligne. Elle se connecte au Stock, au CRM (les acheteurs deviennent des fiches) et à la Facturation. ## Produits, variantes et rayons - Créez des produits avec photos, description, prix et TVA ; déclinez-les en variantes (taille, couleur…) à prix et stock propres. - Rangez-les en catégories (rayons) et étiquetez-les avec des tags à facettes (couleur, matière…) pour filtrer. - Mettez des produits « à la une », épinglez vos best-sellers, ou réservez un produit à vos membres/adhérents. ## Panier et paiement Vos clients ajoutent au panier et règlent par carte (Stripe) ; l’encaissement va sur votre compte. Le parcours est en trois temps clairs : fiche produit → panier → coordonnées et paiement. Les totaux (promo, frais de port, franco) sont toujours recalculés côté serveur — jamais de mauvaise surprise. ## Boutique → Configurations : tous les réglages de vente La page Boutique → Configurations regroupe les réglages de vente : frais de port, classes d’expédition, politique de retours, présentation du catalogue, disposition de la boutique (avec aperçu), tarif adhérent et paliers d’adhésion. - Frais de port : un forfait, offert au-dessus d’un montant (franco), et un supplément au poids (€ / kg) si vos fiches produit portent un poids. - Classes d’expédition : chaque classe décrit un TYPE de colis (« Petit colis », « Volumineux », « Fragile »…) avec son tarif. Créez-les dans Configurations, puis affectez la classe à chaque produit concerné depuis sa fiche (carte « Logistique & marque »). Au panier, la classe la plus chère présente donne le tarif de base ; un article sans classe suit le forfait. - Tarif adhérent : une remise réservée à vos membres ou adhérents, appliquée automatiquement quand ils sont connectés. - Produits numériques : clés d’activation ou fichiers livrés par e-mail et dans l’espace du client — jamais de frais de port. ## Avis et recommandations Les clients laissent des avis (que vous modérez) ; un avis issu d’un achat vérifié est mis en avant. La fiche produit suggère aussi « souvent achetés ensemble » et « vous aimerez aussi », calculés à partir des ventes — et vous pouvez épingler jusqu’à quatre ventes croisées à la main sur chaque fiche. ## La fiche produit (administration) - Chaque produit a sa fiche complète : identité et prix, photos (médiathèque), variantes, contenu numérique, rayon et tags, mise en avant, tarif adhérent, logistique (poids, EAN, marque, classe d’expédition) et stock par entrepôt. - Générez vos déclinaisons depuis les maître-tags : cochez Couleur × Taille et la grille se crée (SKU dérivés, prix hérités) ; la fiche publique propose alors un sélecteur par axe. - Les rayons portent trois niveaux (rayon → collection → sous-collection), chacun avec son adresse publique et son fil d’Ariane. - Import CSV : tout ce que porte la fiche s’importe — identité (référence, nom, description en Markdown, prix HT, TVA, publication, audience), classement (rayon en chemin « A > B > C » créé au besoin, tags — « Couleur:Rouge » rattache le tag au maître-tag « Couleur », créé au besoin —, marque), logistique (EAN, poids, dimensions, classe d’expédition, virtuel, sur commande, stock, coût d’achat, remise adhérent) et déclinaisons via la colonne parent_sku. Le bouton « Importer » détaille chaque colonne et propose un fichier modèle. - Une colonne absente du fichier ne change rien : réimportez « référence, prix » pour ne mettre à jour que vos tarifs, sans risquer d’effacer le reste. La classe d’expédition doit exister avant l’import (son tarif ne s’invente pas). - Vous venez de WooCommerce ou d’Odoo ? Leur export s’importe tel quel : les en-têtes (post_title, Regular price, Categories, default_code, list_price, qty_available…) sont reconnus et les unités converties (kg → grammes, cm → millimètres). Vérifiez juste que les prix sont bien HORS TAXE. - Les photos s’importent avec un fichier ZIP joint au CSV : la colonne « image » liste les noms de fichiers du ZIP (« face.jpg|dos.jpg », jusqu’à 9 par produit) — jamais des adresses web. Elles rejoignent la médiathèque et s’ajoutent aux photos existantes. - Prix dégressifs : sur la fiche d’un produit, définissez des paliers « dès N unités → prix HT à l’unité ». Le client paie toujours le meilleur prix (jamais un cumul avec une campagne ou le tarif adhérent), la fiche publique affiche le tableau des paliers, et le panier applique le bon prix dès que la quantité franchit un seuil. ## Campagnes promo Dans Boutique → Promotions → Campagnes : nommez une opération (« Black Friday »), ciblez des collections avec un taux par collection, posez les dates — bannière à décompte, prix barrés et badges s’activent et s’éteignent tout seuls. Le prix barré respecte automatiquement le plancher légal des 30 derniers jours. Le tarif adhérent ne se cumule pas : le client obtient la meilleure des deux remises. ## Commandes, retours et factures - Chaque commande payée envoie une confirmation ; à l’expédition, le client reçoit le numéro de suivi que vous avez saisi. Un bon de livraison PDF s’imprime depuis la commande. - Retours : le client demande depuis son compte (fenêtre configurable, 14 jours par défaut), vous acceptez (adresse et consignes partent par e-mail) ou refusez avec motif ; à réception, la marchandise entre dans l’emplacement « Retours » non vendable — le remboursement vient APRÈS le contrôle du colis. - Facture : émise en un clic depuis la commande (acquittée, archivée), et automatiquement si l’acheteur a saisi un SIREN ou se fait livrer hors de France. Le client la télécharge depuis son compte. ## Modes de vente - « Sur commande » : le produit reste vendable épuisé (fabrication ou réappro après l’achat) — dit clairement au client. - Précommande : date de disponibilité affichée, paiement immédiat, e-mail automatique aux acheteurs le jour de la sortie. - « Plus que N » s’affiche sur les cartes quand le stock devient bas. ## Caisse et réappro - La Caisse (Facturation → Caisse, plan Pro) encaisse au comptoir : recherche par nom, SKU ou scan de code-barres, espèces, CB sur place ou QR payé sur le téléphone du client — même catalogue, mêmes prix, même stock que le site. - Le stock de base est inclus avec la boutique ; le multi-entrepôts, l’inventaire physique et l’écran « À racheter » (suggestions d’après vos ventes réelles + bon de commande pré-rempli) relèvent du plan Business. --- ## Blog : publier des articles Le Blog publie des articles sur votre site — pour votre référencement, vos actualités ou votre expertise. Il s’organise en trois onglets : Articles, Commentaires (modération) et Réglages. ## Écrire un article (par blocs) L’écriture se fait sur une page dédiée, par blocs : tapez « / » pour insérer un titre, une image (ou collez-la directement), une vidéo YouTube/Vimeo, un encadré, un bouton ou une intégration (un lecteur Spotify, une carte, un agenda… par simple adresse https). Tout s’enregistre automatiquement pendant que vous tapez. Ajoutez un chapô (l’accroche des cartes, du flux RSS et de l’e-mail aux abonnés), jusqu’à trois miniatures depuis votre médiathèque (la première illustre les cartes et le partage ; à plusieurs, elles forment le bandeau de l’article) et des tags. Vos articles écrits avant cette version s’ouvrent tels quels dans le nouvel éditeur. ## L’assistant d’écriture (IA) Dans l’éditeur, l’assistant prend une consigne libre — « rédige une introduction », « raccourcis de moitié », « corrige le ton » — et propose une version complète de l’article. Les différences s’affichent comme un comparatif : lignes vertes (ajouté) et rouges (retiré). Rien n’est modifié sans vous : vous appliquez ou ignorez, et Ctrl+Z revient en arrière. L’assistant est inclus à partir de l’offre Pro et ne peut jamais inventer d’images — il ne fait que réutiliser celles de l’article. ## Auteurs Chaque article affiche son auteur (nom et photo de profil), avec une page publique qui liste ses publications — de quoi mettre en avant les plumes de votre équipe. Ce comportement se désactive d’un clic dans les Réglages du blog si vous préférez publier au nom de l’organisation. ## Réserver du contenu Chaque article a une audience : public, réservé aux membres connectés, ou aux adhérents. Un article réservé n’est ni listé ni servi aux visiteurs non autorisés (le contenu n’est jamais envoyé), il est exclu de l’indexation, et commenter le suppose lisible. ## Le blog sur votre site Dès qu’un article est publié, votre blog apparaît tout seul dans la navigation de votre site (si vous laissez la navigation automatique). La liste est paginée, filtrable par tag, et chaque page adopte le style de votre site avec les balises SEO (JSON-LD) qui aident Google. Les articles publics entrent dans le plan du site (sitemap). Un flux RSS (format XML standard des agrégateurs) est publié à l’adresse /blog/rss de votre site — annoncé aux navigateurs, filtrable par tag ou par auteur. En bas d’un article, des articles liés (mêmes tags, puis récents) sont proposés. Chaque article porte un bouton « J’aime » (un par personne — dédupliqué par compte membre, sinon par navigateur) et des liens de partage (X, Facebook, LinkedIn, WhatsApp, e-mail, copier le lien) — de simples liens, aucun script de réseau social n’est chargé sur votre site. La page publique d’un auteur affiche son niveau (dérivé de ses articles, des j’aime reçus et des lectures récentes) et ses articles les plus appréciés. ## Commentaires Les commentaires sont modérés : rien ne s’affiche sans votre validation, et vous êtes notifié à chaque commentaire en attente. Quand les comptes membres de votre site sont actifs, commenter exige d’être connecté (identité et avatar du compte). L’onglet Commentaires permet de publier, dépublier ou supprimer. ## Abonnement e-mail et newsletter Un formulaire d’abonnement (double confirmation par e-mail) permet à vos lecteurs de recevoir les nouveaux articles — tout le blog ou seulement un tag. À la publication d’un article public, les abonnés concernés sont prévenus automatiquement et gratuitement. Un article réservé ne part jamais par e-mail public. Pour une annonce mise en forme à une liste de diffusion, « Envoyer par newsletter » (sur un article publié) prépare une campagne pré-remplie dans l’app Newsletter — titre, miniature, chapô et bouton « Lire l’article » ; rien ne part sans votre envoi. --- ## Newsletter : vos annonces par e-mail La Newsletter sert à annoncer vos nouveautés, promotions et actualités aux personnes qui ont choisi de vous lire. Elle est pensée pour être conforme (RGPD) et respectueuse par construction : consentement tracé, désinscription en un clic dans chaque e-mail, zéro pistage individuel. Vous la trouvez dans le menu « Newsletter », en trois onglets : Campagnes, Listes & abonnés, Modèles. ## Les listes : publiques ou réservées aux adhérents Une liste PUBLIQUE se remplit par le bloc « Inscription newsletter » de votre site, en double opt-in : la personne confirme son adresse par e-mail avant de compter. La date, le canal et le libellé exact de la case cochée sont conservés comme preuve de consentement. Une liste par défaut est créée à l’activation (« Actualités & promotions »). Si votre système d’adhésion est actif, vous pouvez créer des listes « Adhérents » : elles se remplissent toutes seules à partir de vos adhésions actives au moment de chaque envoi, avec au besoin un palier minimum (« Or et au-dessus »). Un adhérent qui se désinscrit des e-mails reste adhérent — il n’est simplement plus adressé. Vous pouvez aussi importer un fichier CSV d’abonnés existants — en attestant que ces personnes ont consenti (jamais une liste achetée). Chaque liste s’exporte en CSV, et vous pouvez désinscrire ou supprimer un abonné à sa demande (droit à l’effacement). ## Composer une campagne (par blocs) Une campagne se compose comme une page : titres, paragraphes, images, encadrés, boutons — tapez « / » pour insérer un bloc. Partez d’un modèle officiel, d’un de vos modèles ou d’une page vierge, réglez l’objet et le pré-en-tête (le texte d’aperçu), et choisissez la liste destinataire. Personnalisez chaque envoi avec des variables : écrivez {{prenom}}, {{nom}} ou {{email}} dans l’objet ou le contenu — chaque destinataire reçoit sa propre version (« Bonjour Enzo, »). Si la donnée manque pour un abonné, prévoyez un repli : {{prenom|ami·e}} affiche « ami·e » à la place. Le prénom vient du formulaire d’inscription de votre site (champ facultatif), d’un import, ou du compte membre pour les listes d’adhérents. L’aperçu montre le VRAI rendu de l’e-mail (bureau et mobile), aux couleurs et au logo de votre organisation — variables remplies avec des valeurs d’exemple. « M’envoyer un test » l’expédie sur votre propre boîte avant d’arroser qui que ce soit. Vous pouvez enregistrer une campagne comme modèle pour les suivantes. ## Envoyer, programmer, suivre L’envoi de campagnes est disponible à partir de l’offre Pro — sur l’offre Gratuite, vous composez, prévisualisez et testez librement (et les annonces automatiques de votre blog restent gratuites, dans l’app Blog). Envoyez tout de suite ou programmez une date : le contenu reste modifiable jusqu’au départ, et l’envoi s’annule à tout moment. Après l’envoi, la campagne affiche des statistiques honnêtes : envoyés, échecs, écartés (désinscrits, liste de suppression). Pas de taux d’ouverture — cette mesure repose sur un pixel espion que Capibara refuse de poser (et que la CNIL soumet désormais au consentement). En revanche, les liens de vos campagnes qui pointent vers votre site sont marqués comme venant de l’e-mail : vos statistiques de visite comptent la source « E-mail (newsletter) ». Chaque e-mail porte automatiquement une version web (« Voir dans le navigateur ») et un pied avec la mention d’inscription et le lien de désinscription — il n’est pas supprimable, c’est lui qui protège votre réputation d’expéditeur. ## Les protections d’envoi (pourquoi ça peut refuser) Les campagnes partent depuis une infrastructure partagée par toutes les organisations : quelques garde-fous protègent la délivrabilité de tous. Une campagne est plafonnée en destinataires (largement plus sur un domaine relié et vérifié — Paramètres › Société › Domaines), un budget quotidien monte progressivement avec l’ancienneté de votre organisation, et un même destinataire n’est jamais sollicité plus de quelques fois par semaine, tous canaux confondus. En cas de refus, le message vous dit le chiffre exact et le remède. Une adresse qui rejette définitivement vos e-mails ou qui s’est désinscrite est automatiquement écartée de tous les envois suivants — même si elle figure encore dans une liste. ## Bonnes pratiques - N’écrivez qu’à des personnes qui ont consenti : une liste achetée ou aspirée nuit à votre délivrabilité et n’est pas conforme. - Soignez l’objet et le pré-en-tête : c’est ce qui fait ouvrir. - Un rythme régulier vaut mieux qu’un envoi massif isolé. - Pour envoyer davantage et sous votre marque, reliez votre nom de domaine (voir « E-mails et délivrabilité »). --- ## Formation : gérer votre organisme de formation (QUALIOPI) L’application Formation (module en option, disponible sur toutes les formules) est conçue pour les organismes de formation (OF). Elle gère tout le cycle administratif et pédagogique et vous met à niveau des exigences QUALIOPI, avec des documents générés automatiquement à partir de vos données. Vous la trouvez dans le menu « Formation ». ## De la formation au dossier Vous créez une formation (durée, objectifs, tarif) dans votre catalogue, puis, pour chaque session, un dossier composé d’une ou plusieurs conventions. Une convention porte ses stagiaires, son devis et sa facture. Des modèles de documents et le « repiquage » automatique évitent de tout ressaisir : les informations de la formation et du client alimentent les pièces à produire. ## Les demandes reçues depuis votre site Chaque demande envoyée depuis une fiche de votre catalogue public arrive dans l’onglet « Demandes » (avec un badge sur les nouvelles) : devis ou inscription, contact complet, entreprise retrouvée dans l’annuaire SIRENE (le SIRET est capturé), participants nommés, financement envisagé, message. « Préparer un dossier » fait alors TOUT d’un coup : l’entreprise est réutilisée ou créée en client dans votre CRM, la convention est créée quand le SIRET est vérifié, et les participants deviennent les stagiaires — le dossier arrive prêt, en brouillon ; le devis et les envois restent vos gestes. « Analyser (IA) » pré-remplit l’import intelligent avec le texte de la demande. Les responsables reçoivent aussi un e-mail à chaque nouvelle demande. ## Signatures et feuilles de présence Les pièces à faire signer (convention, contrat, règlement…) partent par e-mail — aux couleurs de votre organisation — avec une signature électronique intégrée : le signataire ouvre un lien sécurisé et signe en ligne. Le règlement intérieur et le livret d’accueil se génèrent PAR stagiaire (chacun signe sa copie). Si un envoi échoue faute d’adresse, l’écran nomme le tiers concerné et vous propose de saisir une adresse ponctuelle. Les liens publics (signature, questionnaire) expirent automatiquement au bout de 30 jours pour la sécurité. Chaque séance porte ses horaires en clair — tapez « 9h-12h30 / 14h30-17h45 » : les heures prévues en sont calculées automatiquement (et « Horaires types » les applique à toutes les séances d’un coup). La feuille de présence se remplit d’un clic : ✓ présent, ✗ absent, rond orange pour une présence partielle en heures ; « Tous présents / tous absents » traite une colonne. La feuille d’émargement PDF affiche les dates ET les horaires de chaque créneau. Le bouton « Convoquer » envoie aux stagiaires un e-mail complet — période et horaires, détail des séances, durée, lieu (mémorisé sur le dossier, sinon l’adresse de votre organisme), formateur, programme et contact — distinct de la pièce « Convocation » à signer. Anti-spam : une pièce envoyée ne peut pas être renvoyée pendant 10 minutes (chaque renvoi remplace le lien précédent — marteler le bouton casserait le lien déjà reçu). Sur la ligne de chaque stagiaire, le menu « Éval. » enregistre le résultat de l’évaluation des acquis (acquis / en cours / non acquis) : il est repris automatiquement dans son attestation de fin de formation. Vos stagiaires et entreprises disposent aussi d’une page publique de réclamation sur votre site (lien dans les e-mails) — chaque dépôt alimente votre registre Qualité. ## Questionnaires et satisfaction Vous créez vos propres questionnaires (positionnement en amont, satisfaction à chaud en fin de formation, satisfaction à froid quelques mois après) et les envoyez par un lien public. Les réponses sont agrégées pour votre suivi qualité et vos indicateurs. ## Votre catalogue sur votre site Chaque formation du catalogue peut être publiée sur votre site : ouvrez sa fiche puis cochez « Publier cette formation sur le site public » (avec un résumé, un visuel, les publics visés et les délais d’accès). La page /formations de votre site liste alors vos formations publiées, et chaque fiche publique reprend automatiquement l’information attendue par QUALIOPI : objectifs, prérequis, programme, modalités, délais d’accès, accessibilité handicap et tarif. Un formulaire de demande de devis crée directement un contact dans votre CRM et vous notifie. Le bouton « Vitrine » du catalogue règle ce qui entoure vos formations : texte d’accueil, indicateurs de résultats (satisfaction dès 3 réponses, assiduité, stagiaires formés — les mêmes chiffres que votre tableau de bord), certification Qualiopi (affichée en texte, jamais le logo, dont l’usage est encadré par votre certificateur), et lien vers vos avis Google. Si votre numéro de déclaration d’activité est renseigné, la mention légale « ne vaut pas agrément de l’État » est composée automatiquement. Deux sections du constructeur de site (« Catalogue de formations » et « Indicateurs de formation ») posent les mêmes contenus sur n’importe quelle page. ## Sessions inter-entreprises vendables en ligne L’onglet « Sessions » planifie des dates ouvertes à plusieurs entreprises : formation du catalogue, dates, lieu ou distance, nombre de places et prix par place. Une session publiée apparaît sur la fiche publique de la formation (et sur la page /formations) avec le nombre de places, les places prises et les places restantes — les visiteurs s’inscrivent et paient en ligne (le paiement arrive directement sur votre compte Stripe, comme la billetterie). Une session gratuite s’inscrit sans paiement. Chaque inscrit reçoit une confirmation par e-mail, avec les participants nommés. Une place non payée est automatiquement libérée après ~35 minutes si le paiement est abandonné. Côté suivi : le bouton « Inscriptions » liste les inscrits, permet de renvoyer une confirmation, d’annuler/rembourser une inscription (droit dédié « Rembourser une inscription de session »), et « Ajouter une inscription » enregistre une vente au guichet — chèque, espèces, TPE sur place, virement ou place offerte : les places sont réservées, la confirmation part par e-mail et la vente entre en comptabilité au moyen choisi. Trois jours avant la session, chaque inscrit reçoit automatiquement un rappel. Quand la session se concrétise, « Préparer le dossier » crée LE dossier de la session, puis « Créer la convention » transforme chaque inscription payée en convention conforme : vous choisissez la fiche entreprise (SIRET valide exigé), les participants deviennent les stagiaires — le circuit habituel (pièces, émargement, questionnaires) prend le relais. ⚠️ Une inscription payée en ligne est déjà encaissée et comptabilisée : ne refacturez pas la même prestation depuis la convention — la convention documente l’action. ## Avis publics de vos stagiaires La fiche publique de chaque formation accepte des avis (note sur 5 + commentaire). Rien n’est publié sans votre relecture : chaque avis arrive dans Site → Avis avec un badge « Formation : … », vous l’approuvez, le rejetez ou y répondez publiquement. Quand l’adresse e-mail de l’auteur correspond à un stagiaire d’une convention engagée de cette formation, l’avis porte le badge « Stagiaire vérifié ». La note moyenne alimente les résultats enrichis Google de la fiche. ## Financement et facturation La partie financière s’appuie sur votre module Facturation plutôt que de la réimplémenter : devis et factures des conventions sont de vrais documents comptables, avec la prise en charge des financeurs. Le BPF (bilan pédagogique et financier) ne comptabilise que les conventions réellement engagées — pas les brouillons — pour un chiffre juste. ## Vos formateurs Rattachez un formateur (fiche de l’onglet Formateurs) à chaque dossier — carte « Formateur » de la fiche dossier — et, si vous le souhaitez, à une session inter-entreprises : son nom apparaît alors sur la feuille d’émargement, l’archive du dossier, le champ de fusion {{formateur}} de la convention, et alimente les cadres formateurs du BPF. Un formateur qui a un compte dans votre organisation (invité normalement, avec un rôle même minimal) retrouve un onglet « Espace formateur » dans Mon compte : ses prochaines interventions, ses dossiers et l’état de ses pièces — sans accéder à la gestion de l’app. Le lien se fait par l’adresse e-mail : celle de sa fiche formateur doit être celle de son compte. ## Conformité QUALIOPI et BPF - Dossier formateur : registre des habilitations avec des alertes avant leur échéance. - Registre des réclamations et suivi de la satisfaction (indicateur QUALIOPI). - Veille QUALIOPI : un tableau de bord des indicateurs et de leur fraîcheur. - BPF : génération sur le Cerfa officiel, agrégats et export. - Export ZIP du dossier complet (pièces + données), prêt pour un audit. - Des droits d’accès fins par rôle : catalogue, dossiers, sessions, registre des formateurs, BPF et qualité s’accordent séparément (Mon organisation → Rôles). ## Zéro double saisie (IA) Le différenciateur de l’app : collez un e-mail de demande de formation, l’IA en extrait les informations, vous les relisez, et le dossier, la convention et les stagiaires sont créés d’un coup. Vous gardez toujours la main : rien n’est enregistré sans votre validation. --- ## Importer un agenda ou une invitation (.ics) Le format `.ics` est le standard des agendas : c’est ce que vous recevez quand quelqu’un vous envoie une invitation depuis Outlook, Google Agenda ou Apple Calendrier, et c’est aussi ce que produisent les billets de train, les convocations et les inscriptions à un événement. ## Importer Planning › onglet Calendrier › bouton « Importer ». Glissez le fichier, ou cliquez pour le choisir. Si votre webmail affiche l’invitation en texte plutôt qu’en pièce jointe, vous pouvez aussi coller son contenu. Le fichier est lu **dans votre navigateur** : rien n’est envoyé tant que vous n’avez pas validé. Vous voyez la liste de ce qu’il contient, avec les dates, les lieux, et un repère sur les événements qui se répètent. ## Ce qui arrive dans votre agenda Les événements sélectionnés sont ajoutés **en privé** : personne d’autre dans l’organisation ne les voit. Une fois importés, ils vous appartiennent et se modifient comme n’importe quel autre événement que vous auriez créé. Un événement marqué comme annulé par l’organisateur n’est pas coché par défaut — vous pouvez toujours le cocher si vous voulez en garder la trace. ## Réimporter sans créer de doublons Chaque événement porte un identifiant unique venu du fichier d’origine. Si vous réimportez le même fichier, Capibara reconnaît ce qui est déjà là et vous le dit (« 3 déjà présents ») au lieu de dupliquer. Vous pouvez donc relancer un import sans crainte. Cet identifiant est propre à chaque personne : si la même invitation est envoyée à trois collègues, chacun peut l’importer dans son propre agenda. ## Les limites, dites franchement Les répétitions simples (tous les jours, toutes les semaines, tous les mois, tous les ans, avec un intervalle et une fin) sont conservées. Une règle plus complexe — « le deuxième mardi du mois », par exemple — est **écartée** et l’événement est importé comme un rendez-vous unique : mieux vaut une date juste qu’une série qui tombe à côté. Un fichier est limité à 2 Mo et 500 événements. Tout ce qui est écarté vous est indiqué avec la raison — un import qui perd des lignes en silence est un import auquel on ne peut pas se fier. ## Dans l’autre sens : s’abonner à votre agenda Capibara Le bouton « S’abonner », juste à côté, fait l’inverse : il vous donne une adresse à coller dans Google Agenda, Outlook ou Apple Calendrier pour y voir vos événements Capibara, mis à jour automatiquement. --- ## Événements : le guide complet Capibara couvre un événement de bout en bout : la page publique qu’on partage, les invitations, la vente de billets, le contrôle à l’entrée, les obligations légales françaises, et l’album de photos d’après-soirée. Tout se gère depuis l’onglet « Billetterie » de votre site. Ce guide décrit l’ensemble. Les autres articles (« Billetterie », « Album partagé ») entrent dans le détail de chaque partie. ## Le point le plus important : invités OU billetterie (ou les deux) Ce sont deux mécaniques différentes, et les confondre fait perdre du temps. **Les invités**, c’est vous qui allez vers les gens. Vous entrez une liste de personnes, Capibara leur envoie une invitation par e-mail, et chacune répond « je viens », « je ne viens pas » ou « peut-être ». Personne ne paie, personne n’achète : vous cherchez à savoir COMBIEN de personnes seront là. C’est le mode d’un gala associatif, d’une inauguration, d’un repas d’entreprise, d’une réunion privée. La valeur, c’est le chiffre à donner au traiteur. **La billetterie**, ce sont les gens qui viennent vers vous. Vous publiez la page de l’événement, n’importe qui la trouve, choisit son tarif, paie en ligne et reçoit son billet avec un QR code. Vous ne connaissez pas les acheteurs à l’avance. C’est le mode d’un concert, d’une soirée étudiante, d’un spectacle. La valeur, c’est l’encaissement et le contrôle à l’entrée. **Les deux ensemble**, enfin, c’est le cas courant d’une soirée qui a du public payant ET une liste d’invités (partenaires, presse, artistes, bénévoles). Le réglage « Mode » de l’événement vous laisse choisir : Billetterie, Invitations, ou les deux. ## Créer l’événement Titre, date de début et de fin, lieu, capacité, visuel. La capacité est un compteur réel : Capibara refuse la vente au-delà, y compris si dix personnes achètent en même temps. Une fois publié, l’événement a sa propre adresse (`/evenement/votre-evenement`), indexable par Google, que vous pouvez partager telle quelle. Il apparaît aussi dans l’agenda public de votre site (`/evenements`) et dans le bloc « Billetterie » si vous l’avez posé sur une page. L’agenda public montre le prochain rendez-vous en vedette, puis les suivants mois par mois (date, lieu, tarif, places restantes ou complet), et garde vos derniers événements passés en bas de page — avec le lien vers l’album de photos quand il est ouvert. Dès qu’un événement est publié, le menu de votre site gagne automatiquement une entrée « Événements » (menu en mode automatique — la case se décoche dans Mon site › Navigation) ; l’agenda et chaque page d’événement entrent aussi dans le plan du site (sitemap). ## Remplir la page publique — ce qui fait vraiment venir les gens La page ne sert pas qu’à annoncer : elle doit répondre aux questions qu’on vous pose sinon cent fois en message privé. Quatre outils pour ça. **Les infos pratiques** : heure d’ouverture des portes (souvent différente de l’heure annoncée), âge minimum, et un texte libre pour l’accès. **Les commodités** : des cases à cocher qui deviennent des pictogrammes sur la page — parking sur place, accessible en transports, navettes, stationnement vélo, accès aux personnes à mobilité réduite, bar, restauration, vestiaire, places assises ou debout, extérieur, espace fumeurs, paiement par carte ou espèces uniquement, contrôle des sacs, animaux, bienvenue en famille. Deux secondes à cocher, et vous ne répondez plus jamais « oui il y a un parking ». **Le programme** : le déroulé horodaté de la soirée (20 h 30 première partie, 22 h concert, minuit DJ set). C’est la seule réponse à « je rate quoi si j’arrive à 22 h ? ». L’ordre est celui que vous saisissez, ce qui reste juste pour une soirée qui passe minuit. **Les questions fréquentes** : tout le reste, avec vos mots. Elles s’affichent en accordéon, et Google peut les reprendre directement dans ses résultats de recherche. ## Vendre des billets Créez un ou plusieurs **tarifs** (plein, réduit, VIP, étudiant…), chacun avec son prix et son quota. Un événement sans tarif est en admission générale. Un événement à 0 € se réserve sans paiement. L’argent arrive sur VOTRE compte, via vos encaissements en ligne (Stripe), comme pour la boutique. Reliez-les dans Paramètres › Facturation : tant que ce n’est pas fait, un événement payant ne peut pas être réservé en ligne. L’acheteur reçoit ses billets par e-mail, avec un QR code par place et un PDF de l’ensemble. Le QR est embarqué dans le message : il s’affiche sans que le destinataire ait à autoriser quoi que ce soit. ## Vendre sans passer par le site « Émettre des places » crée des billets directement : au guichet, en allotement pour un partenaire, pour la presse, ou pour rattraper une vente encaissée ailleurs. Vous choisissez la quantité, le tarif, un prix éventuel et un motif. Vous récupérez les codes en CSV et une planche de billets en PDF, et vous pouvez les envoyer par e-mail à une adresse. ## Inviter des personnes Ajoutez vos invités un par un, ou collez une liste (un nom et une adresse par ligne). Chacun reçoit un lien personnel : il répond sans créer de compte, indique combien de places il confirme, le nom de ses accompagnants, et peut laisser un mot. Vous suivez en direct **le chiffre du traiteur** : confirmés, en attente, refus, plus une estimation qui applique la marge que vous avez choisie. Les invités sans réponse sont relancés automatiquement, une fois à J+7 puis à J+14, jamais après la date limite. ## Ne pas devenir indésirable Les invitations sont le seul message que Capibara envoie à des personnes qui n’ont rien demandé : c’est vous qui saisissez leur adresse. Chaque invitation porte donc en pied un lien « ne plus recevoir d’invitations de cette organisation ». Quand quelqu’un s’en sert, il n’est plus jamais sollicité par vos invitations — ni par les relances automatiques, ni par l’annonce d’album. Vous le voyez au moment de l’envoi (« 2 désinscrits »), et ce n’est pas signalé comme une erreur : c’est le système qui fonctionne. Cette coupure ne touche PAS les messages liés à un achat : quelqu’un qui a payé sa place reçoit toujours son billet, son reçu et les informations d’annulation. Ce sont des messages essentiels, jamais désactivables. Un plafond quotidien limite par ailleurs le nombre de destinataires par organisation : les envois partent sous notre domaine et notre adresse IP, partagés par tous les clients. ## Le contrôle à l’entrée « Contrôle d’accès » scanne les QR codes à la caméra du téléphone, ou accepte le code saisi à la main quand le scan échoue — ça arrive tous les soirs. Deux propriétés qui comptent le jour J : la liste **fonctionne sans réseau** (téléchargée à l’avance, les entrées se synchronisent au retour de la connexion), et elle **se recharge toute seule** dès qu’il y a du réseau, pour que les places vendues depuis la file d’attente apparaissent. Un billet déjà scanné, annulé, remboursé ou appartenant à un autre événement est refusé avec le motif exact. Une liste d’émargement papier est imprimable, en dernier recours. ## Prévenir, annuler, rembourser « Prévenir / Annuler » envoie un message à tous les participants (changement de salle, report, météo) et permet d’annuler l’événement en prévenant tout le monde. Une commande se rembourse depuis « Participants » : le paiement en ligne est remboursé, les billets sont invalidés, et les places retournent en vente. ## Rester en règle (France) L’onglet « Conformité » vous pose quelques questions simples — musique, buvette, voie publique, artistes rémunérés, jauge de la salle — et en déduit vos obligations avec leurs échéances : déclaration SACEM, autorisation de buvette temporaire, déclaration en mairie, GUSO, licence d’entrepreneur de spectacles, jauge ERP, et pour les associations le compteur des six manifestations exonérées. Rien n’est bloqué : on informe, on alerte, la responsabilité reste la vôtre. Aucun autre outil de billetterie ne fait ça. ## Après l’événement L’**album partagé** ouvre un espace privé où les personnes présentes déposent leurs photos avec leur numéro de billet, et qui s’efface tout seul au bout du temps que vous choisissez. C’est la seule fonctionnalité d’après-soirée que vos participants vivent vraiment. Voir l’article dédié. ## Qui peut faire quoi Tout passe par le droit « Billetterie » du Site : lecture pour consulter les participants et le contrôle d’accès, écriture pour créer, vendre, émettre et modérer. Le remboursement demande en plus le droit dédié « Rembourser un billet », pour qu’un bénévole à la porte ne puisse pas rembourser une commande. --- ## Album partagé : les photos de vos participants, après l’événement Après un concert, une soirée ou un gala, vos participants ont tous des photos sur leur téléphone — et personne ne sait où les mettre. L’album partagé leur donne un endroit commun, réservé aux personnes qui étaient là, et qui disparaît de lui-même au bout du temps que vous choisissez. C’est la seule fonctionnalité « après l’événement » que vos participants vivent vraiment : elle prolonge la soirée et vous fait revenir sur leur écran une semaine plus tard. ## Ouvrir l’album Depuis l’onglet Billetterie de votre site, bouton « Album » sur l’événement. Vous cochez « Ouvrir l’album », choisissez la durée de vie (7 ou 30 jours après l’événement) et le nombre de photos par personne. C’est tout : l’adresse de l’album est ajoutée automatiquement à la page publique de l’événement. ## Comment vos participants entrent Ils saisissent le numéro figurant sur leur billet — ou collent le code reçu dans leur invitation. Aucun compte à créer : leur nom est repris du billet, et ils peuvent le remplacer par un pseudo. C’est ce qui fait la différence entre un album vivant et un album vide. ## Ce qui s’efface, et quand À l’échéance choisie, les photos sont supprimées : les fichiers ET les enregistrements. Ce n’est pas un réglage de confort, c’est la promesse faite aux participants — et la seule raison pour laquelle on peut héberger des centaines de photos par événement. Un compte à rebours est affiché en permanence sur l’album pour que chacun télécharge ce qu’il veut garder. Vous pouvez aussi vider l’album à tout moment depuis le bouton « Vider maintenant ». Vidé, ou effacé à son échéance, l’album se dit terminé dans le dialogue Album : « Relancer l’album » le rouvre, vide, pour la durée choisie. ## Deux façons d’ajouter des photos « Prendre une photo » ouvre un appareil photo directement dans l’album : un appui suffit, la photo part aussitôt et le viseur reste ouvert pour la suivante. La date et l’heure sont incrustées en bas à droite, comme sur un appareil jetable — ça date l’album pour toujours. « Ma galerie » permet de déposer des photos déjà prises. Celles-là ne sont pas tamponnées : on n’abîme pas une photo que quelqu’un avait déjà. ## Prévenir les participants Bouton « Prévenir les participants » dans le dialogue Album : un e-mail part à toutes les personnes qui ont une place (acheteurs de billets et invités ayant répondu), avec le lien de l’album et sa date de fin. Sans cet envoi l’album reste souvent vide — l’adresse figure bien sur la page de l’événement, mais personne n’y retourne le lendemain d’une soirée. ## Télécharger avant que ça disparaisse Depuis l’album, deux boutons : « Tout télécharger » et « Mes photos ». Chacun récupère une archive en un clic. C’est la contrepartie du compte à rebours : on prévient les gens que l’album va s’effacer, il faut donc qu’ils puissent tout sauvegarder sans enregistrer les photos une par une. ## Modération : signaler masque immédiatement N’importe quel participant peut signaler une photo. Elle est alors masquée tout de suite, sans attendre votre intervention : c’est ce qui protège les personnes photographiées qui ne veulent pas y figurer. Vous tranchez ensuite depuis la file « Photos signalées » — « Republier » si l’alerte était infondée, « Supprimer » sinon. Chaque participant peut également retirer ses propres photos sans passer par vous. ## Contenu sensible (événements 18 ans et plus) Sur un événement dont vous avez renseigné un âge minimum de 18 ans, vous pouvez autoriser le contenu sensible. Les photos concernées arrivent alors floutées et ne se révèlent qu’au clic, avec la possibilité de tout garder flouté. Vous devez cocher une attestation : c’est vous qui connaissez votre public. Les actes sexuels explicites restent interdits par les conditions d’utilisation, quel que soit le réglage. ## Vie privée et droit à l’image L’album n’est jamais public ni indexé par les moteurs de recherche : seules les personnes disposant d’un billet y accèdent. Les photos sont conservées le temps que vous avez choisi, puis supprimées. Un rappel sur le droit à l’image et un bouton de signalement sont affichés en permanence. --- ## Billetterie : vendre des billets pour vos événements La Billetterie permet de vendre des places pour vos événements (spectacles, ateliers, conférences…) directement depuis votre site. L’argent est encaissé sur VOTRE compte (via Stripe), comme pour la boutique. Elle se gère depuis l’onglet « Billetterie » de votre site. **À ne pas confondre avec les invités.** La billetterie, ce sont les gens qui viennent vers vous : ils trouvent votre page, choisissent un tarif, paient et reçoivent un billet. Les **invités**, c’est l’inverse : vous entrez une liste de personnes, elles reçoivent une invitation et répondent si elles viennent ou non — sans rien acheter. Un même événement peut faire les deux (public payant + invités partenaires ou presse). Voir le guide complet des événements. ## Créer un événement et ses tarifs Vous créez un événement (date, lieu, capacité, visuel) et définissez un ou plusieurs tarifs : plein, réduit, VIP, étudiant… chacun avec son prix et son quota. Un événement sans tarif est en admission générale. Chaque événement dispose d’une page publique dédiée (indexable par Google, avec les balises Event), à partager directement. ## Votre agenda public Tous vos événements publiés et à venir sont réunis sur une page unique : votre agenda public. C’est UNE adresse à mettre dans votre bio Instagram, votre signature ou vos affiches, au lieu de partager une page par soirée. Google l’indexe (balises Event), et les dates passées disparaissent toutes seules. Sur chaque événement, pensez aux « Infos pratiques » : heure d’ouverture des portes, âge minimum, accès et parking. Ce sont les trois questions que votre public pose systématiquement — les renseigner une fois vous évite d’y répondre cent fois en message privé. ## Vendre en ligne Ajoutez le bloc « Billetterie » à votre site : les visiteurs choisissent un tarif, une quantité, et paient par carte. Ils reçoivent leur billet par e-mail avec un QR code (et un PDF imprimable). Les places sont réservées de façon atomique — impossible de survendre, même en cas d’achats simultanés. Un événement gratuit émet les billets directement, sans passer par le paiement. ## Émettre des places en masse ou au guichet Vous pouvez émettre des places sans vente en ligne : en masse (vous récupérez un CSV des codes et une planche PDF de billets), au guichet, ou pour des ventes réalisées ailleurs. Vous pouvez aussi (r)envoyer les billets d’une commande par e-mail — pratique si un client a perdu le sien. ## Inviter des personnes et savoir qui vient Vendre des billets ne suffit pas toujours : pour un mariage, un gala ou une assemblée générale, vous voulez surtout savoir QUI VIENT. Le bouton « Invités » vous donne une liste d’invitations : ajoutez les personnes une par une, ou collez votre liste (un par ligne : nom ; e-mail ; nombre de places). Chaque invitation vaut pour un nombre de places que VOUS fixez à l’avance. C’est ce qui règle la question du « +1 » : votre invité voit « cette invitation vaut pour 2 personnes » et ne peut pas en confirmer davantage. Chacun dispose d’un lien personnel — copiez-le et envoyez-le comme vous voulez (e-mail, SMS, WhatsApp). Vos invités répondent sur une page simple, SANS créer de compte : oui, non, ou peut-être, avec le nom de leurs accompagnants, leurs réponses à vos questions (menu, allergies…) et un mot pour vous. Ils peuvent modifier leur réponse tant que l’événement n’a pas eu lieu — un désistement à l’avance vaut toujours mieux qu’une chaise vide. Beaucoup de réponses arrivent par téléphone ou de vive voix : vous pouvez les consigner vous-même en un clic sur la liste, pour que vos chiffres restent justes. ## Envoyer les invitations et relancer les silencieux Le bouton « Envoyer N invitations » écrit à tous ceux qui ont une adresse e-mail et ne l’ont pas encore reçue. Chacun reçoit un message à VOTRE nom (pas au nôtre) avec un gros bouton « Répondre en un clic » et un lien « Ajouter à mon agenda ». « Relancer les X sans réponse » ne s’adresse qu’à ceux qui n’ont rien répondu — jamais à quelqu’un qui a déjà dit oui, non, ou peut-être. La relance rappelle toujours POURQUOI vous insistez (« nous bouclons les effectifs le 12 ») : c’est ce qui fait la différence entre une relance bien reçue et un harcèlement. Une relance automatique part aussi toute seule : au bout d’une semaine sans réponse, puis une seconde fois une semaine plus tard — jamais davantage, jamais après votre date limite, et jamais deux fois le même jour. Passé ça, c’est qu’il faut décrocher le téléphone. ## Combien serez-vous ? (le chiffre à donner au traiteur) En haut de la liste des invités, vous voyez le chiffre à annoncer à votre prestataire. Ce n’est pas un simple compteur : tout le monde ne vient pas, et des accompagnants s’ajoutent au dernier moment. Nous affichons donc les confirmés, les « peut-être », les sans-réponse, puis une estimation qui ajoute une marge de sécurité (10 % par défaut, réglable), et le maximum possible si tout le monde venait. Vous pouvez aussi fixer une date limite de réponse, choisir d’autoriser ou non le « peut-être », et exporter votre liste en CSV pour votre traiteur ou votre salle. ## Conformité : ce que la loi française attend de vous C’est la partie que tout le monde découvre trop tard. Le bouton « Conformité » vous pose 4 questions simples (musique ? artistes rémunérés ? buvette ? voie publique ?) et en déduit VOS obligations, avec leurs dates limites et un compte à rebours. Exemples de ce qui remonte : la déclaration SACEM (20 % de réduction si vous déclarez au moins 15 jours avant), le GUSO dès que vous rémunérez un artiste ou un technicien, l’autorisation de buvette du maire (5 par an maximum pour une association), la déclaration en mairie pour la voie publique, l’assurance responsabilité civile, ou encore la règle qui veut que chaque entrant ait un billet — y compris gratuit. Renseignez la jauge autorisée de votre salle : nous vous alertons quand vos ventes s’en approchent ou la dépassent. Si vous êtes une association, un compteur suit vos 6 manifestations exonérées de l’année. Chaque point cite sa référence légale pour que vous puissiez vérifier, et se coche une fois traité. Attention : ces rappels sont informatifs et ne remplacent pas un conseil juridique — les règles varient selon votre situation, votre commune et votre lieu. ## Le jour J : contrôle d’accès, même sans réseau Avant d’ouvrir les portes, cliquez sur « Contrôle d’accès » puis « Télécharger la liste » pendant que vous avez du réseau. Ensuite, tout fonctionne HORS LIGNE : cave, salle des fêtes, 4G saturée par le public — le scan reste instantané, parce qu’il est tranché sur votre appareil et non sur nos serveurs. Vous pouvez ouvrir plusieurs portes en même temps : chaque poste scanne de son côté, et tout se synchronise dès que le réseau revient. Si un billet a déjà été validé à une autre entrée, il est signalé — impossible d’entrer deux fois avec le même billet. Trois filets de sécurité, pour que la file n’arrête jamais d’avancer : le scan du QR code, la saisie du code à la main, et la recherche par nom (quand l’écran du téléphone est cassé ou le billet froissé). En dernier recours, imprimez la liste d’émargement avec une colonne signature. Un compteur permanent vous indique combien de personnes sont entrées, combien sont attendues, et combien de scans restent à synchroniser. ## Prévenir tout le monde, ou tout annuler Le bouton « Prévenir / Annuler » couvre les deux imprévus classiques. « Prévenir les participants » envoie un e-mail à tous les détenteurs de billets — changement de salle, horaire d’ouverture, consignes d’accès. « Annuler l’événement » fait tout en un geste : les billets sont invalidés, les places libérées, les paiements en ligne REMBOURSÉS INTÉGRALEMENT, et chaque participant reçoit un e-mail avec votre motif. C’est une obligation légale : quand c’est l’organisateur qui annule, le remboursement est intégral (frais compris) et vous ne pouvez pas imposer un avoir. Si un remboursement échoue (carte expirée, litige en cours), nous vous le disons : le billet concerné n’est PAS invalidé, car on n’annule jamais un billet sans avoir rendu l’argent. ## Rembourser ou annuler Si vous devez annuler, le remboursement se fait proprement : Capibara rembourse le paiement en ligne, annule les billets concernés et libère les places automatiquement pour qu’elles redeviennent disponibles. --- ## Adhésions : abonnements récurrents pour vos membres Les Adhésions permettent de faire payer une cotisation récurrente à vos membres (association, club, média, communauté…). C’est un abonnement : le paiement se renouvelle tout seul chaque mois ou chaque année, encaissé sur VOTRE compte (via Stripe). Vous gérez tout depuis l’onglet « Adhésions » de votre site. À ne pas confondre avec VOTRE abonnement à Capibara — l’offre Free, Pro ou Business de votre organisation, qui se change dans « Mon organisation › Abonnement » et fait l’objet de son propre guide. Ici, il s’agit des cotisations que vos membres vous paient, à vous. ## Créer des paliers Vous définissez un ou plusieurs paliers (par exemple « Soutien » à 5 €/mois, « Bienfaiteur » à 15 €/mois), chacun avec son prix, sa périodicité (mensuelle ou annuelle) et ses avantages. Vous publiez les paliers quand ils sont prêts, et pouvez en archiver un sans toucher aux adhérents déjà abonnés. Les avantages se cochent sur le palier et sont APPLIQUÉS AUTOMATIQUEMENT par le site : accès aux ventes privées et précommandes exclusives (les produits réservés « Adhésion active » deviennent visibles et achetables), articles et contenus exclusifs du blog, et réduction permanente sur la boutique propre au palier (elle prime sur le tarif adhérent global). Vous pouvez toujours ajouter des avantages en texte libre (remerciement, invitation…) — eux relèvent de votre organisation. Les paliers créés avant cette évolution gardent l’accès complet tant que vous ne les modifiez pas. Rôles Discord : avec l’intégration « Rôles Discord » (carte en bas de l’onglet Adhésions), un palier peut donner un rôle de votre serveur Discord — sans bot à inviter. Vous créez votre propre application sur le portail développeur Discord (5 minutes, guidé pas à pas), vos adhérents lient leur compte Discord depuis leur espace membre (/compte), et Discord attribue puis retire le rôle tout seul selon l’adhésion (exigence « Adhérent actif = vrai » ou « Palier ≥ N » sur le rôle, N = le champ Ordre du palier). ## Le bloc sur votre site Ajoutez le bloc « Adhésion » à une page : il affiche vos paliers sous forme de cartes avec un formulaire d’inscription. Le visiteur choisit un palier, paie, et devient adhérent. S’il est déjà abonné, le bloc affiche « Votre adhésion » au lieu de lui reproposer de payer. ## Réserver du contenu aux adhérents Vous pouvez réserver des contenus à vos adhérents : le bloc « Contenu réservé » vérifie, côté serveur, qu’une adhésion est active avant d’afficher quoi que ce soit (le contenu réservé n’est jamais envoyé à un non-adhérent). Des articles de blog et des produits de la boutique peuvent aussi être réservés aux adhérents. ## Gérer les adhérents L’onglet « Adhésions » liste vos adhérents et estime votre revenu récurrent (MRR). De son côté, chaque adhérent retrouve « Mon adhésion » dans son espace : il peut résilier (l’adhésion s’arrête à la fin de la période déjà payée, sans remboursement au prorata) ou la réactiver. Les renouvellements et les échecs de paiement sont reflétés automatiquement. --- ## Congés & absences : poser, valider, suivre les soldes Le module RH gère les congés de bout en bout : le salarié pose sa demande, elle part en validation, le manager approuve, et le solde se met à jour tout seul. Le nombre de jours est TOUJOURS calculé par Capibara à partir des dates (le salarié ne le saisit pas) : selon le mode de décompte du type de congé, en excluant les week-ends et les jours fériés français, et en tenant compte des demi-journées. ## Côté salarié — « Mes congés » Chaque personne rattachée à une fiche salarié dispose de la page « Mes congés » (sans avoir besoin des droits RH). Elle y voit ses soldes en temps réel (acquis / pris / restant par type), pose une demande en choisissant le type, les dates et éventuellement une demi-journée de début ou de fin, et suit l’état de ses demandes. Une demande encore en attente — ou approuvée mais pas encore commencée — peut être annulée d’un clic (le solde est restitué). Un encart « Mon équipe » montre qui est absent ce mois-ci (sans le motif). ## Côté RH — types & décompte Dans RH › Soldes & absences, vous définissez les types d’absence et, pour chacun, le mode de décompte et le droit annuel : - Jours ouvrés (lun.–ven.) : le plus courant pour les RTT et la plupart des absences. - Jours ouvrables (lun.–sam.) : le décompte légal des congés payés (30 ouvrables = 5 semaines). - Jours calendaires : tous les jours comptent. - Droit annuel : renseignez-le pour l’acquisition automatique (laisser vide = saisie manuelle, par ex. maladie / sans solde). ## Acquisition automatique Les soldes « acquis » se calculent automatiquement : droit annuel × mois travaillés dans l’année ÷ 12. Le calcul est rejoué le 1er de chaque mois pour tous les salariés actifs (vous pouvez aussi le relancer à la main via « Recalculer les acquisitions »). C’est idempotent : relancer ne gonfle jamais les compteurs. ## Validation & calendrier Chaque demande crée une validation qui apparaît en direct dans la cloche « Validations » de l’en-tête (et dans l’onglet Validations de RH). À l’approbation, le solde « pris » est mis à jour ; au refus, rien n’est décompté. L’onglet « Calendrier » de RH montre, mois par mois, qui est absent dans toute l’organisation — pratique pour arbitrer les chevauchements avant d’approuver. --- ## Dossier salarié : contrats, avenants & coffre-fort de documents La fiche d’un salarié (RH › Salariés) regroupe son identité, ses contrats et un coffre-fort de documents. Toutes ces informations sont sensibles : elles ne sont visibles que des personnes ayant le droit RH, et de chaque salarié pour ce qui le concerne. ## Contrats & avenants Ajoutez le contrat de travail (type, dates, poste, rémunération brute de référence, durée hebdomadaire). Un contrat se modifie (correction) et se prolonge par un AVENANT : l’avenant reprend les conditions et fixe leur nouvelle date d’effet, sans effacer le contrat d’origine. La fiche affiche l’historique complet, avec un badge « Avenant » sur chaque modification. ## Générer un modèle de contrat (PDF) Depuis un contrat, le bouton PDF produit un modèle de contrat pré-rempli avec les données du salarié, du poste et de votre organisation, couvrant les mentions obligatoires (parties, poste, date d’effet, lieu, durée du travail, rémunération, congés, période d’essai, convention collective, préavis). Les points à arbitrer sont signalés « à compléter ». C’est une aide à la rédaction : faites-le relire avant signature — Capibara ne fournit pas de conseil juridique. ## Faire signer un contrat (signature électronique) Chaque contrat — et chaque avenant — se fait signer en ligne, sans rien imprimer. Sur la ligne du contrat (fiche du salarié, section Contrats), « Envoyer à signer par e-mail » transmet un lien de signature personnel au salarié (sa fiche doit porter une adresse e-mail). Le salarié ouvre le lien, voit le PDF du contrat et le contenu certifié, et signe en un clic. Le lien n'est jamais affiché dans votre écran : il part par e-mail, personne ne peut signer à la place du salarié. Le suivi se lit au même endroit : « lien envoyé à … » tant qu’il n’est pas signé, puis « Signé par X le… » avec l’empreinte de preuve. La preuve conservée scelle le contenu signé, le signataire et l’horodatage (empreinte SHA-256), avec l’adresse IP et le navigateur du signataire. Le lien expire automatiquement au bout de 30 jours — un renvoi en crée un nouveau. Le PDF signé porte un « Identifiant de preuve » : toute personne qui détient le document peut en vérifier l’authenticité sur capibara.fr/verifier-signature (certificat en ligne + attestation PDF). Un contrat signé est VERROUILLÉ : il ne se modifie plus — toute évolution passe par un avenant, qui se signe de la même façon. Le PDF du contrat regénéré après signature porte le bloc de signature électronique. ## Coffre-fort de documents Déposez dans le coffre-fort de chaque salarié ses documents RH, classés par catégorie (contrat, avenant, bulletin de paie, attestation, pièce d’identité, RIB…). Les fichiers sont stockés de façon privée (jamais dans la médiathèque publique) et ne sont téléchargeables que par les RH et le salarié concerné. Une date d’expiration est proposée selon des durées de conservation usuelles, pour vous aider à respecter les règles de conservation. ## Côté salarié Le salarié retrouve ses propres documents dans « Mes congés » (section « Mes documents ») et peut les télécharger à tout moment — sans avoir accès aux dossiers des autres. --- ## Parcours d’arrivée et de départ (onboarding / offboarding) Un parcours est une checklist reproductible qui se déclenche à l’arrivée (onboarding) ou au départ (offboarding) d’un salarié. Chaque tâche porte une échéance calculée automatiquement par rapport à la date d’entrée ou de sortie, peut être assignée à un collègue, et fait l’objet d’un rappel quand elle approche. ## Démarrer un parcours Depuis la fiche d’un salarié, section « Parcours », choisissez « Arrivée » ou « Départ », la date de référence, et éventuellement un modèle. Capibara crée la checklist avec les tâches datées. Sans configuration préalable, un jeu de tâches par défaut est proposé (préparer le contrat, DPAE, créer les accès, remettre le livret d’accueil, visite médicale, entretien de fin de période d’essai… ou côté départ : entretien, récupération du matériel, désactivation des accès, solde de tout compte, certificat de travail…). ## Suivre et assigner Cochez les tâches au fur et à mesure : une barre de progression indique où en est le parcours. Assignez une tâche à la personne responsable (elle est notifiée) et ajoutez ou retirez des tâches librement. Un rappel automatique est envoyé à l’assigné quand l’échéance d’une tâche approche. ## Créer vos modèles Dans RH › Parcours, créez vos propres modèles (ou partez des modèles par défaut) : définissez les tâches et leur décalage en jours (négatif = avant la date, 0 = le jour même). Vos modèles sont ensuite proposés au démarrage d’un parcours — vos process d’accueil et de départ deviennent reproductibles. --- ## Temps de travail & notes de frais Deux outils complètent le dossier du salarié : la feuille de temps (temps de travail déclaré) et les notes de frais (dépenses à se faire rembourser). Les deux sont accessibles au salarié depuis « Mes congés » ; les RH les retrouvent dans le module RH. ## Temps & activités Le salarié déclare son temps selon son régime : en heures, ou en forfait-jours (journée, demi, quart). Un récapitulatif du mois s’affiche (total en heures et en jours). Côté RH, chaque fiche salarié a une section « Temps », et le temps déclaré est repris dans le récap paie exporté pour l’expert-comptable (colonnes « Heures déclarées » et « Jours déclarés »). ## Notes de frais Le salarié crée une note, y ajoute ses dépenses (repas, transport, hébergement…), joint un justificatif (stocké de façon privée), puis la soumet. Les frais kilométriques se calculent automatiquement à partir des km et de la puissance du véhicule (barème indicatif, ajustable). La note part alors en validation (cloche « Validations » de l’en-tête). Pour aller plus vite, le bouton « Scanner » analyse la photo d’un reçu (montant, date, commerçant, catégorie) et pré-remplit la dépense — que vous vérifiez toujours avant de l’ajouter. Cette assistance requiert l’IA (offres Pro/Business). ## Validation, remboursement & comptabilité Un responsable approuve ou refuse la note. Une fois approuvée, les RH la marquent « remboursée » quand le virement est fait. Si le module Comptabilité est actif, un bouton « Comptabiliser » génère l’écriture comptable correspondante (charge de déplacement au débit, dette envers le salarié au crédit) — une action volontaire, jamais automatique, pour garder la maîtrise du grand livre. --- ## Entretiens obligatoires : professionnel, état des lieux… La loi impose des entretiens périodiques : l’entretien professionnel tous les 2 ans (consacré aux perspectives d’évolution, jamais à l’évaluation), et un état des lieux récapitulatif du parcours tous les 6 ans. Capibara calcule ces échéances automatiquement et vous alerte des retards. ## L’échéancier L’onglet « Entretiens » de RH liste les entretiens en retard ou imminents pour toute l’organisation, triés par urgence. Sur chaque fiche salarié, un rappel indique la prochaine date due (entretien professionnel, état des lieux) selon la date d’embauche et le dernier entretien tenu. Chaque mois, les managers reçoivent un récapitulatif des retards de leur équipe. ## Mener et archiver Depuis la fiche du salarié, planifiez un entretien, saisissez son compte rendu une fois tenu (points abordés, souhaits d’évolution, besoins de formation), puis marquez-le signé. Vous pouvez aussi enregistrer les entretiens forfait-jours (charge de travail) et les entretiens annuels d’évaluation. Le compte rendu reste consultable dans l’historique du salarié. --- ## Conformité RH : registre du personnel, visites médicales, échéancier L’onglet « Conformité » de RH regroupe vos obligations d’employeur et vous évite les oublis coûteux. ## Registre unique du personnel Obligatoire dès le premier salarié, le registre est généré automatiquement depuis les fiches (nom, sexe, nationalité, date de naissance, emploi, qualification, dates d’entrée et de sortie, type de contrat) et exportable en PDF. Renseignez le sexe et la date de sortie sur chaque fiche pour compléter les colonnes obligatoires. ## Visites médicales Sur chaque fiche salarié, enregistrez les visites médicales (embauche, périodique, reprise, suivi renforcé), l’avis d’aptitude et la date de la prochaine visite. Cette prochaine échéance remonte automatiquement dans l’échéancier légal. ## Échéancier légal central En tête de l’onglet, l’échéancier réunit tout ce qui arrive à échéance ou est en retard : entretiens obligatoires, visites médicales, fins de CDD. Trié par urgence, il vous donne une vue unique de ce qu’il reste à faire. --- ## Paie : export des éléments variables (EVP) Capibara ne remplace pas votre logiciel de paie et ne produit jamais la DSN : ce sont des tâches réglementées confiées à un prestataire spécialisé (PayFit, Silae, votre expert-comptable…). En revanche, Capibara réunit et prépare les « éléments variables de paie » (EVP) du mois pour vous éviter la double saisie. ## Export EVP (le fichier à transmettre) Choisissez le mois, puis « Export EVP (CSV) ». Le fichier liste, par salarié : le brut de référence, les absences ventilées (congés payés, congés sans solde, maladie), le temps déclaré (heures ou jours de forfait) et les frais remboursés dans le mois. Les congés sans solde sont séparés car ils entraînent une retenue sur salaire, contrairement aux congés payés. ## Frais remboursés La colonne « Frais » reprend les notes de frais marquées comme remboursées durant le mois. Ces remboursements ne sont pas soumis à cotisations : votre prestataire les traite comme des lignes distinctes du salaire. ## Récap administratif & synchronisation Le « Récap admin » est une vue plus simple pour votre expert-comptable (dont le temps projet). Le bouton « Synchroniser au prestataire » pousse la liste des salariés vers le prestataire connecté ; en l’absence de connecteur, il fonctionne en mode démonstration. --- ## RH & Employés : le guide complet RH & Employés est votre SIRH intégré : le dossier de chaque salarié, ses contrats, ses congés, son temps, ses notes de frais, ses entretiens obligatoires et votre conformité — au même endroit que le reste de votre organisation. Conçu pour les TPE/PME : zéro paramétrage pour démarrer, conformité française native. Capibara PRÉPARE la paie (variables) mais ne la calcule jamais : le calcul et la DSN restent chez votre prestataire ou votre expert-comptable. ## Trois vues, trois métiers - Vue RH (gestionnaire) — la page « RH & Employés » : gère les salariés, l’organisation, les congés, la conformité, la paie… (réservée aux personnes ayant le droit RH). - Vue manager — le manager retrouve son équipe dans l’organigramme et reçoit les échéances (entretiens, fins de contrat). - Vue salarié (self-service) — chaque salarié a son « Espace salarié » dans Mon compte : soldes de congés, demandes, temps, notes de frais, documents. Il n’a besoin d’aucun droit RH. ## Le parcours d’un salarié - Arrivée : dès qu’une personne rejoint l’organisation (owner, invitation, SSO), une fiche salarié est créée automatiquement (statut actif, badge « à compléter »). - Dossier : complétez la fiche (identité, contrat, coffre-fort de documents), lancez le parcours d’onboarding par checklist. - Au quotidien : congés (avec validation), temps, notes de frais (avec scan du reçu), entretiens obligatoires. - Conformité : registre unique du personnel, visites médicales, DUERP, échéancier légal centralisé. - Départ : parcours d’offboarding, date de sortie, documents de fin de contrat. ## Organisation & équipes L’onglet « Organisation » dessine l’organigramme (par lien hiérarchique ou par département), avec avatars et postes ; un clic ouvre la fiche. Les départements se détaillent (personnes, effectif, salaire moyen si vous avez le droit paie) et regroupent des Équipes — les mêmes équipes natives que dans Mon organisation, simplement rattachées à un département. ## Signatures Les comptes rendus d’entretien et les contrats de travail se signent électroniquement : le lien de signature part par e-mail au salarié en un clic (il n’est jamais copiable — personne ne peut signer à sa place), et le salarié signe sur une page dédiée où il voit le document. La preuve (horodatage, adresse IP, empreinte du document) est conservée, et le document reste consultable ensuite. ## Droits d’accès - Le droit « RH & Employés » ouvre le module (dossiers, congés, organisation, entretiens, conformité…). - La « Paie » est un droit séparé (sensible) : sans lui, on gère tout le reste mais on ne voit ni l’onglet Paie, ni la masse salariale, ni les salaires agrégés. - L’« Espace salarié » (self-service) ne demande aucun droit — il apparaît dans Mon compte dès qu’une fiche est reliée. ## Pour aller plus loin Chaque brique a son guide détaillé : Congés & absences, Dossier salarié & documents, Parcours d’onboarding/offboarding, Temps & notes de frais, Entretiens obligatoires, Conformité & registres, DUERP, Paie & export EVP, Tableau de bord RH. --- ## Tableau de bord RH : effectifs, turnover, masse salariale Le tableau de bord réunit les grands indicateurs de votre organisation, calculés à la volée depuis les fiches salariés. Plus vos fiches sont complètes (dates d’entrée et de sortie, type de contrat, brut de référence, date de naissance, sexe, service), plus les chiffres sont justes. ## Indicateurs clés En haut : l’effectif actuel, la masse salariale mensuelle (somme des bruts de référence), l’ancienneté et l’âge moyens, puis les entrées, sorties et le taux de turnover sur les 12 derniers mois. Le turnover rapporte le nombre de départs à l’effectif moyen de la période. ## Évolution et répartitions La courbe d’effectif retrace les 12 derniers mois. Les histogrammes ventilent votre effectif par type de contrat, par service, par tranche d’âge, par ancienneté et par répartition femmes / hommes. Ces vues aident à préparer un bilan social ou un point de pilotage. ## Confidentialité Tous les calculs restent internes à Capibara : aucune donnée salariée n’est envoyée à un service tiers ni à une IA. Le tableau de bord se limite à des agrégats de votre propre organisation. --- ## DUERP : document unique d’évaluation des risques Le DUERP est obligatoire dès l’embauche du premier salarié. Il recense, pour chaque « unité de travail » (bureau, atelier, accueil…), les risques professionnels, les évalue et liste les mesures de prévention. Capibara vous outille pour le rédiger et le conserver — il ne se substitue pas à votre évaluation (à faire relire ; ce n’est pas un conseil juridique). ## Partir d’une grille sectorielle Pour ne pas démarrer d’une page blanche, choisissez une grille pré-remplie proche de votre activité (bureau, commerce, restauration, soins, artisanat/BTP). Elle ajoute des unités de travail avec des risques types déjà cotés, que vous adaptez ensuite à votre réalité. ## Coter un risque Chaque risque est coté par une gravité (1 à 4) et une fréquence (1 à 4). Capibara en déduit un niveau — faible, moyen, élevé, critique — pour prioriser vos actions. Renseignez les mesures déjà en place et les actions à mener (que vous pouvez marquer « réalisées »). ## Publier une version (conservation 40 ans) Quand votre évaluation est à jour, « Publier une version » fige un instantané immuable, exportable en PDF. La loi impose de conserver les versions successives au moins 40 ans, sans écraser les précédentes : Capibara les archive toutes. Vous continuez ensuite à éditer ; la prochaine publication crée une nouvelle version. ## Mise à jour Le DUERP doit être révisé au moins une fois par an (obligatoire à partir de 11 salariés, recommandé en-deçà) et à chaque changement important (nouveau poste, accident, nouvel équipement). L’échéancier légal de l’onglet Conformité vous rappelle quand une révision est due. --- ## Adresses e-mail externes (IMAP/SMTP) En plus des boîtes e-mail hébergées par Capibara, vous pouvez relier vos adresses EXTERNES — celles que vous avez déjà chez un autre fournisseur — et les consulter depuis Capibara via les protocoles standards IMAP (réception) et SMTP (envoi). Vous trouvez cette fonction dans le menu « Boîtes externes ». ## Ajouter une adresse Ouvrez « Boîtes externes » puis « Ajouter une adresse ». Choisissez votre fournisseur dans la liste (OVH, Gandi, Gmail, Outlook…) pour pré-remplir automatiquement les serveurs et les ports, ou saisissez-les à la main. Renseignez votre adresse, votre identifiant (souvent l’adresse elle-même) et votre mot de passe. La connexion est testée immédiatement : si les paramètres sont bons, l’adresse apparaît « Connectée ». - Serveur IMAP (réception) : par ex. ssl0.ovh.net, port 993 (SSL) ou 143. - Serveur SMTP (envoi) : par ex. ssl0.ovh.net, port 465 (SSL) ou 587. - Ces informations sont fournies par votre fournisseur (rubrique « configurer un logiciel de messagerie »). ## Gmail, Outlook et double authentification Si votre compte est protégé par une double authentification (Gmail, Outlook/Microsoft 365…), vous ne pouvez pas utiliser votre mot de passe habituel : générez un « mot de passe d’application » dans les réglages de sécurité de votre compte, et collez-le ici. La connexion directe par mot de passe Google/Microsoft (OAuth) arrivera dans une prochaine version. ## Lire et répondre Cliquez sur « Ouvrir » pour accéder à la boîte : choisissez un dossier, parcourez la liste (les non-lus sont en gras), ouvrez un message pour le lire, puis « Répondre » ou « Écrire » pour envoyer — le message part depuis VOTRE adresse externe. Les pièces jointes sont listées (leur téléchargement arrive bientôt). ## Sécurité et limites - Vos identifiants sont chiffrés au repos et ne sont jamais affichés ni partagés. - L’envoi se fait uniquement depuis votre propre adresse (jamais d’usurpation). - Chaque adresse est personnelle : vous ne voyez que les vôtres. Jusqu’à 5 adresses externes. - Version actuelle : affichage du message en texte (mise en forme riche et téléchargement des pièces jointes à venir). --- ## Encaissements en ligne : mise en place et gestion des risques Les encaissements en ligne permettent à vos clients de payer vos factures, réservations et ventes par carte. L'argent arrive directement sur VOTRE compte Stripe : vous êtes le marchand (vos reçus, vos remboursements, vos litiges). Capibara fournit la plateforme et prélève une commission de service. ## Mise en place - Paramètres › Facturation › Encaissements en ligne. - Déclarez votre activité et confirmez qu'elle est autorisée (examen de conformité obligatoire avant le branchement). - Reliez votre compte Stripe : la vérification d'identité (KYC) est hébergée par Stripe. - Une fois « Encaissements actifs », le bouton « Payer en ligne » apparaît sur vos documents. ## Commission La commission Capibara est de 10 % sur le plan Gratuit et de 0 % sur les plans Pro et Business. Les frais de traitement de Stripe restent à votre charge, comme pour tout marchand. Passer à un plan payant supprime la commission. ## Activités interdites Vous ne pouvez encaisser que pour une activité licite et autorisée. Les activités interdites ou réglementées (liste Stripe) ne sont pas acceptées. En cas de doute, consultez la page « Activités interdites et réglementées ». ## Fraude, litiges et supervision Chaque paiement est analysé automatiquement par Stripe (Radar) pour détecter la fraude. Si un litige (contestation de paiement) ou une alerte de fraude survient sur votre compte, vous êtes notifié et devez traiter la situation depuis votre tableau de bord Stripe. Capibara conserve un rôle de supervision : en cas de signalements concordants (par exemple des clients prouvant un produit payé mais non livré), la plateforme peut ouvrir une enquête, suspendre votre capacité d'encaissement et vous demander de rembourser les clients lésés. Restez irréprochable : livrez ce que vous vendez et répondez vite aux demandes. ## Un client vous a signalé : ce qui se passe N'importe quel visiteur peut signaler un vendeur depuis une page publique. Un signalement n'est PAS une sanction : à lui seul, il ne déclenche rien, ne bloque rien et ne vous est même pas notifié. Notre équipe l'examine d'abord. - Classé sans suite : le signalement est écarté, vous n'avez rien à faire. Vous êtes informé que le dossier a été examiné et clos. - Retenu : le signalement apparaît alors dans Paramètres › Facturation › Encaissements en ligne, section « Signalements clients », avec le motif, ce que le client a écrit et la note de notre équipe. - Retenu avec demande de remboursement : remboursez le client (bouton « Rembourser un client » de la même page), puis cliquez sur « Marquer comme remboursé ». - Suspension : réservée aux cas graves ou répétés restés sans réponse. Votre organisation est alors suspendue (site public compris) et un formulaire de recours s'affiche sur votre site pour demander un réexamen. ## Le signalement est injustifié : que faire ? Cela arrive : un client mécontent, un malentendu sur un délai, ou quelqu'un qui se trompe de vendeur. Ne restez pas silencieux — l'absence de réponse est ce qui fait basculer un dossier, bien plus que le signalement lui-même. - Ouvrez un ticket de support en citant le motif affiché dans « Signalements clients ». C'est le canal pour contester : nous réexaminons le dossier. - Joignez vos preuves : bon de livraison ou numéro de suivi, échanges avec le client, conditions de vente acceptées, preuve d'un remboursement déjà effectué. - Si un remboursement est demandé et que vous le jugez infondé, dites-le dans le ticket AVANT l'échéance plutôt que d'ignorer la demande. - En cas de suspension, utilisez le formulaire de recours affiché sur votre site : il ouvre un réexamen formel, tranché puis notifié par e-mail. Un conseil qui évite la plupart des litiges : gardez la trace de vos livraisons et répondez à vos clients sous 48 h. Un client qui obtient une réponse signale rarement. --- ## Abonnement Capibara : passer à Pro ou Business, forfaits et prix Cet article traite de VOTRE abonnement à Capibara : l’offre de votre organisation — les mots « forfait » et « plan » désignent la même chose — parmi Free, Pro et Business, son prix, son paiement et vos factures. Il ne traite pas des factures que vous envoyez à vos propres clients (voir « Devis & Factures »), ni des adhésions que vos membres vous paient (voir « Adhésions »). ## Où changer d’offre : le chemin exact Dans la barre latérale, ouvrez « Mon organisation », puis l’onglet « Abonnement ». La page « Abonnement » s’ouvre : elle affiche votre plan actuel, une bascule « Par an » / « Par mois », puis les trois cartes Free, Pro et Business. Réglez la périodicité, puis cliquez sur « Choisir » sur la carte de l’offre voulue. L’adresse directe de cette page est /parametres/abonnement : vous pouvez la mettre en favori. Ce n’est pas dans « Paramètres ». Il n’existe aucune section « Abonnement » dans les Paramètres : leur rubrique « Facturation » ne contient que la Numérotation et les Encaissements en ligne, qui servent à facturer VOS clients. Chercher son abonnement à cet endroit est la confusion la plus fréquente. D’autres chemins mènent à la même page : le bouton « Passer à Pro » (ou « Passer à Business ») affiché sur une application verrouillée dans « Modules », et le bandeau « Voir les plans » qui apparaît quand votre équipe approche de sa limite d’utilisateurs. ## Les trois offres : Free, Pro et Business - Free : les applications de base — CRM, Facture & Devis (le menu « Facturation »), Boutique, Stock de base, Blog, Projets, Planning, Newsletter, Support — et le socle toujours actif : site web, médiathèque, stockage de fichiers et wiki, noms de domaine, messagerie, chat et visioconférence, validations, achats. Votre site sur l’adresse capibara.fr offerte, jusqu’à 3 utilisateurs, et aucune boîte e-mail hébergée. Pour démarrer sans payer. - Pro : débloque la Comptabilité, le builder avancé avec l’IA, votre domaine personnalisé sans watermark, jusqu’à 5 boîtes e-mail hébergées et jusqu’à 25 utilisateurs. - Business : tout Pro, plus la RH & Employés et le Stock avancé (multi-entrepôts, inventaire physique, écran « À racheter »), la connexion bancaire avec rapprochement automatique (3 comptes inclus), le portail SSO à votre marque, jusqu’à 100 boîtes e-mail, le support en direct et jusqu’à 500 utilisateurs. - Une précision qui évite l’erreur la plus courante : Facture & Devis, le stockage de fichiers et le wiki (Documents) et le Stock de base ne sont réservés à aucune formule payante. Ils sont à 0 € et s’activent dès la formule gratuite. Seules la Comptabilité (Pro) et la RH & Employés (Business) demandent réellement une formule ; côté Stock, seuls le multi-entrepôts, l’inventaire physique et l’écran « À racheter » sont Business. - Le détail « qui inclut quoi » est dans le tableau « Comparer les formules », en bas de la page Abonnement. ## Passer à Pro ou Business (souscrire, mettre à niveau) Sur la page « Abonnement », réglez d’abord la bascule « Par an » / « Par mois » : le prix affiché sur les cartes en dépend. Cliquez ensuite sur « Choisir » sous l’offre voulue. Vous êtes conduit vers le paiement sécurisé Stripe, par carte bancaire, puis ramené sur Capibara. Les formules payantes s’ouvrent sur un essai gratuit de 14 jours. Votre carte est demandée à la souscription — c’est Stripe qui l’enregistre, jamais Capibara — mais rien n’est prélevé pendant l’essai : le premier prélèvement a lieu à la fin des quatorze jours, et c’est cette date qui s’affiche comme prochaine échéance sur la carte « Plan actuel ». Le forfait est complet dès la validation, et une résiliation avant la fin de l’essai ne débite rien. Le nouveau forfait est actif dès le retour : la carte de votre offre porte alors la mention « Plan actuel », et son bouton n’est plus cliquable. En revanche, les applications que le forfait débloque ne s’allument pas toutes seules : changer de formule lève le verrou, cela n’active rien. Ouvrez « Modules », repérez l’application — sa pastille « Pro » ou « Business » a disparu — et cliquez sur « Activer ». C’est immédiat et sans paiement supplémentaire : ces applications sont à 0 €, comprises dans votre forfait, et leur entrée de menu apparaît dans la foulée. Les montants ne sont pas repris dans cette page d’aide : le prix qui fait foi est celui affiché sur les cartes, pour votre équipe, au moment où vous choisissez. ## Facturation par utilisateur (les sièges) Les offres Pro et Business sont facturées par utilisateur actif — un « siège » par membre actif de votre organisation. Inviter ou retirer quelqu’un met la quantité facturée à jour automatiquement, au prorata de la période en cours. Chaque offre plafonne le nombre d’utilisateurs : 3 en Free, 25 en Pro, 500 en Business. Au-delà, il faut passer à l’offre supérieure — un bandeau vous prévient avant d’atteindre la limite. Le grand chiffre de chaque carte est le prix par utilisateur et par mois. Juste en dessous, dès que votre équipe compte plus d’une personne, s’affiche le total exact prélevé pour la période choisie : le prix affiché est le prix facturé. ## Mensuel ou annuel La bascule « Par an » / « Par mois » choisit la périodicité. L’engagement annuel donne un tarif réduit par rapport au mensuel et se prélève en une seule échéance par an ; le mensuel se prélève chaque mois. Les deux prix sont visibles avant toute validation, et il n’y a pas d’engagement de durée. ## Paiement sécurisé par Stripe Les paiements sont traités par Stripe. Vos coordonnées de carte ne sont jamais stockées par Capibara. Passé l’essai gratuit de 14 jours, l’abonnement est prélevé d’avance pour la période à venir, puis reconduit automatiquement à chaque échéance ; la date du prochain prélèvement — la fin de l’essai, pour le tout premier — est indiquée sur la carte « Plan actuel ». ## Vos factures et votre moyen de paiement Une facture est émise à chaque échéance, avec les mentions légales et la TVA conformes au statut juridique de votre organisation. Vous la retrouvez à deux endroits. - Sur la page « Abonnement » elle-même : le bloc « Mes factures », en bas, liste vos factures (numéro, date, montant, statut) et les télécharge en PDF. - Dans « Mon compte » : ouvrez le menu de votre avatar, en haut à droite, choisissez « Mon compte », puis l’onglet « Abonnement ». Vous y trouvez vos modules actifs, vos factures émises et votre moyen de paiement, avec le bouton « Ouvrir le portail Stripe » pour changer de carte ou télécharger vos reçus. - Attention : cet onglet « Abonnement » de Mon compte sert à CONSULTER. Il ne contient aucun bouton pour choisir une offre — le changement de forfait se fait uniquement sur la page « Abonnement » ouverte depuis Mon organisation. ## Changer d’offre, résilier, période de grâce - Monter d’offre (Free vers Pro, Pro vers Business) est immédiat : les modules concernés se débloquent aussitôt — il reste à les activer dans « Modules », en un clic et sans paiement supplémentaire. - Redescendre : Capibara affiche d’abord « Confirmer le changement de plan » et liste ce qui dépasserait les limites de la nouvelle offre. Pendant 14 jours après le changement, les contenus concernés restent lisibles mais figés. - Résilier : le bouton « Annuler à la fin de la période », sur la carte de votre plan. Aucun nouveau prélèvement ensuite, et vous gardez l’accès jusqu’à la fin de la période déjà payée. Tant que cette date n’est pas atteinte, le bouton « Reprendre l’abonnement » annule la résiliation. - Échec de paiement : une période de grâce vous laisse régulariser. Un bandeau l’annonce, avec sa date de fin et un bouton « Réactiver mon abonnement ». - Gérer l’abonnement chez Stripe : le bouton « Gérer mon abonnement » ouvre le portail Stripe (carte, reçus, historique). ## Qui a le droit de changer l’offre Le changement d’offre, la résiliation et les paiements demandent le droit « Facturation & paiements ». Sans ce droit, la page « Abonnement » reste consultable, mais un message l’annonce et les boutons sont grisés : ce n’est pas une panne. Demandez à un administrateur de votre organisation, ou faites-vous attribuer ce droit dans « Mon organisation › Rôles et droits ». L’entrée « Mon organisation » de la barre latérale n’apparaît qu’aux personnes autorisées à voir les utilisateurs. Si vous ne la voyez pas, ouvrez directement /parametres/abonnement : la page s’affiche, en lecture seule si vous n’avez pas le droit « Facturation & paiements ». --- ## Connexion bancaire : synchroniser sa banque et rapprocher ses factures La connexion bancaire, réservée à la formule Business, relie un ou plusieurs comptes bancaires à votre comptabilité par un prestataire agréé (un « agrégateur » autorisé au titre de la directive européenne sur les services de paiement). L’accès est en lecture seule : Capibara voit les soldes et les opérations, jamais vos identifiants de connexion à la banque — vous les saisissez chez le prestataire, sur sa page —, et ne peut initier aucun virement ni aucun paiement. Sans connexion, l’import de relevés (CSV, OFX, QIF) et le rapprochement avec vos factures restent disponibles : la connexion supprime simplement l’étape du fichier à télécharger. ## Relier une banque Comptabilité › Banque › « Relier une banque » : un écran récapitule d’abord ce que Capibara lira (comptes, soldes, opérations), ce qu’il ne fera jamais (aucun paiement, aucun identifiant conservé) et la durée du consentement (180 jours). Vous êtes ensuite envoyé sur la page du prestataire, où vous choisissez votre banque et vous identifiez comme sur son site, puis ramené dans Capibara. Capibara vous propose alors les comptes de PAIEMENT trouvés (comptes courants — un livret d’épargne n’est pas proposé, il ne sert pas au rapprochement). Pour chacun, cochez-le pour le suivre, et choisissez s’il devient un nouveau compte bancaire ou s’il rejoint un compte que vous aviez déjà créé à la main (vos anciens imports restent alors au même endroit). Trois comptes connectés sont inclus dans Business. Au-delà, un supplément mensuel par compte est annoncé sur l’écran avant que vous ne validiez — jamais une surprise sur la facture — et prélevé sur votre facture Capibara du mois suivant. ## Ce qui se passe ensuite Les 90 derniers jours d’opérations sont importés tout de suite, puis Capibara se synchronise chaque heure. Les opérations du jour, que la banque n’a pas encore définitivement comptabilisées, apparaissent « en attente » : leur libellé ou leur montant peut encore changer, elles ne sont jamais rapprochées automatiquement. Le solde de chaque compte connecté s’affiche dans l’onglet « Votre argent » et dans le widget d’accueil (« En banque »). Le solde initial de la vérification de compte est posé automatiquement au lendemain de la liaison, pour ne pas compter deux fois les opérations déjà passées. Si vous aviez importé un relevé à la main, les mêmes opérations ne sont pas doublées : la ligne importée est reconnue (même jour, même montant, même libellé) et simplement rattachée à la connexion. ## Le consentement dure 180 jours C’est la règle européenne : l’accès accordé au prestataire expire au bout de 180 jours. Capibara prévient les responsables 30 jours, 7 jours puis la veille de l’échéance (notification et e-mail — l’e-mail se coupe dans Paramètres › Notifications, catégorie « Connexion bancaire »). À l’échéance, la connexion passe « À renouveler » : la synchronisation s’arrête, rien n’est perdu. « Renouveler » relance le même parcours que la liaison ; la connexion redevient active avec une nouvelle échéance et vos comptes restent reliés. ## Rapprochement avec vos factures Chaque ligne bancaire non pointée est confrontée à vos factures émises non soldées (facture par facture, ou échéance par échéance pour un échéancier) et à vos factures fournisseurs non réglées. Quand une ligne ressemble à une facture — montant identique, numéro de facture dans le libellé, nom du client —, la carte « Rapprochement avec vos factures » de l’onglet Banque la propose avec ses raisons et un indice de confiance. « Confirmer » a exactement l’effet d’un règlement saisi à la main : la facture passe encaissée à la date de la ligne (compta, arrêt des relances, statut transmis au circuit de facturation électronique), ou la facture fournisseur passe réglée, et la ligne est pointée dès que son écriture existe. « Ignorer » écarte définitivement cette correspondance pour cette ligne. Au départ, tout est suggestion. Après cinq confirmations sans aucun refus, Capibara « gagne » l’automatique : les correspondances sûres (montant exact et numéro de facture dans le libellé, un seul candidat) sont enregistrées sans vous, et une notification aux responsables résume ce qui a été encaissé ; les autres restent des suggestions. Vous pouvez aussi choisir le mode à la main — automatique tout de suite, ou désactivé. Le rapprochement fonctionne aussi bien avec un relevé importé (CSV, OFX, QIF) qu’avec une connexion : il passe après chaque import, chaque synchronisation, et toutes les heures. ## Déconnecter « Déconnecter » révoque l’accès chez le prestataire et efface les clés d’accès. Les opérations déjà importées sont conservées : ce sont vos pièces comptables. Le compte reste dans votre liste, marqué « Déconnecté » : il ne reçoit plus rien, mais son historique et ses rapprochements restent consultables. La connexion, elle, passe dans « Anciennes connexions », sous la liste : elle ne synchronise plus rien et n’encombre plus le panneau. Un accès seulement « À renouveler » reste, lui, en pleine vue — c’est une connexion vivante, à réactiver en un clic. Si votre organisation est supprimée, ses connexions bancaires sont révoquées chez le prestataire avant que ses données ne disparaissent. ## Reconnecter la même banque, sans doublon Une connexion déconnectée ne se rouvre pas : reconnecter votre banque crée un NOUVEL accès chez le prestataire, et vos comptes y portent de nouveaux identifiants. Capibara ne peut donc pas savoir tout seul, avec certitude, qu’il s’agit des mêmes comptes qu’avant. Il le repère quand même, par l’IBAN : à l’écran « Comptes trouvés », un compte qui ressemble à un compte déjà suivi est signalé, et il n’est PAS coché. Le cocher quand même crée un second compte dans Capibara — c’est parfois voulu (deux comptes réellement distincts), mais si c’est le même compte réel, ses opérations seront importées deux fois, les alertes « sorties sans pièce » compteront chaque sortie deux fois, et ce compte de plus entrera dans le décompte des comptes connectés de votre formule, au-delà desquels chaque compte est facturé. Si l’ancienne connexion est encore active, le solde de « Votre argent » additionnera en plus les deux comptes. Un compte dont vous importiez les relevés à la main, lui, n’a aucun identifiant en commun avec ce que votre banque envoie : Capibara ne peut pas deviner que c’est le même compte, et il ne vous le signalera pas. À l’écran « Comptes trouvés », cochez le compte puis choisissez sa fiche existante dans le menu de sa ligne, au lieu de « Nouveau compte » : l’historique continue, sans doublon. Quand deux comptes portent le même IBAN, le panneau « Sources » vous le dit, et il dit ce que le doublon coûte VRAIMENT chez vous : deux connexions vivantes, et les opérations arrivent en double, le solde additionne les deux comptes et les deux comptes entrent dans votre formule ; une connexion déconnectée, et le compte en trop ne synchronise plus rien et n’est plus facturé — seules ses opérations déjà importées restent en double. Capibara ne les fusionne pas tout seul : supprimer un compte effacerait ses opérations et tout l’historique de rapprochement qui justifie vos écritures comptables. Écrivez au support, la fusion se fait au cas par cas. Dernière protection : si vous enregistrez une sortie ou une entrée d’argent en dépense ou en recette alors que la même opération est déjà enregistrée sur le compte jumeau, Capibara le dit et demande confirmation avant d’écrire — sans quoi la charge, la recette et la TVA compteraient double. ## Ce que Capibara ne fait pas (volontairement) - Initier un virement, un prélèvement ou un paiement : l’accès est strictement en lecture seule. - Conserver vos identifiants bancaires : ils sont saisis chez le prestataire agréé, jamais dans Capibara. - Annuler seul un règlement enregistré par erreur : comme pour tout règlement, la correction passe par un avoir — c’est pourquoi l’automatique ne s’active qu’une fois que vos confirmations ont montré que les correspondances sont justes chez vous. - Remonter au-delà de 90 jours d’historique à la liaison (importez un relevé pour l’antérieur). --- ## Votre comptabilité : recettes, dépenses, TVA L’application Comptabilité est pensée pour les indépendants et TPE qui font d’habitude leur comptabilité sur un tableur : tout ce qui est encaissé dans Capibara (factures, boutique, TPE, billets, dons, adhésions…) y entre automatiquement, et vous n’y ajoutez que ce qui se passe ailleurs — vos dépenses et votre banque. L’écran s’organise en cinq onglets : Votre argent, Dépenses, Banque, TVA & clôture, et Pour votre comptable. Les quatre premiers parlent votre langue ; le dernier porte la comptabilité en partie double (journaux, écritures, balance) que votre cabinet attend. ## Votre argent : la vue d’ensemble Le premier onglet montre l’essentiel : encaissé et dépensé du mois, solde, TVA de l’année, courbe sur 12 mois avec la répartition par source (boutique, TPE, billets…), factures émises pas encore payées (avec les retards), et le récurrent estimé de vos adhésions. La liste des transactions est écrite en clair : « Encaissement TPE +15 € », « Loyer −850 € ». La carte montre les 9 dernières ; « Voir toutes les transactions » ouvre la page dédiée, avec un filtre par mois et un chargement progressif (jamais des milliers de lignes d’un coup). Une transaction liée à une pièce (facture, bon de commande) s’ouvre d’un clic. Derrière chaque ligne, Capibara tient les écritures comptables en partie double (c’est ce qui rend votre export FEC valable) — mais elles restent dans l’onglet « Pour votre comptable », jamais en premier écran. Le bouton « Recette » enregistre une entrée d’argent encaissée en dehors de Capibara (virement reçu, espèces, chèque…) : libellé, montant, date, moyen d’encaissement, TVA incluse — elle entre dans votre chiffre d’affaires comme n’importe quel encaissement. C’est le symétrique de « Nouvelle dépense » pour l’argent qui entre. ## Dépenses : la fin du tableur Une dépense se saisit en quelques secondes : fournisseur, date, montant TTC, TVA (boutons 20 / 10 / 5,5 / 0 %), et une catégorie en langage humain — Déplacements, Loyer, Assurances, Cotisations URSSAF… Le compte comptable se déduit tout seul, avec les subtilités justes (la TVA d’une assurance n’est jamais récupérable, un matériel de 500 € HT ou plus part en immobilisation). « Scanner une facture » accepte une photo ou un PDF : l’intelligence artificielle pré-remplit le formulaire, vous relisez avant d’enregistrer, et le document scanné devient le justificatif joint. La catégorie est aussi suggérée sans IA : Capibara mémorise vos fournisseurs (SNCF catégorisé une fois = proposé pour toujours). « Scanner en lot » traite plusieurs justificatifs d’un coup (jusqu’à 10 photos ou PDF) : chaque fichier passe au scanner l’un après l’autre, vous relisez le tableau (fournisseur, date, montants, catégorie — tout est corrigeable), puis un clic enregistre toutes les dépenses, chacune avec son fichier en justificatif. - Le badge « Justificatif manquant » signale chaque dépense notée sans sa facture — vous pouvez la joindre plus tard depuis la liste. - Une dépense non payée reste « À payer » ; marquez-la payée quand l’argent sort. - Les achats saisis depuis le module Stock (bons de commande, factures fournisseurs) apparaissent dans la même liste : c’est le même registre. ## Banque : importer, pointer, vérifier La banque a sa page : Comptabilité › Banque (aussi depuis « Votre argent » et la recherche ⌘K). En haut, le nom du compte affiché et quatre chiffres : le solde d’après vos relevés, le solde en comptabilité, l’écart entre les deux et le nombre d’opérations à rapprocher. Quand tout est pointé, l’écart est à zéro. Deux façons de l’alimenter : relier votre banque (formule Business — les opérations arrivent seules chaque heure, voir l’article « Connexion bancaire ») ou importer vos relevés (CSV, OFX ou QIF) avec le bouton « Importer un relevé » : ré-importer le même fichier ou une période qui chevauche ne crée jamais de doublon, et chaque relevé reste listé dans Sources › Relevés importés avec « Annuler cet import » tant que ses lignes ne sont pas rapprochées. Les opérations se lisent dans un tableau avec recherche, filtre par mois et filtre d’état (à rapprocher, avec suggestion, rapprochées, toutes), par pages de cinquante. Une opération « en attente » (annoncée par la banque mais pas encore comptabilisée) est marquée comme telle : son libellé ou son montant peut encore changer, elle n’est jamais rapprochée automatiquement. Chaque ligne porte son état et ses gestes. Une suggestion de facture (émise non soldée ou fournisseur non réglée) se confirme d’un clic — confirmer = un règlement saisi à la main, avec les mêmes effets : comptabilité, relances, statut transmis. « Rapprocher » ouvre les écritures comptables candidates (et les factures qui ressemblent). « Dépense » crée la dépense correspondante, payée à la date de la ligne ; « Recette » enregistre une entrée d’argent encaissée hors Capibara dans votre chiffre d’affaires. Une ligne rapprochée montre le numéro et le libellé de son écriture et se dé-rapproche depuis son menu. Une ligne rapprochée dit à quoi elle est reliée et l’ouvre : la fiche de la facture (ou de l’avoir) pour un encaissement, le bon de commande ou le justificatif pour une dépense — depuis le libellé sous l’état ou par le menu de la ligne. Avec plusieurs comptes, le compte affiché se choisit d’un clic dans Sources (liste des comptes, ou comptes d’une connexion bancaire) ; les compteurs et les chiffres du haut sont ceux du compte affiché, et le bouton « Importer un relevé » écrit son nom pour que la cible ne soit jamais un pari. Une sortie d’argent sans pièce — un débit relié ni à une facture fournisseur, ni à une dépense, ni à une écriture — est signalée : le filtre « Sorties sans pièce » les isole avec leur total, un encart le rappelle en haut de la page Banque et sur « Votre argent », et les responsables de l’organisation reçoivent une notification, au plus une par semaine, tant qu’il en reste depuis plus de sept jours. Pour justifier une sortie : « Dépense » sur la ligne (la facture se joint ensuite), ou « Rapprocher » si la dépense est déjà saisie. Une suggestion non confirmée ne justifie rien. « Rapprocher automatiquement » enchaîne les deux moteurs : les écritures au montant exact et sans ambiguïté, puis les factures reconnues avec certitude (montant exact et numéro dans le libellé), selon le mode réglé dans Sources › Rapprochement — suggestions à confirmer par défaut, automatique « gagné » après cinq confirmations sans refus, ou désactivé. Le solde initial (Sources › Comptes) est le point de départ des relevés importés : il cale la vérification de compte. Un écart est normal quand une écriture n’est pas encore sur un relevé, ou l’inverse — rapprochez les lignes en attente, ou enregistrez celles qui manquent en dépense ou en recette. ## TVA : préparée, jamais télédéclarée En franchise en base, vous n’avez aucune déclaration de TVA à faire : l’onglet suit votre chiffre d’affaires face aux seuils (37 500 € de prestations de services / 85 000 € de ventes en 2026) et vous alerte à l’approche. Au régime réel, choisissez votre périodicité (mensuelle, trimestrielle ou annuelle) : Capibara prépare la déclaration case par case, avec les numéros du formulaire 3310-CA3 (base et TVA par taux, TVA déductible, TVA nette due ou crédit) — vous recopiez sur impots.gouv.fr. Capibara prépare, ne déclare jamais à votre place. « J’ai déclaré cette période » verrouille les écritures de la période : plus rien ne peut y être modifié par erreur. Le verrou reste révisable par un administrateur dans la carte Exercices. ## Pour votre comptable Le dernier onglet porte la comptabilité brute : journal des écritures, saisie manuelle, balance, lettrage, plan comptable, et le bouton « Synchroniser les écritures » qui vérifie que toutes vos ventes ont bien la leur (et rattrape celles qui manquent, sans jamais créer de doublon). La carte « Tout donner à votre comptable » exporte tout ce qu’un cabinet demande sur une période : le FEC, le journal, le grand livre, la balance et la liste des dépenses en CSV lisibles dans Excel, et les justificatifs en ZIP — avec un récapitulatif des dépenses dont la facture manque encore. Le FEC est volontairement un fichier texte (.txt) : son nom (SirenFECAAAAMMJJ) et son format (colonnes séparées par « | ») sont imposés par l’administration fiscale — c’est exactement ce fichier que réclament un contrôle et le logiciel de votre comptable, ne le renommez pas. Pour consulter vos données dans Excel, prenez les exports CSV juste à côté. ## Ce que Capibara ne fait pas (volontairement) - Télédéclarer la TVA ou produire une liasse fiscale : ces actes engagent votre responsabilité — Capibara prépare des chiffres justes, votre cabinet (ou vous) déclarez. - Le bilan et les amortissements : l’export FEC assure la continuité avec les outils de votre expert-comptable. - Modifier une écriture d’une période déclarée ou d’un exercice clôturé. --- ## Devis & Factures : tout le cycle de vente L’application Facturation gère tout votre cycle de vente : devis → facture → paiement, avec des documents conformes au droit français (numérotation continue, mentions légales, archivage). À ne pas confondre avec votre abonnement à Capibara (l’offre Free, Pro ou Business de votre organisation), qui se gère dans « Mon organisation › Abonnement » et a son propre guide. Tout vit dans un seul écran, Facturation › Documents, organisé en cinq onglets : Documents, Encaissements, Trésorerie, Conformité et Réglages. ## Avant de commencer : votre identité Renseignez votre identité légale dans Paramètres › Société › Identité légale : raison sociale, adresse complète, SIRET, numéro de TVA, et si vous êtes une société, capital social et ville du RCS. Ce n’est pas cosmétique : ces informations sont FIGÉES sur chaque document au moment où vous l’émettez, et certaines sont obligatoires pour la facturation électronique. Si elles manquent, un bandeau orange vous prévient en haut de l’écran Documents — corrigez-le avant d’émettre vos premières factures. ## Créer un devis ou une facture - Cliquez sur « Devis » ou « Facture » : un brouillon s’ouvre, modifiable autant que vous voulez. - Choisissez le client dans la liste déroulante (elle cherche parmi tous vos contacts et sociétés, pas seulement ceux déjà marqués « client »). - Pas de fiche pour ce client ? Choisissez « Saisir un client (sans fiche) » : vous tapez ses coordonnées à la main, et la recherche d’entreprise remplit tout d’un coup à partir du nom, du SIREN ou du SIRET. Une case permet d’enregistrer au passage la fiche dans votre base. - Ajoutez vos lignes : désignation, quantité, prix unitaire HT, taux de TVA (20 %, 10 %, 5,5 %, 2,1 %, taux zéro, exonéré ou autoliquidation, ligne par ligne). - Le total se met à jour en direct pendant que vous tapez. Une remise globale et des notes imprimées sur le document sont disponibles à droite. ## Émettre : le point de non-retour Le bouton « Émettre » enregistre vos modifications puis fige le document. À cet instant : il reçoit son numéro définitif (séquentiel, sans trou), votre identité et celle du client sont recopiées telles quelles, les mentions légales sont calculées, et un PDF est archivé (accompagné d’un fichier Factur-X pour les factures et avoirs). Si la case « Envoyer au client par e-mail » est cochée (elle l’est par défaut) et que le client a une adresse connue, il reçoit aussitôt un e-mail à vos couleurs avec le récapitulatif, le PDF, et le bon bouton : « Payer en ligne » pour une facture, « Accepter et signer » pour un devis. Le bouton « Envoyer par e-mail » d’un document émis permet de renvoyer ce même message à tout moment. Après l’émission, plus aucune modification n’est possible — c’est la loi, et c’est ce qui rend vos documents opposables. Une erreur se corrige par un AVOIR, jamais par une retouche. Le PDF que vous téléchargez est toujours celui de l’archive, pas une régénération : même si vous déménagez ou changez de nom l’an prochain, une facture de cette année restera exactement telle qu’elle a été émise. ## Faire signer un devis Sur un devis émis, « Envoyer par e-mail » transmet le devis à votre client avec un bouton « Accepter et signer en ligne ». Le lien de signature est personnel au signataire : il part par e-mail et n'est jamais copiable depuis votre écran — personne ne peut signer à la place du client. Sur la page de signature, le client voit le PDF du devis, le contenu certifié, et signe. La signature vaut acceptation : le devis passe automatiquement en « Accepté », l’opportunité liée dans le CRM passe en « Gagné », et le PDF archivé est régénéré avec un bloc « Bon pour accord » portant le nom du signataire, la date, l’identifiant de preuve et une empreinte SHA-256. N’importe qui — votre client compris — peut vérifier l’authenticité de cette signature sur capibara.fr/verifier-signature en saisissant l’identifiant ou l’empreinte imprimés sur le document, et télécharger une attestation PDF. Vous pouvez aussi marquer un devis accepté ou refusé à la main (le client a répondu par téléphone), puis le convertir en facture en un clic — la facture reprend toutes les lignes. « Retirer le devis » annule un devis émis tant qu’aucune décision n’est prise : il ne peut plus être signé, accepté ni envoyé, et son PDF archivé porte le tampon « Annulée ». Une décision prise reste prise — et une facture émise, elle, ne s’annule jamais : elle se corrige par un avoir. ## Se faire payer - « Lien de paiement » copie une adresse que votre client ouvre pour régler par carte. Il paie sans quitter la page ; l’argent arrive sur VOTRE compte Stripe, et la facture passe « Payée » toute seule. - « Enregistrer un règlement » couvre tout le reste : virement, chèque, espèces. Choisissez le moyen et la date de réception — la facture (ou l’échéance) est marquée payée avec exactement les mêmes effets qu’un paiement en ligne : tampon « Acquittée », encaissement enregistré, écriture comptable, arrêt des relances. - Le paiement en ligne demande d’avoir relié votre compte Stripe (Paramètres › Encaissements en ligne) et un montant d’au moins 0,50 €. Si quelque chose bloque, le bouton vous dit précisément quoi. - Une facture réglée voit son PDF archivé régénéré avec un tampon « Acquittée ». - « Payer en plusieurs fois » découpe la facture en 2 à 24 échéances mensuelles. Chaque échéance a son propre lien de paiement et ses propres relances. Dès qu’une échéance est réglée, le plan se verrouille. - Pour rembourser un encaissement par carte (total ou PARTIEL), passez par Paramètres › Encaissements en ligne › « Rembourser un client » — chaque encaissement d’une facture y apparaît, échéances comprises. Un règlement reçu par virement se rembourse par virement, hors de l’outil. ## Relancer les impayés Activez les relances automatiques dans l’onglet Réglages et choisissez votre cadence (par exemple 3, 10 puis 20 jours après l’échéance). Capibara envoie les rappels avec le lien de paiement, sur un ton progressif — courtois, puis ferme, puis dernière relance avant recouvrement — et s’arrête net dès que le règlement arrive. La même cadence couvre les deux cas : une facture SANS échéancier est relancée à partir de sa date d’échéance (ou de son émission si vous n’en avez pas mis), et une facture en « plusieurs fois » est relancée échéance par échéance. Une facture couverte par un avoir n’est jamais relancée, et une relance réclame toujours le montant réellement restant dû. ## Encaissements et trésorerie L’onglet Encaissements liste TOUS vos encaissements en ligne, quelle que soit leur origine : factures, TPE virtuel, billetterie, dons, réservations, adhésions, boutique. C’est le point de vérité de ce qui est entré. L’onglet Trésorerie en donne la courbe sur douze mois, avec le total du mois en cours et celui de l’année. ## Facturation électronique (2026) À partir du 1er septembre 2026, toutes les entreprises devront pouvoir RECEVOIR des factures électroniques via une plateforme agréée (l’émission devient obligatoire aux mêmes dates pour les grandes entreprises, et au 1er septembre 2027 pour les PME et TPE). L’onglet Conformité gère tout cela. Pour transmettre en votre nom, Capibara s’appuie sur Super PDP, la plateforme agréée qu’il intègre. Une seule fois, depuis l’onglet Conformité, cliquez sur « Relier votre entreprise » : vous passez par le parcours sécurisé de Super PDP (votre e-mail, votre entreprise, votre accord pour l’envoi des factures, une vérification d’identité, puis l’autorisation donnée à Capibara) et vous revenez dans Capibara : votre entreprise est reliée. Prévoyez quelques minutes et une pièce d’identité. Tant que Super PDP termine la vérification de votre entreprise, rien ne part : l’onglet l’affiche et propose « Vérifier maintenant ». Le coût est ensuite refacturé au document transmis selon votre formule (réduit en Pro et Business), montant et décompte visibles dans l’onglet Conformité. Vous avez déjà votre propre abonnement Super PDP ? Collez plutôt les clés de votre application (section « Options avancées » de l’onglet) : Super PDP vous facture alors directement et Capibara ne refacture rien. Dans tous les cas, recevoir les factures de vos fournisseurs est inclus. Pour ACTIVER l’émission vers le circuit, un moyen de paiement doit être enregistré (les formules payantes en ont déjà un ; en Gratuit, le bouton de l’onglet Conformité l’ajoute en une minute). Vous n’êtes facturé qu’à l’usage, en fin de mois : rien transmis, rien facturé. La RÉCEPTION des factures fournisseurs, elle, est incluse et jamais bloquée — c’est votre obligation dès le 1er septembre 2026, alors qu’émettre ne devient obligatoire pour les PME qu’au 1er septembre 2027. Un document à 0 € n’est jamais transmis automatiquement (transmission manuelle possible depuis sa fiche). Une fois raccordé, tout est automatique : chaque facture, acompte ou avoir émis à un client professionnel est transmis tout seul (désactivable), les statuts du circuit se mettent à jour toutes les 30 minutes, votre encaissement est déclaré à la plateforme quand la facture est réglée, et les factures de vos FOURNISSEURS sont relevées automatiquement — les responsables de l’organisation sont notifiés quand il en arrive de nouvelles. Un dépôt refusé par la plateforme ne repart jamais tout seul : corrigez ce qui manque, puis retransmettez depuis la fiche. Une facture fournisseur reçue s’enregistre en dépense en un clic : elle attend alors son règlement et se rapproche d’elle-même de la ligne bancaire correspondante. L’onglet Conformité le résume en une carte : l’état de la transmission (active, à faire, en vérification, en démonstration), sous quelle identité vos factures partent, le décompte du mois, et le geste à faire s’il y en a un. Juste dessous, les deux automatismes — transmission des factures aux professionnels, e-reporting chaque matin — se coupent d’un clic. Chaque matin, Capibara dépose aussi l’e-reporting : l’agrégat de vos ventes aux particuliers de la veille (biens et prestations distingués comme l’exige la norme) et les données de paiement de vos prestations. Vous n’avez rien à faire, mais tout se désactive dans l’onglet. Si une facture ne peut pas partir, la fiche vous dit exactement ce qui manque (SIRET, adresse du client…). Ces données étant figées à l’émission, complétez-les puis émettez la facture suivante : celle qui est déjà partie se corrige par un avoir. Un dépôt rejeté par la plateforme ne se retente jamais tout seul — corrigez puis retransmettez depuis la fiche. Une facture adressée à un PARTICULIER n’est jamais transmise à l’acte — la transmission ne concerne que les factures entre professionnels. Ses ventes sont couvertes par l’e-reporting quotidien automatique : pas besoin de l’adresse complète du client, la facture s’émet et se paie normalement. Une de vos organisations facture une autre de vos organisations ? Sur la fiche d’une facture, d’un acompte ou d’un avoir émis, « Déposer chez… » place une copie, avec son PDF, dans les factures fournisseurs de l’organisation cliente : une facture s’y enregistre en dépense en un clic, TVA pré-remplie, et le PDF en devient le justificatif. Le bouton n’apparaît que si vous êtes PROPRIÉTAIRE de l’organisation cliente, qu’elle utilise la facturation et que son SIREN est celui du client de la facture ; un second dépôt ne crée rien de plus. Ce dépôt est une copie de confort, jamais une transmission légale : quand votre organisation est soumise à la facturation électronique, la facture légale reste celle transmise par la plateforme agréée. Si les deux exemplaires arrivent, un seul devient une dépense : Capibara reconnaît la même facture à son numéro, au SIREN du fournisseur et à l’année. ## Encaisser au comptoir (TPE virtuel) Le TPE virtuel encaisse sur place sans terminal bancaire : vous saisissez un montant et un libellé, le client scanne le QR code affiché et paie sur son téléphone. Le paiement se confirme en direct sur votre écran, et l’encaissement rejoint l’onglet Encaissements. ## Bon à savoir - L’écran Documents crée devis et factures ; un AVOIR se crée depuis la facture émise à corriger (bouton « Créer un avoir » sur sa fiche). Le moteur gère aussi acomptes, reçus, notes et reçus fiscaux de don — émis par les rails concernés (TPE, dons…), leurs boutons arrivent écran par écran. Reçus et notes peuvent rester anonymes ; une facture doit toujours nommer son client. - Un avoir ÉMIS agit sur la facture liée : couverte en totalité, elle ne se paie plus (« Annulée par avoir ») ; couverte en partie, son lien de paiement réclame la somme restante. Si la facture était déjà réglée, l’avoir vous dit ce que vous devez rembourser au client — Capibara ne rembourse jamais à votre place. - Un contact que vous facturez devient automatiquement « client » dans votre CRM. - Dupliquer un document (émis ou non) recrée un brouillon identique — pratique pour une prestation récurrente ou pour re-proposer un devis expiré. - La TVA par défaut des ventes sans détail par ligne (TPE, billets, réservations) se règle dans Paramètres › Devises et taxes. Si vous êtes en franchise de TVA, Capibara le sait et l’écrit sur vos documents. --- ## Signature électronique : preuve, vérification et sécurité Capibara intègre une signature électronique dite « simple » (articles 1366 et 1367 du Code civil, règlement eIDAS n° 910/2014) : le signataire lit le document en ligne, saisit son nom, certifie sa lecture et signe en un clic. Une preuve est scellée au même instant : le contenu certifié du document, le nom du signataire, l'horodatage, l'adresse IP et le navigateur. Les documents concernés : les devis (la signature vaut acceptation — bon pour accord), les pièces des dossiers de formation (convention, règlement intérieur, livret…), les synthèses de contrat de travail et les comptes rendus d'entretien. ## Le lien de signature ne passe QUE par e-mail Le lien de signature est personnel au signataire : il part par e-mail depuis Capibara et n'est jamais affiché ni copiable dans votre back-office. C'est une protection contre la contrefaçon — si le lien était copiable, n'importe qui côté organisation pourrait ouvrir la page et signer à la place du client ou du salarié, ce qui viderait la preuve de sa valeur. Votre écran montre l'état, jamais le lien : « envoyé à X, valable jusqu'au Y », puis « Signé par X le… » avec le certificat. Un renvoi passe par le bouton « Renvoyer » (pour les pièces de formation, chaque renvoi révoque le lien précédent, et un anti-spam empêche de renvoyer la même pièce plusieurs fois en 10 minutes). Les liens expirent automatiquement au bout de 30 jours. ## Ce que voit le signataire La page de signature porte votre marque (logo, couleur de votre site). Le bloc de signature est en haut ; en dessous, le document : le PDF quand il existe (devis, contrat) et le « contenu certifié » — le texte exact dont l'empreinte sera scellée dans la preuve. Après signature, le signataire voit son certificat complet (nom, date et heure, identifiant de preuve, empreinte SHA-256) et peut télécharger une attestation PDF transmissible. Un devis signé notifie immédiatement votre centre de notifications — la facture reste ensuite votre geste, quand vous le décidez. ## L'empreinte SHA-256 : ce qu'elle couvre (et ce qu'elle ne couvre pas) L'empreinte imprimée sur les documents et l'attestation scelle trois choses ensemble : le contenu certifié du document, le nom du signataire et l'horodatage de la signature. Toute altération de l'un des trois donnerait une empreinte différente. Ce n'est PAS l'empreinte du fichier PDF : si vous hachez le fichier dans un outil, vous obtiendrez une autre valeur — normale et attendue, car le fichier PDF est régénéré à chaque évolution d'affichage (tampon « Acquittée », bloc de signature ajouté, mise en page) sans que le contenu signé ait changé. La bonne façon de vérifier n'est jamais de hacher le fichier : c'est de comparer l'empreinte et l'identifiant imprimés, ou de les saisir sur la page de vérification. ## Vérifier une signature (public) N'importe qui — votre client compris — peut vérifier une signature sur capibara.fr/verifier-signature en saisissant l'identifiant de preuve ou l'empreinte SHA-256 imprimés sur le document. La page confirme l'enregistrement (organisation, document, signataire, date) et propose l'attestation PDF. Un identifiant inconnu, un lien en attente ou révoqué renvoient la même réponse « introuvable » : la page ne confirme jamais l'existence d'un document non signé. La page permet aussi de détecter un exemplaire modifié : elle affiche le contenu certifié par l'empreinte (re-vérifié mathématiquement à chaque consultation — l'empreinte est recalculée depuis ce contenu et confrontée à la preuve) et fournit le document signé en PDF tel qu'enregistré sur la plateforme. Si quelqu'un a retouché son exemplaire en conservant le bloc certificat imprimé, la comparaison avec le document servi par Capibara révèle immédiatement la différence. ## Signature en ligne vs marquage manuel Marquer un document « signé » à la main (le client a signé sur papier, répondu par téléphone…) reste possible — mais aucun certificat n'est alors affiché ni imprimé : Capibara ne fabrique jamais une preuve qui n'existe pas. Seule une signature posée en ligne, par le signataire, via son lien personnel, produit le certificat, l'empreinte et l'attestation. --- ## Stockage : espaces, versions, corbeille et partage sécurisé Le Stockage (menu « Stockage ») réunit trois espaces au même endroit, en onglets : la Médiathèque (vos images), les Documents (vos fichiers partagés), et le Wiki (vos pages de connaissances). Ce guide couvre les Documents et le Wiki. Tout est pensé pour être sûr : un fichier n'est visible que par les personnes autorisées, une suppression est réversible, et un partage vers l'extérieur peut être révoqué à tout moment. ## Les espaces : qui voit quoi Chaque fichier (et chaque dossier) vit dans un espace. Vous choisissez l'espace via les onglets en haut de la page Documents. - Organisation : visible de toute votre organisation. C'est l'espace par défaut, pour les documents communs. - Mon espace : visible de vous seul. Idéal pour vos brouillons et fichiers personnels. Il a son propre quota (une jauge dédiée s'affiche). - Équipes : visible des membres d'une équipe. Choisissez l'équipe dans le sélecteur. - Tous les fichiers : réservé à la modération (droit « Supprimer ») — permet de voir et gérer l'ensemble. ## Médiathèque : qui peut afficher vos images La Médiathèque suit les mêmes espaces (Organisation / Mon espace / Équipes), mais avec une règle d'accès qu'il faut connaître, car vos images servent des surfaces PUBLIQUES (votre site, vos fiches produits, vos e-mails). - Espace Organisation : chaque image est servie par une adresse directe non devinable. TOUTE personne qui possède ce lien peut l'afficher, même sans compte — c'est ce qui permet à vos images d'apparaître sur votre site public et dans vos e-mails. Ne rangez donc jamais un visuel confidentiel dans l'espace Organisation. - Mon espace et Équipes : l'image n'est visible que des personnes autorisées (vous, ou les membres de l'équipe), connectées à l'organisation. Le lien copié ne fonctionne pour personne d'autre. - Exceptions techniques : le logo de l'organisation, les photos de profil et les visuels du portail SSO restent affichables sans session — ils sont consommés par des e-mails, la visioconférence et les pages de connexion. - Pour un fichier réellement confidentiel, préférez l'onglet Documents (toujours authentifié) ou le coffre-fort RH pour les pièces d'un salarié. ## Importer des fichiers Cliquez sur « Importer » (ou glissez plusieurs fichiers). Chaque envoi affiche une barre de progression : vous pouvez l'annuler d'un clic, et en cas de coupure réseau, Capibara réessaie automatiquement. Les fichiers arrivent dans l'espace de l'onglet actif. Le clic droit sur un fichier ouvre son menu d'actions (renommer, aperçu, nouvelle version, déplacer, partager, supprimer). ## Versions et aperçu - Nouvelle version : déposez une version mise à jour d'un fichier — l'ancienne est conservée dans l'historique. - Fiche « Informations » : type, taille, emplacement, espace, propriétaire, dates, liste des versions (téléchargeables) et des partages actifs. - Restaurer une version : depuis la fiche Informations, revenez à une version antérieure (elle devient la version courante, sans rien perdre). - Aperçu : les images et les PDF s'affichent directement dans une fenêtre d'aperçu, sans télécharger. Les autres formats se téléchargent (jamais exécutés dans le navigateur, par sécurité). ## La corbeille : récupérer une suppression Supprimer un fichier le met à la CORBEILLE (il n'est pas détruit tout de suite). Un bandeau « Annuler » apparaît quelques secondes, et l'onglet « Corbeille » liste tout ce qui est supprimé. Vous pouvez y restaurer un document, ou le supprimer définitivement. Au bout de 30 jours, les documents en corbeille sont détruits automatiquement (et l'espace de stockage se libère). ## Partager un document Le menu d'un fichier propose « Partager… ». Deux familles de liens : - Lien rapide : un lien de téléchargement direct, valable 7 jours. Simple, mais non révocable — à réserver aux partages ponctuels. - Partage contrôlé (recommandé) : une page privée, révocable à tout moment, avec compteur de vues. Vous gardez la main même si le lien est transféré. ## Partage sécurisé : code ou e-mails autorisés Sur un partage contrôlé, vous choisissez le niveau de sécurité : - Lien seul : toute personne ayant le lien accède au document. - Code à 6 chiffres : un code est généré à la création (affiché UNE seule fois). Communiquez-le séparément du lien ; le destinataire le saisit pour accéder. - E-mails autorisés : vous listez les adresses qui ont le droit d'accéder. Le visiteur saisit son adresse sur la page ; si elle est autorisée, il reçoit par e-mail un code à usage unique (8 chiffres, valable 15 minutes) qu'il saisit pour accéder. ## Le journal d'activité Le bouton « Activité » (réservé aux administrateurs) montre qui a fait quoi sur les documents : imports, nouvelles versions, renommages, déplacements, partages, suppressions, restaurations. Les simples téléchargements ne sont pas journalisés (pour ne pas noyer le journal). ## Droits fins (au petit oignon) Dans l'éditeur de rôles, le Stockage propose des droits précis, activables indépendamment. En plus des droits de base (Consulter, Modifier, Supprimer), vous pouvez accorder à un rôle de simple consultation une capacité ciblée : - Importer des fichiers : un « contributeur » qui dépose des fichiers sans pouvoir les modifier ni les supprimer. - Partager : créer des liens de partage. - Déplacer entre espaces : réorganiser les documents entre Organisation / Mon espace / Équipes. ## Le Wiki L'onglet Wiki héberge vos pages de connaissances, organisées en espaces et en arborescence (pages et sous-pages). - Éditeur : une barre d'outils visible (titres, gras, listes, citation, lien, image…) ; tapez « / » pour insérer un bloc. Collez ou déposez une image directement, elle est importée automatiquement. - Enregistrement automatique : vos modifications sont sauvegardées en continu ; un indicateur le confirme. - Historique : consultez et restaurez une version antérieure d'une page. - Organisation : repliez/dépliez l'arbre, créez une sous-page depuis n'importe quel nœud, déplacez une page sous une autre. - Corbeille : une page supprimée (et ses sous-pages) part en corbeille, restaurable 30 jours. --- ## Puis-je récupérer mes données ? Oui, à tout moment — vos données vous appartiennent. Des exports aux formats standards sont disponibles depuis votre espace, conformément au RGPD (droit d’accès et de portabilité). Vous pouvez aussi corriger vos informations directement, et demander l’effacement de données personnelles (droit à l’oubli). La liste des sous-traitants techniques et le registre des traitements sont publiés dans les pages légales. --- ## Mes données sont-elles en sécurité ? Oui. Les données de chaque société sont isolées dans leur propre espace cloisonné (vos tables et votre stockage, séparés des autres) : aucune organisation ne peut accéder aux données d’une autre. Tout transite en HTTPS chiffré, les mots de passe sont hachés (jamais stockés en clair) et chaque accès est contrôlé par des rôles et des permissions fines. L’infrastructure est hébergée en France, sauvegardée régulièrement avec une copie hors-site, et un journal d’activité conserve la trace des actions importantes. --- ## Premiers pas avec Capibara Capibara réunit deux choses au même endroit : un site web public que vous composez par blocs, sans écrire de code, et une suite d’applications de gestion — CRM, devis et factures, comptabilité, boutique, stock, projets, planning, support, RH… Un seul compte, un seul espace, et les mêmes données qui circulent d’une application à l’autre. Il n’y a rien à installer, rien à mettre à jour et aucun serveur à louer : tout tourne sur une infrastructure hébergée en France, chez Ikoula, et s’utilise depuis un navigateur, sur ordinateur, tablette ou téléphone. Cet article vous accompagne de la création du compte à vos premiers gestes quotidiens. ## Les partis pris de Capibara Quelques partis pris valent d’être connus avant de commencer : ils expliquent la plupart des choix que vous rencontrerez dans l’interface. - Modulaire par principe — vous n’activez que ce dont vous avez besoin. Un socle est présent dès le premier jour et le reste : votre site, la médiathèque, le stockage de fichiers et le wiki, vos noms de domaine, la messagerie e-mail (l’application ; les boîtes hébergées par Capibara, elles, demandent une formule Pro ou Business), le chat et la visioconférence, la boîte de validation, les achats. - Aucune carte bancaire pour démarrer — la formule gratuite est active immédiatement, sans moyen de paiement ni engagement. Vous ne passez à une formule payante que le jour où une fonction réservée à Pro ou Business vous devient utile ; les applications de base, elles, sont à 0 €. - Réversible — une application se désactive comme elle s’active, sans justification à donner. Vos données sont conservées, et vous les retrouvez si vous la réactivez plus tard. - Un éditeur associatif — Capibara est édité par Forge Network, association loi 1901 à but non lucratif. La gestion est désintéressée : les recettes du service sont affectées à son fonctionnement (serveurs, infrastructure, exploitation) et à son développement ; aucun membre de l’association n’est rémunéré sur ces recettes. - Deux noms, un seul produit — « Capibara » est le service que vous utilisez, « Colibri » est le moteur technique sur lequel il repose. Vous croiserez parfois le second dans des pages techniques : il s’agit bien du même produit. ## 1. Créer votre compte et votre société Depuis la page d’accueil de capibara.fr, « Lancez-vous, c’est gratuit » ouvre l’inscription. Elle tient en quatre étapes courtes, et tout ce que vous y saisissez reste modifiable ensuite dans les réglages. - Votre compte — prénom, nom, adresse e-mail et mot de passe. C’est avec ce compte que vous vous connecterez, et il peut gérer plusieurs organisations. - Votre société — son nom, son e-mail, son téléphone, son statut juridique, son adresse, son logo si vous en avez un, et l’adresse de votre site. Une recherche « nom ou SIRET » interroge l’annuaire officiel des entreprises et remplit pour vous le nom et l’adresse ; le SIRET, la TVA et le reste se complètent plus tard dans Paramètres › Société. - Préférences — la langue et la devise par défaut de votre espace. Aucune coordonnée bancaire n’est demandée ici : les formules payantes se règlent plus tard par carte, via Stripe. - Conditions générales — vous acceptez les conditions générales de vente, puis « Créer mon compte ». La connexion est automatique dans la foulée. ## 2. Votre adresse publique À l’étape « Votre société », vous choisissez votre sous-domaine, de la forme ma-societe.capibara.fr : c’est l’adresse publique de votre site, celle que vous communiquerez à vos clients. La disponibilité est vérifiée pendant que vous tapez, et si vous laissez le champ vide, l’adresse est générée à partir du nom de votre société. Cette adresse fonctionne immédiatement et reste gratuite. Plus tard, avec une formule Pro ou Business, vous pourrez lui substituer votre propre nom de domaine (par exemple monentreprise.fr) — voir l’article « Brancher votre nom de domaine ». ## 3. Choisir votre profil Juste après l’inscription, un court parcours d’accueil vous demande votre profil. Capibara pré-active alors un bouquet d’applications cohérent, que vous ajustez à l’écran suivant avant d’entrer dans votre espace ; « Passer pour l’instant » vous laisse entrer sans rien choisir. Chaque profil n’active volontairement que les trois ou quatre applications essentielles à son cas d’usage : un espace lisible le premier jour vaut mieux qu’un menu de douze rubriques. Tout le reste s’ajoute plus tard en un clic. - Boutique en ligne — vendre des produits, gérer les clients et le stock. - Indépendant / consultant — devis, factures, projets et suivi des clients. - Agence / petite équipe — projets clients, factures et rendez-vous. - Commerce / boutique physique — stock, facturation rapide et clients au comptoir. - Association / bénévolat — membres, événements et communication. - Sur mesure — aucune application pré-cochée, vous les choisissez une par une. ## Ce qui est déjà là, sans rien activer Le tableau de bord est votre point de départ : des widgets y résument l’essentiel — un aperçu de votre site, votre agenda, vos raccourcis. Un court tour de bienvenue vous présente les grandes zones à la première visite — et il se rejoue autant de fois que vous voulez : Paramètres › Formation › « Revoir les tutoriels » liste les visites guidées (votre espace, l’assistant IA, votre site), dit où chacune se joue, et la fait repartir d’elle-même à votre prochain passage sur l’écran concerné. Un réglage permet aussi de ne plus se voir reproposer une visite qu’on a passée. Quelques données d’exemple peuvent par ailleurs être présentes pour que vous puissiez explorer sans partir d’une page blanche ; vous les effacez quand vous voulez depuis Paramètres › Avancé. Sans aucune activation, vous disposez déjà de : - Site web — votre site public et son éditeur. - Médiathèque — vos images et vos fichiers, réutilisables partout, dans le menu « Stockage ». - Domaines — votre adresse et vos noms de domaine, dans Paramètres › Société › Domaines. - Messagerie — l’application e-mail et son webmail. Nuance importante : les boîtes hébergées par Capibara (en @capibara.fr comme sur votre domaine) demandent une formule Pro ou Business — sur la formule gratuite, aucune ne peut être créée. Vous pouvez en revanche, dès le gratuit, relier une adresse e-mail que vous possédez déjà ailleurs (IMAP) et la consulter ici. - Communications — le chat interne, les appels et la visioconférence. - Validations — la boîte où atterrissent les demandes à approuver (congés, achats…), signalées par une icône dans l’en-tête de votre espace. ## 4. Faire votre site Le menu « Site web » ouvre le pilotage de votre site, organisé en sections. Pages : créer, publier, régler l’accès — « Éditer » ouvre l’éditeur de blocs. Modèles : poser un site complet en un clic — les pages arrivent en brouillon, mais le style choisi et, pour le modèle « Communauté privée », la confidentialité du site s’appliquent tout de suite à votre site en ligne. Apparence : style, couleurs, polices, favicon. Navigation : le menu, le bandeau d’annonce, le pied de page. Réglages : confidentialité du site, langues proposées, référencement par défaut. Viennent ensuite les sections Communauté (membres, forum, avis, sondages), Vendre (billetterie, adhésions), Étendre (blocs apportés par vos apps, cartes) et Mesurer (statistiques de visites, sans cookie ni suivi individuel). Une carte « Prochaines étapes » vous guide tant que l’essentiel n’est pas fait : publier votre page d’accueil, choisir un modèle ou un style, poser votre logo ou votre favicon, vérifier le menu et le pied de page, renseigner le référencement, brancher un nom de domaine. Elle disparaît d’elle-même une fois tout coché. Vous ne risquez pas la page blanche : tant que vous n’avez rien personnalisé, votre adresse affiche une page d’accueil sobre à votre marque, qui renvoie vers vos rubriques publiques. Détails dans « Votre site et votre sous-domaine » et « Navigation, menu et pages de votre site ». ## 5. Votre adresse e-mail professionnelle Le menu « Messagerie » héberge de vraies boîtes e-mail pour votre organisation — à ne pas confondre avec le chat interne, qui sert aux échanges entre collègues. Selon vos droits, cette page ne montre pas la même chose : une personne qui dispose simplement d’une boîte est conduite directement à son webmail, tandis qu’un gestionnaire voit l’administration (créer les boîtes, les attribuer, gérer les alias d’équipe et les transferts). Le webmail s’utilise sans rien installer, et vos boîtes se configurent aussi dans votre logiciel de messagerie habituel. L’application Messagerie est toujours active, quelle que soit votre formule : il n’y a rien à activer dans « Modules ». Une boîte HÉBERGÉE par Capibara, en revanche, demande une formule Pro (jusqu’à 5 boîtes) ou Business (jusqu’à 100) : sur la formule gratuite, la création est refusée, avec le message « Votre forfait actuel ne permet pas de créer de boîte mail ». Trois façons d’avoir une adresse dans Capibara : - Adresse incluse (Pro ou Business) — de la forme libellé.votre-societe@capibara.fr (par exemple contact.mon-resto@capibara.fr). Le libellé est libre : contact, support, compta… Rien à configurer, ces adresses partent depuis l’infrastructure authentifiée de Capibara. - Votre propre domaine (Pro ou Business) — de la forme libellé@mondomaine.fr, une fois votre nom de domaine branché et vérifié. Vous envoyez et recevez sous votre marque. - Une adresse que vous avez déjà ailleurs (toutes formules, gratuite comprise) — chez votre hébergeur, Gmail, Outlook… : reliez-la en IMAP depuis le menu « Boîtes externes » et lisez-y votre courrier sans quitter votre espace. Aucune formule payante n’est exigée pour cela. Le détail est dans « Adresses e-mail externes (IMAP/SMTP) ». ## 6. Ajouter des applications Le menu « Modules » réunit tout ce qui s’ajoute à votre espace, sous deux onglets. « Modules » liste les applications Capibara : vous y voyez ce qui est inclus dans votre formule et ce qui relève d’une formule supérieure, et vous activez d’un clic. « Apps » liste les apps publiées par des développeurs extérieurs : vos apps installées d’abord, puis le catalogue. Une app a sa propre page dans votre espace. Tant qu’elle n’est pas installée, cette page est un écran de consentement : les autorisations qu’elle demande, écrites en phrases lisibles, l’endroit où elle tourne et où vont ses données, et son prix — certaines apps de développeurs sont payantes, le montant est affiché avant toute installation. Une fois installée, la page devient un tableau de bord à onglets : vue d’ensemble, réglages, accès, journal et santé, données, version. Sa fiche publique, elle, vit dans le marketplace, consultable même sans compte. Pour voir concrètement à quoi cela ressemble, l’app officielle Météo (clé meteo) est un bon exemple : sa fiche publique est sur capibara.fr/marketplace/meteo, et son installation depuis votre espace sur /modules/addons/meteo. Le détail de tout le reste — mettre en pause, ouvrir l’accès à un rôle, lire le journal, comprendre la facturation — vit dans « Activer et gérer les modules » et « Les apps du marketplace : installer, autoriser, suivre ». ## 7. Choisir votre formule Votre formule se change depuis « Mon organisation › Abonnement ». La facturation est par siège, c’est-à-dire par utilisateur actif, au mois ou à l’année — l’engagement annuel revient moins cher. Le paiement passe par Stripe, et Capibara ne conserve pas vos coordonnées bancaires. Les formules payantes s’ouvrent sur un essai gratuit de 14 jours : Stripe enregistre votre carte à la souscription, mais le premier prélèvement n’intervient qu’au bout des quatorze jours. Les tarifs à jour et le comparatif complet sont affichés sur cette page avant toute validation. Ce que débloque chaque formule : - Gratuit — les apps de base : CRM, Facture & Devis (le menu « Facturation »), Boutique, Stock de base, Blog, Projets, Planning, Newsletter, Support. Plus le socle toujours actif : site web, médiathèque, stockage de fichiers et wiki (Documents), noms de domaine, messagerie, chat et visioconférence, validations, achats. 3 utilisateurs inclus, aucune boîte e-mail hébergée, support par ticket. - Pro — tout le gratuit, plus la Comptabilité, l’éditeur de site avancé avec l’assistant IA, le domaine personnalisé sans filigrane et jusqu’à 5 boîtes e-mail hébergées ; 25 utilisateurs inclus ; support prioritaire. - Business — tout le Pro, plus les RH et employés, le Stock avancé (multi-entrepôts, inventaire physique, écran « À racheter »), le portail SSO à votre marque, la connexion bancaire avec rapprochement automatique (3 comptes inclus) et jusqu’à 100 boîtes e-mail hébergées ; 500 utilisateurs inclus ; support immédiat par chat en direct. - Ce que beaucoup croient payant et ne l’est pas : Facture & Devis et le Stock de base sont à 0 €, disponibles dès la formule gratuite — il suffit de les activer dans « Modules ». Le stockage de fichiers et le wiki (Documents) sont gratuits eux aussi, et déjà actifs : vous n’avez rien à activer. Seules la Comptabilité (Pro) et les RH & Employés (Business) sont réellement réservées à une formule, et côté Stock seuls le multi-entrepôts, l’inventaire physique et l’écran « À racheter » sont Business. ## 8. Inviter votre équipe Vos collègues s’invitent depuis « Mon organisation » : la carte « Membres actifs » ouvre la page « Membres de l’organisation », où vous saisissez leur adresse e-mail. Chacun reçoit un lien pour créer son accès et choisir son mot de passe. Vous attribuez à chacun un rôle — Administrateur, Manager ou Employé — qui détermine ce qu’il peut voir et faire ; l’onglet « Rôles et droits » de Mon organisation permet ensuite d’affiner, module par module. Gardez en tête que sur une formule payante, chaque utilisateur actif consomme un siège : ajouter une personne augmente votre facture d’un siège. Les détails sont dans « Utilisateurs et droits d’accès ». ## Trouver de l’aide Vous n’êtes jamais seul devant l’écran. Le niveau de service suit votre formule — par ticket sur le gratuit, prioritaire sur Pro, immédiat par chat en direct sur Business — mais l’aide en libre-service, elle, est la même pour tout le monde. Quatre portes, selon ce que vous cherchez : - Le centre d’aide — ces guides, publics sur capibara.fr/aide et repris dans votre espace sous « Aide ». La recherche en haut de page vous mène droit au bon article. - L’Assistant Capibara — la bulle « ? » en bas à droite de votre espace : il cherche dans tout ce centre d’aide et répond à vos questions sur Capibara, depuis n’importe quel écran. Si votre formule inclut l’IA, son onglet « Mon activité » lit en plus vos chiffres (ventes, devis, stock…) — en lecture seule, et seulement ce que votre compte a le droit de consulter. Si vous avez masqué la bulle, le menu de votre avatar la ramène, entrée « Assistant Capibara ». Son fonctionnement complet — les deux modes, ce qu’il sait lire, ce qu’il ne fait jamais — est détaillé dans l’article « L’Assistant Capibara : ses deux modes et ce qu’il sait lire ». - Le chat avec le support — même bulle, onglet « Chat support » : vous écrivez à une personne de l’équipe. - Le ticket — capibara.fr/aide/contact, avec un raccourci « Signaler un bug » dans le menu de votre avatar. Vous choisissez une catégorie (question générale, problème technique, signalement de bug, facturation, données personnelles), les réponses arrivent par e-mail et se suivent dans « Mes tickets ». ## Et après Quand vous aurez fait le tour, ces guides prennent le relais : - « Votre site et votre sous-domaine » — l’éditeur, les blocs, la confidentialité du site. - « Brancher votre nom de domaine » — remplacer l’adresse en capibara.fr par la vôtre. - « Navigation, menu et pages de votre site » — organiser vos pages et votre menu. - « Activer et gérer les modules » — activer, mettre en pause, comprendre ce qui est inclus. - « Les apps du marketplace : installer, autoriser, suivre » — les apps de développeurs, leurs autorisations et leur journal. - « Boîtes e-mail et webmail » — créer les boîtes, les alias d’équipe, les filtres et la réponse automatique. - « Utilisateurs et droits d’accès » — rôles, permissions fines, équipes. - « Abonnement Capibara : passer à Pro ou Business, forfaits et prix » — où changer d’offre, la facturation par siège, le paiement par Stripe et vos factures. - « Données et sécurité » — où vivent vos données, sauvegardes, export et droits RGPD. - « L’Assistant Capibara : ses deux modes et ce qu’il sait lire » — poser une question sur Capibara, ou sur vos chiffres. --- ## L’Assistant Capibara : ses deux modes et ce qu’il sait lire L’Assistant Capibara vit dans la bulle « ? » en bas à droite de votre espace, sur tous les écrans. Un clic la déplie : elle réunit l’assistant et le chat avec le support humain. « Assistant Capibara » ouvre le panneau de discussion ; « Masquer » le fait disparaître si vous préférez l’écran net, et le menu de votre avatar le ramène (entrée « Assistant Capibara »). Il sert à répondre sans quitter la page où vous travaillez : comment faire telle chose dans Capibara, et — si votre formule inclut l’IA — ce que disent vos propres chiffres. Sous la conversation, un lien « Ouvrir un ticket » reste toujours affiché : quand l’assistant ne suffit pas, une personne de l’équipe prend le relais. ## Deux modes, et une seule chose à retenir En haut du panneau, deux onglets. Ils ne lisent pas les mêmes sources et ne répondent pas aux mêmes questions : choisir le bon onglet est le seul geste qui demande un peu d’attention. - « Aide » — il répond sur le FONCTIONNEMENT de Capibara. Il cherche dans tout le centre d’aide, depuis n’importe quel écran, et ne voit AUCUNE de vos données : ni vos factures, ni vos clients, ni vos montants. - « Mon activité » — il lit VOS chiffres et les commente. En revanche il ne connaît pas le mode d’emploi : une question de paramétrage posée ici reçoit une réponse honnête, « je ne sais pas lire cela », suivie de ce qu’il sait faire. La règle tient en une phrase : une question en « comment » va dans Aide, une question en « combien », « où en est » ou « qui » va dans Mon activité. « Comment créer une facture d’acompte ? » → Aide. « Combien ai-je encaissé ce mois-ci ? » → Mon activité. Se tromper d’onglet ne casse rien : vous obtenez une réponse à côté de la plaque, il suffit de changer d’onglet et de reposer la question. Chaque mode garde sa propre conversation, vous ne perdez rien en basculant de l’un à l’autre. ## L’onglet « Aide » : comment marche Capibara Posez votre question en langage courant. L’assistant cherche dans TOUT le centre d’aide — ces guides et les articles publiés par l’équipe — et vous répond avec la marche à suivre : ce qui se passe, où cliquer, dans quel ordre. Les liens vers les articles viennent en plus, à la fin, jamais à la place de la réponse. Il sait sur quel écran vous êtes, mais ce n’est qu’un indice de contexte : depuis le Planning, une question sur vos e-mails reçoit bien une réponse sur les e-mails. Par défaut il répond court ; demandez-lui de détailler et il déroule la procédure complète. - Disponible quelle que soit votre formule, y compris sur la gratuite. - Il ne voit aucune donnée de votre organisation : seulement votre question, la conversation en cours et la documentation. - Il ne fabrique jamais d’adresse. Si aucun guide ne couvre le sujet, il le dit, explique ce qu’il sait, et propose d’ouvrir un ticket. - La conversation reste affichée tant que vous naviguez dans votre espace ; recharger la page repart d’une page blanche. ## L’onglet « Mon activité » : vos chiffres, lus pour vous Cet onglet répond avec vos propres nombres. Vous demandez « où en est mon argent » ou « qu’est-ce qui se vend le mieux » ; l’assistant choisit, dans une liste fermée de lectures, celles qui répondent, les exécute, puis commente ce qu’elles ont donné. Les chiffres affichés — indicateurs, courbes, tableaux — sont calculés et dessinés par Capibara. Le modèle d’IA les commente, il ne les écrit pas : un montant affiché ne peut donc être ni inventé ni arrondi en chemin. - « Lectures effectuées », sous chaque réponse, déplie le détail : quelles lectures ont eu lieu, et lesquelles ont échoué le cas échéant. Rien n’est masqué. - Quand la question est ambiguë, il demande une précision et propose des réponses à cliquer. Y répondre ne compte pas comme une nouvelle question. - Avant votre première question, le panneau affiche d’emblée la liste des lectures disponibles pour VOTRE compte ; ensuite, « Ce que je sais lire », en bas du panneau, la rouvre à tout moment. Un clic sur une ligne pose la question telle quelle. ## Pourquoi la réponse prend un instant L’assistant travaille en deux temps : il lit d’abord, il rédige ensuite. Tant qu’il collecte, rien n’est rédigé ; il ne commente que des résultats qu’il a réellement sous les yeux. C’est ce qui l’empêche d’annoncer un chiffre avant de l’avoir lu — et ce qui explique les quelques secondes d’attente. Le travail est borné : quelques lectures au maximum par question. S’il n’aboutit pas, il le dit et affiche tout de même ce qu’il a lu, plutôt que de meubler. ## Ce qu’il sait lire La liste est fermée : l’assistant ne peut poser aucune autre question à votre base. Vous ne voyez que les lectures des applications actives chez vous, et seulement celles que votre compte a le droit de consulter — la liste ci-dessous est donc le maximum possible, pas ce que vous aurez forcément. - « Mes ventes par mois » — vos encaissements réels mois par mois sur douze mois glissants, tous moyens confondus (facture réglée, boutique, caisse, terminal de paiement, encaissement manuel), et la comparaison d’un mois sur l’autre. Ne dit rien de ce qui est facturé mais pas encore payé. - « Le taux de conversion de mes devis » — vos devis des douze derniers mois : acceptés, refusés, expirés, encore en attente, le taux calculé sur les seuls devis décidés, et le montant accepté. - « Mes affaires gagnées et perdues » — les affaires clôturées du CRM, le taux de réussite et le montant gagné sur tout l’historique, la répartition par mois et les motifs de perte sur douze mois. - « Ma prévision de ventes » — le montant de vos affaires ouvertes pondéré par leur probabilité, plus le détail par étape. Une estimation, jamais un montant acquis. - « Les affaires à relancer » — les affaires ouvertes sans activité depuis 14 jours (à relancer) ou 21 jours (à revoir), les plus dormantes d’abord. - « Les contacts à rappeler en priorité » — vos contacts notés chaud, tiède ou froid d’après les signaux détenus : achats, devis, commandes, rendez-vous, activité récente. - « Combien j’ai de contacts et de clients » — les trois compteurs du carnet d’adresses : contacts, sociétés, et parmi elles celles marquées comme clientes. - « Les rendez-vous à venir » — les vingt prochains rendez-vous du planning, plus trois compteurs glissants : 24 heures, 7 jours, 30 jours. Ce sont ceux de TOUTE l’organisation : le planning ne dit pas ici à qui chaque rendez-vous est affecté, ouvrez-le pour filtrer par personne. - « L’état de mes demandes de support » — la répartition par statut, les demandes sans aucune réponse, celles dont le délai de première réponse est dépassé, et la note de satisfaction moyenne. - « Où en est mon argent » — recettes et dépenses sur douze mois, TVA de l’année en cours, factures non soldées ventilées par échéance, revenu récurrent estimé, dépenses sans justificatif et sorties bancaires sans pièce. - « Encaissé et dépensé ce mois-ci » — les deux totaux du mois civil en cours, du 1er à aujourd’hui, donc sur un mois incomplet. - « Ce que je dois à mes fournisseurs » — le restant dû sur vos factures fournisseurs et vos dépenses non réglées, dont ce qui est en retard. Ne couvre ni les notes de frais, ni les cotisations, ni les impôts. - « Où j’en suis du seuil de franchise de TVA » — votre chiffre d’affaires HT de l’année civile comparé aux seuils de franchise, avec un verdict volontairement prudent. - « Mes commandes de boutique » — le nombre de commandes par statut (en attente de paiement, payée, expédiée, livrée, annulée, remboursée), sur tout l’historique. - « Mes articles les plus vendus » — le classement par quantité vendue sur douze mois, avec le chiffre d’affaires de chacun. Ne compte que les ventes passées par une commande (boutique et caisse), pas celles facturées directement. - « Les articles en stock bas » — les articles descendus à leur niveau de réapprovisionnement, entrepôt par entrepôt. - « Combien vaut mon stock » — la valeur de votre stock aujourd’hui, au total et par entrepôt. Un article sans aucun coût renseigné compte pour zéro : le montant est un minimum. - « Où en sont mes projets » — les projets par état, puis les tâches non terminées : total, en retard, à faire sous sept jours, sans responsable, et les tâches terminées ces trente derniers jours. - « Mon effectif » — effectif actuel, entrées et sorties sur douze mois, rotation, ancienneté, répartitions par contrat et par département. La masse salariale n’apparaît que si vous avez le droit « paie ». - « Les demandes à valider » — les congés et notes de frais déposés que personne n’a encore tranchés, les plus anciens d’abord. Congés et notes de frais UNIQUEMENT : les bons de commande et les remises sur devis à valider se consultent dans la boîte Validations, qui demande un autre droit. - « Mes abonnés à la newsletter » — l’effectif de chaque liste de diffusion : abonnés confirmés et abonnés en attente de confirmation. C’est le registre des inscriptions : une adresse en rejet définitif y reste comptée et sera écartée à l’envoi. Cette liste s’étoffe au fil des versions. Une question qui n’a pas encore sa lecture ne reçoit jamais une réponse inventée : l’assistant dit qu’il ne sait pas la lire, et rappelle ce qu’il sait faire pour vous. ## Ce qu’il ne fait jamais - Il ne crée rien, ne modifie rien, ne supprime rien. Aucune de ses lectures ne peut écrire : c’est une propriété du code, pas une consigne donnée au modèle. - Il n’envoie aucun e-mail, ne valide aucune demande, ne change aucun statut. Pour agir, vous passez par l’écran concerné. - Il n’interroge pas librement votre base : il choisit une lecture dans la liste ci-dessus, telle qu’elle est, sans pouvoir en changer la période ni les filtres. « Du 3 au 17 mars » ne se demande pas encore. - Il n’invente ni fonctionnalité ni page d’aide : une adresse d’aide est toujours recopiée du catalogue, jamais fabriquée, et une question hors de son périmètre reçoit un « je ne sais pas » plutôt qu’une réponse plausible. ## Il ne lit que ce que vous avez le droit de voir Chaque lecture est exécutée en votre nom, avec vos droits, exactement comme si vous ouvriez l’écran vous-même : vos permissions sont relues au moment de la question, et les restrictions fines s’appliquent — un commercial qui ne voit que ses propres affaires n’obtient que les siennes. Conséquence normale : deux personnes de la même organisation peuvent poser la même question et obtenir deux chiffres différents. Ce n’est pas une erreur, c’est votre périmètre. Pour comprendre ou modifier ces périmètres, voir l’article « Utilisateurs et droits d’accès ». Une application désactivée n’a aucune lecture : activez-la depuis « Modules » et ses questions apparaissent (voir l’article « Activer et gérer les modules »). ## Ses limites, dites franchement - Un résultat peut être partiel : certaines lectures s’arrêtent à un nombre maximum de lignes. Une note le signale alors sous le chiffre concerné, et le total annoncé est un minimum. - Les périodes ne sont pas les mêmes d’une lecture à l’autre — douze mois glissants, année civile, mois en cours, tout l’historique. L’assistant les rappelle : lisez-les, elles changent l’interprétation. - Il montre les chiffres, il n’explique pas les causes. Il ne dira pas pourquoi vos ventes baissent : il ne connaît ni votre marché, ni votre saison, ni votre agenda. - Ses commentaires ne valent pas conseil comptable, fiscal ou juridique. Le verdict du seuil de TVA, par exemple, est volontairement prudent : sa lecture revient à vous ou à votre comptable. - Certaines questions n’ont pas encore d’outil — la rentabilité d’un projet, le détail d’un client précis, une période choisie librement. Il le dit plutôt que d’inventer. - Il peut s’arrêter sans conclure. Il affiche alors ce qu’il a lu et rouvre la liste « Ce que je sais lire », pour que vous reformuliez à partir du réel. ## Qui y a droit, et pourquoi l’onglet peut manquer L’onglet « Aide » est là pour tout le monde. L’onglet « Mon activité », lui, n’apparaît que si trois conditions sont réunies : - Votre formule inclut l’IA — c’est le cas à partir de Pro (voir l’article « Abonnement Capibara : passer à Pro ou Business, forfaits et prix »). - Au moins une des applications concernées est active dans votre organisation. - Votre compte a le droit de consulter au moins une des lectures ci-dessus. S’il manque une de ces conditions, l’onglet est simplement absent : Capibara préfère ne rien proposer plutôt qu’ouvrir une porte qui refuserait ensuite. Le mode « Mon activité » ne débite aucun crédit de votre quota IA mensuel, mais il passe par la même porte que les autres fonctions IA : quota mensuel épuisé ou plafond d’appels du jour atteint, il refuse poliment. Il s’espace aussi de lui-même si les questions s’enchaînent très vite. Dans ces cas-là, réessayez un peu plus tard, ou ouvrez un ticket. ## Vos données et le fournisseur d’IA Pour rédiger sa réponse, l’onglet « Mon activité » transmet au fournisseur d’IA (Google, via l’API Gemini) votre question et un résumé des données lues — ce résumé peut comporter des noms de clients, de contacts ou de salariés, des libellés que vous avez saisis (intitulés de congés, de notes de frais, de rendez-vous…), des dates et des montants. C’est la condition pour qu’un texte commente vos chiffres, et l’une des raisons pour lesquelles ce mode est réservé aux formules qui incluent l’IA. Dans l’onglet « Aide », rien de tout cela : seules votre question et la documentation sont transmises. La liste complète des sous-traitants et ce que chacun reçoit est publiée sur capibara.fr/legal/sous-traitants. Côté Capibara, chaque question posée dans « Mon activité » est inscrite au journal d’usage IA de votre organisation sous forme résumée, après masquage des adresses e-mail, IBAN, numéros de carte, de téléphone et de SIREN. Pour le reste — où vivent vos données, sauvegardes, export, droits RGPD — voir l’article « Données et sécurité ». ## À ne pas confondre avec les deux autres assistants - Le « Chat support » — même bulle, juste en dessous : vous y écrivez à une personne de l’équipe Capibara, pas à une IA. - L’assistant IA du chat de VOTRE site — celui qui répond à vos visiteurs quand personne de votre équipe n’est en ligne, à partir de votre wiki. Il n’a rien à voir avec celui-ci : voir l’article « Support client : tickets suivis sur votre site et chat en direct ». ## Bien poser sa question - Une question à la fois : l’assistant répond mieux à « combien de devis signés cette année ? » qu’à trois questions enchaînées dans la même phrase. - Parlez votre langage métier — « mes impayés », « ce que je dois », « qui rappeler » : les lectures sont décrites dans ces mots-là. - En panne d’idée, ouvrez « Ce que je sais lire » et cliquez une ligne : la question part telle quelle. - Si la réponse tombe à côté, vérifiez l’onglet avant de reformuler. Neuf fois sur dix, la question était simplement dans le mauvais mode. --- ## Qu’est-ce que Capibara ? Capibara est une plateforme hébergée qui réunit deux choses au même endroit : un constructeur de site web (façon Canva, sans code) et une suite d’applications de gestion — CRM, facturation, boutique, comptabilité, projets, planning, RH… Vous créez votre site public et vous pilotez votre activité depuis un seul espace, sans installer ni maintenir quoi que ce soit. C’est pensé pour les TPE, PME, indépendants et petites équipes, et hébergé en France. En clair : tout votre business, un seul outil. --- ## Puis-je utiliser mon propre nom de domaine ? Oui, avec les forfaits Pro (1 domaine) et Business (5 domaines). Vous branchez un domaine déjà acheté (OVH, Gandi, Cloudflare, etc.) en quelques minutes via Paramètres › Société › Domaines : Capibara vous guide pas à pas et vous donne les enregistrements DNS exacts à coller chez votre registrar. Une fois vérifié, votre site, votre administration et votre messagerie sont accessibles sous votre domaine, sans mention de Capibara dans l’URL, et le certificat HTTPS est émis automatiquement. --- ## Mon adresse capibara.fr reste-t-elle active ? Oui. L’adresse votre-societe.capibara.fr reste valable comme secours technique, même après avoir branché votre propre domaine. Quand vous désignez votre domaine personnalisé comme adresse principale, l’adresse capibara.fr redirige automatiquement vers lui (redirection permanente 301) — vos visiteurs et votre référencement sont conservés, rien n’est perdu. --- ## Mes e-mails partent-ils à mon nom ? Oui. Vos e-mails automatiques (confirmations, factures, relances, newsletters…) sont envoyés depuis une adresse dédiée à votre société, avec un nom d’expéditeur et une adresse de réponse que vous personnalisez. Tant que vous n’avez pas branché votre propre domaine, ils partent depuis l’infrastructure déjà authentifiée de Capibara : rien à régler et une bonne délivrabilité dès le départ. Avec votre domaine, l’assistant vous aide à poser les enregistrements SPF/DKIM pour envoyer entièrement sous votre marque. --- ## Dois-je installer quelque chose ? Non, rien à installer. Tout fonctionne dans votre navigateur (ordinateur, tablette ou téléphone) : ni serveur à louer, ni logiciel à mettre à jour, ni plugin à bricoler. Vous vous connectez, c’est prêt. L’application peut même être « épinglée » sur votre écran d’accueil comme une appli mobile. Les mises à jour et la maintenance sont faites par nos soins, en continu et sans coupure pour vous. --- ## Combien ça coûte ? Créer votre compte, votre site et utiliser les applications de base est gratuit — vous pouvez démarrer sans payer. Pour les fonctions avancées, vous choisissez un forfait Pro ou Business, facturé par utilisateur (« siège »), au mois ou à l’année (l’annuel donne droit à une remise). Vous pouvez aussi activer des modules à la carte. Il n’y a aucun engagement : tout est résiliable à tout moment, et les prix sont toujours affichés avant validation. Les paiements passent par Stripe ; vos coordonnées bancaires ne sont jamais stockées par Capibara. --- ## Puis-je arrêter quand je veux ? Oui, sans condition. Vous résiliez un module ou votre forfait à tout moment depuis votre espace, en quelques clics. Aucun nouveau prélèvement n’est effectué après la période déjà réglée, et vous gardez l’accès jusqu’à la fin de cette période. Avant de partir, vous pouvez exporter vos données (elles vous appartiennent). Si vous changez d’avis, il suffit de réactiver. --- ## Qu’est-ce qui est inclus dans l’abonnement ? Le compte, le site web et plusieurs applications de base (CRM, Boutique, Blog, Projets, Planning, Newsletter, Support…) sont gratuits, avec un certain nombre d’utilisateurs inclus. Les forfaits Pro et Business — facturés par utilisateur — débloquent les applications qui le nécessitent : la Comptabilité, les Documents et la Facturation & Devis demandent Pro ; les RH & Employés et la gestion de Stock demandent Business. Business ajoute aussi la connexion bancaire (opérations synchronisées, factures rapprochées automatiquement), le portail de connexion à votre marque (SSO), davantage de sièges et un support prioritaire. Le comparatif complet « qui inclut quoi » est affiché sur la page Abonnement ; certains modules spécialisés du marketplace restent en plus à la carte. --- ## Générer mon site en 1 clic ## Comment ça marche Dans **Mon site > Éditeur**, cliquez sur **« Générer ma landing avec l'IA »**. Décrivez votre activité en une ou deux phrases. L'IA rédige une page complète (hero, atouts, FAQ, contact) que vous pouvez ensuite ajuster. ## Disponibilité L'assistant IA est inclus dans les forfaits **Pro** et **Business**. Sur Free, le bouton n'apparaît pas. --- ## Votre site et votre sous-domaine ## Votre adresse publique Chaque société dispose d’une adresse dédiée de la forme votre-societe.capibara.fr. C’est l’adresse que vous communiquez à vos clients : elle affiche votre site public. Elle fonctionne dès la création, sans configuration. ## Construire votre site Le menu « Site web » ouvre votre espace de pilotage du site — l’écran s’appelle « Mon site » (voir la section suivante) ; « Éditer » ouvre l’éditeur d’une page. Vous composez vos pages avec des blocs (héros, textes, images, galeries, tarifs, coordonnées, carte…) que vous ajoutez, réordonnez et personnalisez. Un « Style de site » (couleurs, polices, ambiance) donne l’identité générale, et des modèles prêts à l’emploi permettent de démarrer vite. Vous prévisualisez, puis « Publiez » quand vous êtes prêt. Vos modifications s’enregistrent au fur et à mesure, sans que vous ayez à y penser : en haut de l’éditeur, une coche verte signifie « tout est enregistré » et une roue qui tourne, « c’est en cours ». Pour sortir, le lien « Mes pages », en haut à gauche, vous ramène à la liste de vos pages — et enregistre d’abord ce qui restait à enregistrer : vous ne perdez rien en partant. Enregistrer n’est pas publier. Tout ce que vous écrivez reste un brouillon, visible de vous seul, tant que vous n’avez pas cliqué sur « Publier ». Et à tout moment, Ctrl+Z (Cmd+Z sur Mac) annule la dernière modification, autant de fois que nécessaire. Chaque publication d’une page est gardée dans son historique (les 30 dernières), avec sa date et son auteur : « Paramètres de la page » › Historique. Les brouillons remplacés par un modèle ou par une restauration y sont gardés aussi. « Restaurer » remet une version dans le brouillon, « Revenir à la version publiée » y remet la version en ligne ; la page en ligne, elle, ne change qu’à votre prochaine publication. Dans l’éditeur, Ctrl+Z annule une restauration. La visite guidée de votre site se rejoue quand vous voulez : Paramètres › Formation › « Revoir les tutoriels ». Tant que vous n’avez rien personnalisé, votre adresse affiche une page d’accueil simple à votre marque (façon « link tree ») qui renvoie vers vos rubriques publiques — vous n’avez jamais une page blanche. ## Écrire un texte directement dans la page Vous modifiez les textes là où ils s’affichent, sans passer par un formulaire. Un premier clic sélectionne l’élément (le panneau de droite affiche alors ses réglages) ; un second clic entre dans le texte et pose le curseur exactement là où vous avez cliqué — vous corrigez un mot au milieu d’une phrase sans avoir à tout retaper. Le double-clic fait la même chose en un seul geste. Un texte d’exemple encore intact (« Votre texte… », posé par le modèle) fait exception : il est sélectionné en entier, pour que votre première frappe le remplace d’un coup. Dès que vous avez écrit quelque chose à vous, on n’y touche plus. Entrée valide ce que vous venez d’écrire, Échap annule et remet le texte précédent. Dans un paragraphe, Maj+Entrée passe à la ligne sans sortir de l’édition. ## Effacer un texte : ce qui se passe Vider un texte est une intention légitime, et elle est respectée. Si le texte est facultatif — un sur-titre, un sous-titre — effacez-le puis validez : il disparaît de la page. S’il est indispensable, il ne peut pas rester vide : l’ancien texte est rétabli et un message vous dit lequel et pourquoi, au lieu de le faire revenir en silence. C’est le cas du titre d’une grande section d’ouverture, par exemple. Même chose pour le texte écrit sur un bouton : un bouton affiche toujours quelque chose, donc le vider ferait simplement revenir son libellé par défaut — pour retirer un bouton, passez par le panneau de droite. ## Gras, surlignage, taille d’une seule ligne En plus des textes prévus par chaque bloc, vous pouvez poser les vôtres où vous voulez : un clic droit sur une section ouvre une roue qui propose Titre, Texte, Bouton, Image et Forme. Quand vous écrivez dans un titre ou un texte posé de cette façon, une petite barre de mise en forme apparaît juste au-dessus. - Gras, italique, souligné, barré et surligneur s’appliquent au passage que vous avez sélectionné. - A− et A+ changent la taille : celle du passage sélectionné, ou celle de la ligne entière si vous avez seulement posé le curseur — c’est ainsi qu’on met une ligne plus petite (ou plus grande) que le reste du paragraphe. - La croix efface la mise en forme : celle du passage sélectionné, ou celle de la ligne entière si rien n’est sélectionné. ## Choisir où mène un bouton ou un lien Quand un bloc propose un lien (le bouton d’une section d’ouverture, une carte cliquable…), vous ne tapez plus d’adresse : le panneau de droite vous fait d’abord choisir la destination — aucun lien, une page de votre site, une adresse web, un e-mail ou un téléphone — puis ne vous demande que ce qui manque. Une page se choisit dans la liste de vos pages ; pour un e-mail ou un téléphone, écrivez-les comme vous les écrivez partout ailleurs, le reste est ajouté pour vous (un numéro tapé avec des espaces fonctionne). ## Une image de fond qui reste lisible : le voile Un texte blanc sur une photo claire disparaît. Quand votre grande section d’ouverture porte une image de fond, le réglage « Voile sur l’image » pose un filtre entre l’image et le texte. Trois réglages rapides couvrent l’essentiel — Aucun, Clair, Foncé — et « Personnalisé » ouvre une couleur (à la pastille, ou au code du type #0b1b3a) et une opacité en pourcentage : de quoi obtenir un voile sombre légèrement bleuté, par exemple. Un aperçu montre le résultat sur place, sans avoir à publier, et la couleur du texte suit toute seule : claire sur un voile foncé, foncée sur un voile clair. ## Votre adresse sur une carte, sans coordonnées à recopier Le bloc « Coordonnées & horaires » ne demande ni latitude ni longitude. Écrivez votre adresse dans le champ prévu et quittez le champ : la position est recherchée toute seule, et la carte s’allume. Si plusieurs adresses correspondent, la liste vous est proposée et vous tranchez ; si aucune ne correspond, l’écran vous demande de préciser la ville ou le code postal. Un interrupteur « Afficher la carte » permet de l’éteindre si vous préférez ne montrer que vos coordonnées. Si vous déménagez et modifiez votre adresse, un avertissement signale que la carte, le bouton « Itinéraire » et votre fiche d’établissement pointent encore l’ancienne, avec un bouton « Mettre la carte à jour ». Placer le point à la main reste possible dans l’éditeur de carte, qui sert aussi à ajouter des points d’intérêt. ## Le hub Mon site : tout se pilote à gauche Sur un écran d’ordinateur, « Mon site » affiche votre identité en haut (logo ou favicon, nom du site, adresse publique à copier, état publié ou brouillon, confidentialité) avec les boutons « Voir en ligne » et « Éditer l’accueil », puis une colonne de sections à gauche. Sur un écran étroit, cette colonne devient une barre d’onglets. Chaque section a sa propre adresse (par exemple /site/membres) : vous pouvez la mettre en favori ou la partager avec un collègue. Les sections sont regroupées : Site (Pages, Modèles, Apparence, Navigation, Réglages), Communauté (Membres, Forum, Avis, Sondages), Vendre (Billetterie, Adhésions), Étendre (Apps, Cartes) et Mesurer (Statistiques). Une pastille signale les avis à modérer et les membres en attente. Les sections dont vous n’avez pas le droit n’apparaissent pas. La section Pages liste vos pages en tableau (état, accès, dernière modification) avec « Éditer », un menu par ligne (renommer et changer l’adresse, accès, traduire, accueil, voir en ligne, supprimer) et le bouton « Créer une nouvelle page ». Tant que le site n’est pas en place, une carte « Prochaines étapes » vous guide : publier l’accueil, choisir un modèle ou un style, poser votre logo, régler le menu, le référencement et le domaine — elle disparaît d’elle-même une fois tout fait. Dans Billetterie, chaque événement a sa propre page avec des onglets : Aperçu, Tarifs, Participants, Invités, Contrôle d’accès, Album et Conformité. Les actions courantes (publier, clore, modifier, dupliquer, émettre des places, prévenir ou annuler) sont en haut de la page. ## Partir d’un modèle Dans « Mon site › Modèles », un modèle pose d’un coup les pages d’un type de site — site vitrine, boutique en ligne, blog, portfolio, association, communauté privée — et, si vous le voulez, un style (couleurs et polices). La fenêtre du modèle liste les pages qu’il va poser avant que vous ne décidiez. Trois conséquences vous sont dites avant, pas après. La première : votre page d’accueil est refaite dans tous les cas, c’est le modèle qui la compose. Ce que vous aviez écrit dans son brouillon n’est pas perdu : il reste dans l’historique de la page (« Paramètres de la page » › Historique), d’où « Restaurer » le reprend. La deuxième tient dans une case, « Ne pas conserver les modifications déjà effectuées », qui ne concerne QUE les autres pages du modèle déjà présentes sur votre site : cochée, leur contenu est remplacé par celui du modèle, et leur version précédente reste dans leur historique ; décochée, elles sont laissées telles quelles. La troisième touche votre site EN LIGNE, tout de suite. Deux choses de cette fenêtre ne passent pas par la case brouillon. Le style, d’abord, si vous en choisissez un ici : il s’applique à tout le site — fonds, polices, arrondis, forme des boutons — y compris aux pages déjà publiées (votre couleur d’accent, elle, est conservée). Le modèle « Communauté privée », ensuite : il bascule l’ensemble du site en « réservé aux membres », donc vos pages déjà publiées cessent d’être visibles par les visiteurs non connectés et par les moteurs de recherche. La fenêtre vous prévient des deux avant que vous ne confirmiez, et rien n’est définitif : le style se reprend dans « Mon site › Apparence », la confidentialité dans « Mon site › Réglages ». Les pages, elles, arrivent en brouillon : leur contenu n’apparaît sur votre site en ligne que lorsque vous les publiez. ## Générer ou améliorer votre site avec l’IA (IA Studio) Oui, l’IA peut concevoir votre site pour vous. Dans l’éditeur d’une page, le bouton « IA Studio » ouvre l’assistant de conception : décrivez votre objectif en langage libre (« crée un site vitrine pour mon restaurant », « rends cette page plus vendeuse », « ajoute une section témoignages »…) et choisissez le mode — « Améliorer » (retoucher la page ouverte), « Créer la page » (la concevoir entièrement), « Tout le site » (refaire l’accueil et créer les pages nécessaires : services, à propos, contact…) ou « Une section » (se concentrer sur une seule). L’IA propose alors un plan et des modifications que vous relisez AVANT toute application : chaque changement s’affiche dans un comparatif à cocher, avec un aperçu en direct sur la page. Rien n’est enregistré sans votre validation, et une fois appliqué, Ctrl+Z annule comme n’importe quelle modification. L’IA peut aussi ajuster le style (couleurs, ambiance) de votre site. Si votre offre inclut l’IA, la fenêtre d’un modèle propose en plus un champ « Décrivez votre activité » : quelques phrases sur ce que vous faites, pour qui, où (en dessous d’une dizaine de caractères, l’écran vous prévient que ce sera ignoré). Ce que vous écrivez là n’est envoyé nulle part au moment d’appliquer le modèle : les pages sont posées tout de suite, puis vous êtes conduit dans l’éditeur de votre page d’accueil, l’IA Studio déjà ouvert, en mode « Tout le site », votre description recopiée dans le champ. Rien ne part à l’IA tant que vous n’avez pas lancé la génération vous-même : vous pouvez relire, ajuster, ou fermer le panneau. L’IA Studio est disponible à partir du forfait Pro. Votre offre inclut un quota de crédits IA par mois, remis à zéro au début du mois suivant ; le bas du panneau affiche ce que vous avez consommé. Une seconde limite, personnelle celle-là, étale votre utilisation dans le temps (sur les 5 dernières heures, et sur les 24 dernières). Elle a été nettement desserrée : construire son site d’une traite, avec plusieurs générations à la suite, est un usage normal. Si vous l’atteignez malgré tout, le message vous dit trois choses — qu’il s’agit de VOTRE rythme et non du quota de votre organisation (qui, lui, a encore des crédits), quand vous pourrez relancer, et qu’aucun crédit n’est perdu : cette limite ne consomme rien. ## Les rubriques qui s’affichent toutes seules Les pages publiques des modules (blog, boutique, réservation, aide…) apparaissent automatiquement sur votre site dès lors que le module est actif et qu’il y a du contenu à montrer. Un module non souscrit ne s’affiche pas, et sa page n’est pas accessible : pas de lien mort. ## Confidentialité du site Votre site peut être entièrement public, ou protégé. Vous pouvez verrouiller tout le site (ou certaines pages) par un code, le réserver à vos membres connectés, ou le limiter à un groupe. Chaque page peut aussi être « atteignable par lien mais masquée du menu ». ## Référencement (SEO) Pour chaque page et pour le site, vous réglez le titre, la description et l’image de partage (aperçu affiché sur les réseaux et moteurs de recherche). Une page réservée ou protégée est automatiquement exclue de l’indexation. ## Domaine personnalisé Avec les offres Pro et Business, vous branchez votre propre nom de domaine (par exemple monentreprise.com) à la place de l’adresse capibara.fr. La marche à suivre détaillée se trouve dans l’article « Brancher votre nom de domaine ». --- ## Brancher votre nom de domaine Si vous possédez un nom de domaine (acheté chez OVH, Gandi, Cloudflare, etc.), vous pouvez le brancher sur Capibara en quelques minutes. Votre site, votre administration et — à partir de la Phase 3 — votre messagerie et votre webmail seront accessibles sous votre propre domaine, sans aucune mention de Capibara dans l'URL. ## Forfaits requis Le branchement de domaine personnalisé est inclus dans les forfaits Pro (1 domaine) et Business (5 domaines). Le forfait Free reste sur l'adresse capibara.fr offerte. ## Pas encore de nom de domaine ? L’acheter ici Quand le service est ouvert sur votre instance, vous pouvez acheter votre nom sans quitter Capibara : Paramètres › Société › Domaines, carte « Acheter un nom de domaine ». Les extensions .fr et .com sont proposées pour un an, au prix affiché toutes taxes comprises avant le paiement ; un nom acheté compte dans le nombre de domaines de votre formule. Votre organisation est la titulaire du nom : vous saisissez ses coordonnées (dénomination, représentant, adresse), vous cochez les conditions, puis vous payez par carte. La commande ne part qu’une fois le paiement reçu. Le domaine est en général prêt en quelques minutes, déjà branché et configuré (site, e-mails, HTTPS) : les étapes 1 à 3 ci-dessous ne vous concernent pas. Si l’enregistrement échoue, vous êtes remboursé en totalité, automatiquement. - Un .com : confirmez sous 15 jours l’e-mail de vérification reçu à l’adresse du titulaire, sinon le nom est suspendu. - Renouvellement : proposé 45 jours avant l’échéance, au prix du moment, par e-mail et dans « Mes domaines ». Rien n’est prélevé automatiquement ; sans paiement, le nom expire à son échéance. - Partir : « Transférer ailleurs » affiche le code de transfert une seule fois (il vous est aussi envoyé par e-mail) pour déménager le nom chez un autre bureau d’enregistrement. - Qui peut acheter : l’administrateur de l’organisation, ou un rôle qui a reçu le droit « Acheter, renouveler ou transférer un nom de domaine ». - Les conditions complètes sont à l’article 17 des conditions générales de vente (« Noms de domaine »). ## 1. Ajouter votre domaine dans Capibara Ouvrez « Paramètres > Société > Domaines » puis cliquez sur « Ajouter un domaine ». Saisissez votre nom de domaine (par exemple monentreprise.com). Capibara génère un code de vérification unique. ## 2. Prouver que ce domaine vous appartient (TXT) Connectez-vous sur l'interface de votre registrar (l'endroit où vous avez acheté votre domaine) et créez un enregistrement TXT. Capibara vous donne le nom exact et la valeur exacte à coller. La propagation prend de quelques minutes à quelques heures selon le registrar. - Type : TXT - Sous-domaine : _colibri-verify - Valeur : la chaîne fournie par Capibara (commence par "colibri-verify=…") ## 3. Diriger le trafic vers Capibara (CNAME) Une fois le TXT vérifié, ajoutez chez votre registrar un CNAME (ou un enregistrement A si votre TLD ne supporte pas le CNAME à la racine) qui pointe votre domaine vers votre adresse Capibara. ## 4. Faire de ce domaine votre adresse principale Une fois le domaine vérifié et le certificat HTTPS émis (Capibara le fait automatiquement à la première visite), revenez dans « Paramètres > Société > Domaines » et cliquez sur « Principal ». À partir de ce moment, tous les liens partagés (e-mails, partages SEO) utilisent votre domaine ; l'adresse capibara.fr redirige automatiquement vers lui. ## Bientôt : DNS hébergé par Capibara Dans une prochaine version, vous pourrez déléguer entièrement votre domaine à Capibara (nameservers ns1.capibara.fr et ns2.capibara.fr). Plus aucun enregistrement DNS à configurer manuellement : tout est posé automatiquement (site, mail, webmail, sous-services). Vous gardez bien sûr la possibilité d'ajouter vos propres enregistrements via un éditeur DNS intégré. ## Blocs et pages des apps installées Une app installée (Modules › Apps) peut enrichir votre site. Dans l’éditeur d’une page, « Ajouter » propose un groupe « Vos apps » : chaque bloc proposé par une app se pose comme une section ordinaire, et ses réglages (une ville, un nombre d’éléments…) se remplissent dans le panneau de droite. L’aperçu montre le vrai rendu ; les boutons et formulaires du bloc fonctionnent sur le site publié. Certaines apps proposent aussi des pages entières. Elles ne s’affichent jamais toutes seules : dans « Mon site › Apps », vous activez chaque page et choisissez son adresse (par exemple /meteo). Une page activée entre dans le menu automatique et dans le plan du site ; une page de votre site qui porte déjà la même adresse garde toujours la priorité, et l’onglet vous le signale. Sur le site, l’app ne connaît jamais votre équipe : elle voit seulement le visiteur — son compte membre du site s’il est connecté, sinon un anonyme — et agit avec les droits que vous lui avez accordés à l’installation. --- ## Navigation, menu et pages de votre site ## Gérer vos pages Un site est composé de plusieurs pages (accueil, à propos, services, contact…). Elles se gèrent dans « Mon site › Pages » : un tableau qui donne pour chacune son état, son accès et sa date de dernière modification, avec « Éditer » et un menu par ligne pour la renommer, changer son adresse, régler son accès, la traduire, la définir comme page d’accueil, la voir en ligne ou la supprimer. « Créer une nouvelle page » ouvre un formulaire qui demande tout d’un coup, au lieu de vous faire revenir plus tard. Le titre d’abord — c’est lui qui s’affichera dans le menu de votre site, et six titres courants (À propos, Services, Tarifs, Contact, FAQ, Réalisations) se posent en un clic. Puis l’adresse, c’est-à-dire la fin de l’URL : elle se remplit toute seule à partir du titre, vous pouvez la corriger, et l’écran vous montre celle qui sera réellement créée avant de créer quoi que ce soit. Elle reste modifiable ensuite. Deux cas vous sont signalés sur-le-champ : une adresse déjà réservée par une rubrique fournie avec votre site est refusée (votre page ne s’ouvrirait jamais), et une adresse déjà utilisée par une de vos pages vous est signalée — la nouvelle sera créée à une adresse voisine, à moins que vous n’en choisissiez une vous-même. La page démarre avec un titre et un paragraphe (le pied de page est celui du site, commun à toutes les pages) : vous la composez ensuite dans l’éditeur. Elle arrive en brouillon — rien n’apparaît en ligne tant que vous ne l’avez pas publiée, vous la préparez donc tranquillement. « Traduire » dit, langue par langue, où en est chaque traduction : « À jour », « À retraduire » quand la page a changé depuis (version en ligne, titre ou référencement ; le brouillon si elle n’est pas publiée), « État inconnu » pour une traduction faite avant cette indication. Le menu de la ligne nomme les langues à retraduire. Un rôle en lecture seule ouvre « Paramètres de la page » pour consulter l’historique, sans rien modifier. ## Le menu : automatique ou personnalisé Par défaut, le menu est AUTOMATIQUE : il liste vos pages publiées et ajoute tout seul les rubriques de vos modules actifs (blog, boutique, réservation, formations, événements, forum, aide…) dès qu’il y a du contenu à montrer. Vous n’avez rien à faire. Vous pouvez aussi passer en menu PERSONNALISÉ (« Mon site › Navigation ») : vous choisissez l’ordre des entrées, ajoutez des liens externes, regroupez des entrées dans un sous-menu déroulant, et posez un bouton d’action mis en avant (« Nous contacter », « Réserver »…). ## En-tête et pied de page L’en-tête affiche votre logo (ou le nom de votre société) et le menu. Le pied de page peut porter un slogan, des colonnes de liens et une mention de copyright. Les mentions légales et le lien de signalement y restent toujours présents (obligation légale). ## Masquer une page du menu Une page peut être « atteignable par lien mais masquée du menu » : elle n’apparaît pas dans la navigation, mais reste accessible à qui possède son adresse. C’est pratique pour une page de remerciement, une offre spéciale ou une page que vous liez vous-même. Ce réglage est distinct de la confidentialité (code / membres), qui, elle, empêche l’accès. ## Bon à savoir - Les rubriques d’un module non souscrit ne s’affichent jamais : pas de lien mort. - Une page dépubliée disparaît automatiquement du menu. - Les pages des apps installées (Mon site › Apps) entrent dans le menu automatique dès qu’elles sont activées ; la case « Pages des apps installées » de l’éditeur de menu permet de les en retirer. - Publier une modification est immédiat ; dans l’éditeur, vous pouvez toujours annuler (Ctrl+Z). --- ## Sondages, formulaires et QCM sur votre site ## À quoi ça sert Le bloc « Sondage » vous permet de poser des questions directement sur votre site et de collecter les réponses. C’est utile pour un sondage de satisfaction, un vote, un choix à faire (menu, créneau, option), un petit questionnaire (QCM), ou simplement prendre la température auprès de votre communauté. ## Créer un sondage Depuis « Mon site › Sondages », vous composez vos questions. Chaque question a un type : choix unique (une seule réponse), choix multiples (plusieurs réponses), note de 1 à 5, ou texte libre — et peut être marquée obligatoire. Vous pouvez ajouter un texte d’introduction, et programmer une clôture automatique (date et heure) : passé l’échéance, le sondage n’accepte plus de réponses sans que vous ayez à y penser. Par défaut, chaque personne ne participe qu’une fois. Décochez « Une seule participation par personne » pour autoriser plusieurs réponses — le bon réglage pour un formulaire d’inscription (une réponse par créneau), une prise de commande ou une boîte à idées. Chaque sondage a sa PROPRE PAGE sur votre site, aux couleurs de votre marque : le bouton « Lien » de la liste copie son adresse, à partager par e-mail, réseaux sociaux ou QR code — vos visiteurs répondent directement, sans compte. Vous pouvez aussi l’afficher sur une page du site en ajoutant le bloc « Sondage » dans l’éditeur ; par défaut, le bloc montre votre dernier sondage ouvert. ## Qui a répondu ? L’identité, au choix du répondant Les réponses sont anonymes par défaut. Mais si le visiteur est connecté à son compte membre de votre site, une case en haut du formulaire lui propose de JOINDRE SON IDENTITÉ à sa réponse — c’est son choix, jamais le vôtre. Case cochée, vous voyez son nom et son e-mail dans les résultats et l’export ; décochée, sa réponse reste anonyme comme les autres. Idéal pour les inscriptions : la personne se signale d’elle-même, sans re-taper son nom dans un champ texte. ## Voir les résultats : synthèse ou réponse par réponse Le bouton « Résultats » ouvre deux vues. « Synthèse » agrège tout : nombre de réponses, répartition par option en pourcentage, moyenne des notes, liste des textes libres — la bonne vue pour un sondage d’opinion. « Réponses » montre chaque participation séparément (date, identité si le répondant l’a jointe, et toutes ses réponses) — la bonne vue pour une inscription ou une commande, où chaque réponse est un dossier à traiter, pas une statistique. Le bouton « Exporter (CSV) » télécharge les réponses individuelles pour les retravailler dans un tableur ; les colonnes Participant et E-mail n’apparaissent que si au moins un répondant a joint son identité. Vous pouvez aussi choisir d’afficher publiquement les résultats agrégés (en barres) — sur la page du sondage, ils n’apparaissent qu’après participation ou clôture ; les textes libres, eux, ne sont jamais montrés en public. ## Sondage, formulaire de contact ou avis ? Le SONDAGE recueille des réponses à des questions que vous posez. Le bloc « Contact » envoie un message qui arrive dans vos formulaires reçus (nom, e-mail, message) ; le bloc « Formulaire CRM » fait la même chose ET crée (ou complète) une fiche contact dans votre CRM. Le bloc « Avis clients » recueille des notes et commentaires que vous modérez. Choisissez selon le besoin : répondre à vos questions (sondage), vous écrire (contact ou formulaire CRM), ou donner un avis sur vous (avis). ## Bon à savoir - En participation unique (le défaut), un même visiteur ne peut voter qu’une fois ; un membre connecté est reconnu même s’il change d’appareil. - Les questions gardent un identifiant stable : vous pouvez retoucher un libellé sans perdre les réponses déjà agrégées. - Si un membre supprime son compte, l’identité qu’il avait jointe à ses réponses est effacée avec (droit à l’oubli) — les réponses elles-mêmes restent, anonymes. - Aucune donnée n’est envoyée à l’extérieur : tout reste chez vous. --- ## Communauté et membres de votre site ## Les comptes membres Votre site public peut proposer à vos visiteurs de créer un compte membre (distinct de vos utilisateurs internes de l’administration). Un membre se connecte sur votre site, accède à son espace personnel, et peut voir du contenu réservé ou participer à la communauté. Tout se gère dans « Mon site › Membres ». Vous décidez comment on devient membre : inscriptions OUVERTES (n’importe qui crée un compte), sur INVITATION seulement (vous envoyez les invitations par e-mail), ou FERMÉES (aucun nouveau compte). Vous pouvez aussi exiger la vérification de l’adresse e-mail. ## Le forum Votre site peut porter un forum (à l’adresse /forum) : des catégories que vous créez dans « Mon site › Communauté › Forum », des sujets ouverts par vos membres connectés, et des réponses en texte simple. Créer la première catégorie SUFFIT à ouvrir le forum — il apparaît alors dans la navigation automatique du site ; sans catégorie (ou comptes membres désactivés), il n’existe nulle part. La lecture est ouverte à tous, écrire exige un compte membre. Les messages se publient immédiatement ; vous êtes notifié de chaque nouveau sujet ou réponse et vous modérez a posteriori : épingler ou verrouiller un sujet, supprimer un message ou un sujet entier. À la suppression d’un compte membre, ses messages restent lisibles mais son nom devient « Ancien membre » (sa vie privée part avec le compte). ## Le fil communautaire Le bloc « Communauté » affiche un fil où vos membres connectés publient des messages, visibles des autres membres : un mini-espace d’échange autour de votre activité (annonces, entraide, discussions). Seul le nom d’affichage du membre est montré — jamais son adresse e-mail. ## Le contenu réservé Le bloc « Contenu réservé » n’affiche son contenu qu’aux membres connectés : le texte réservé n’est jamais envoyé à un visiteur anonyme. Vous proposez ainsi des ressources ou informations exclusives à votre communauté. Avec les adhésions payantes, vous pouvez même réserver un contenu aux seuls adhérents à jour de cotisation. ## Modération : vos responsabilités Vous êtes responsable de ce que publient vos membres. Depuis « Mon site › Membres », vous modérez les messages du fil (masquer / supprimer), bloquez un membre (ses sessions sont coupées immédiatement), organisez vos membres en groupes, et pouvez exporter ou supprimer les données d’un membre (droits RGPD). ## Si vous fermez les comptes Si vous désactivez les comptes membres, les blocs Communauté et Contenu réservé sont automatiquement masqués côté public, et les invitations à s’inscrire disparaissent. L’espace « Mon compte » d’un membre reste toutefois accessible, pour qu’il puisse récupérer ou effacer ses données. --- ## Statistiques : d’où viennent vos visiteurs ## Ce que vous voyez La page « Mon site › Statistiques » montre la fréquentation de votre site public : le nombre de visites, le nombre de visiteurs uniques par jour, les pages les plus vues, et les SOURCES — c’est-à-dire d’où viennent vos visiteurs. Vous choisissez la période (7, 30 ou 90 jours). ## Qu’est-ce qu’une « source » (référent) ? Quand un internaute arrive sur votre site en cliquant depuis un autre site — un moteur de recherche, un réseau social, un lien sur un blog, une newsletter… — ce site d’origine est le « référent ». Capibara le détecte à la page d’ENTRÉE (la première page vue de la visite) et le range dans vos sources. Vous voyez ainsi si vos visiteurs viennent de Google, de Facebook, d’une newsletter, etc. Un internaute qui tape directement votre adresse, ou arrive sans référent identifiable, est compté en « accès direct ». ## Faire monter vos sources - Partagez votre adresse sur vos réseaux sociaux et votre fiche d’établissement. - Renseignez le référencement (SEO) de vos pages pour apparaître dans les moteurs de recherche. - Reliez un domaine personnalisé (Pro/Business) pour une adresse plus mémorisable. ## Respect de la vie privée (RGPD) Les statistiques sont mesurées SANS cookie et sans suivi individuel : aucune bannière de consentement n’est nécessaire. Capibara ne stocke ni votre adresse IP ni l’identité des visiteurs — uniquement des compteurs agrégés (visites, estimation des visiteurs uniques du jour, pages et référents), calculés de façon anonyme. C’est un choix assumé : vous obtenez l’essentiel sans pister personne. --- ## Quelle sera l’adresse de mon site ? Votre site est publié à l’adresse votre-societe.capibara.fr, que vous choisissez à l’inscription (la disponibilité est vérifiée en temps réel, et l’adresse est générée automatiquement si vous la laissez vide). C’est l’adresse à communiquer à vos clients. Avec les forfaits Pro et Business, vous pouvez brancher votre propre nom de domaine (par exemple monentreprise.com) à la place — voir plus bas. --- ## Contacter le support Capibara ## Tickets Depuis **/aide/contact**, ouvrez un ticket. Vous recevez les réponses par e-mail et dans **/mes-tickets**. ## Délais de réponse - **Business** : réponse prioritaire sous quelques heures (ouvré). - **Pro** : réponse sous 24 h ouvrées. - **Free** : best-effort. ## Live chat Le widget de chat en bas à droite est disponible pendant les heures ouvrées pour les forfaits payants. --- # Documentation développeur --- ## Démarrer : votre première app, de zéro à la publication ## Ce que vous allez construire Une **app Capibara** ajoute des écrans, des widgets, des panneaux, des tâches ou des blocs de site aux organisations qui l'installent. Elle se décrit dans un fichier unique, `add-on.json` (le **manifeste**), et se distribue par le marketplace. Vous n'avez jamais besoin du code source de Capibara. Trois façons de faire tourner une app, combinables : | Façon | Ce que vous écrivez | Où ça tourne | |---|---|---| | **Déclaratif** | le manifeste seul (un widget `template`) | Capibara collecte et rend tout | | **Code hébergé** (`main`) | du TypeScript `defineApp` qui renvoie du [Kit](/dev/docs/kit) | dans le bac à sable Capibara, sans serveur à gérer | | **Backend externe** (`backend.url`) | le même `defineApp`, servi par votre serveur | chez vous, requêtes signées | Dans ce tutoriel vous construisez **« Ma météo »** : d'abord un widget météo sur l'accueil des organisations, **sans une ligne de code** (15 minutes), publié sur le marketplace ; puis vous refaites le même chemin avec la CLI ; puis vous ajoutez une **page** avec du code hébergé. Le widget déclaratif est exactement celui de l'app « Time » (Night Plugin's), déjà publiée sur le marketplace. --- ## Avant de commencer - Un compte Capibara, et **au moins une organisation dont vous êtes propriétaire** : c'est sur elle que vous installerez l'app en test. - Un forfait **Pro ou Business** sur cette organisation : le portail développeur est réservé aux comptes Pro+ (un compte uniquement Gratuit voit un écran qui propose de passer à Pro). - Pour les parties 2 et 3 : **Node.js 18 ou plus** sur votre machine. Le portail est sur `developer.capibara.fr` (documentation publique, bouton « Se connecter ») ; une fois connecté, vous travaillez sur `capibara.fr/dev`. --- ## Partie 1 — Un widget météo sans code (depuis le portail) ### 1. Créer votre compte développeur Sur `/dev`, un formulaire vous demande un **nom public** (2 à 80 caractères) — celui qui apparaît sur vos apps et sur votre page du marketplace. Un **slug** en est dérivé (minuscules, tirets) : vous le retrouverez dans le manifeste (`author.devAccountSlug`). Un compte Capibara n'a qu'un compte développeur ; recréer renvoie le vôtre. ### 2. Créer l'app Depuis le tableau de bord, **« Nouvelle app »** ouvre un assistant en trois écrans : 1. **Identité** — le nom (« Ma météo »), l'identifiant proposé automatiquement (`ma-meteo` : kebab-case, 3 à 50 caractères, **immuable**, unique sur toute la plateforme — `time` est déjà pris) et la catégorie (`productivity`). 2. **Point de départ** — choisissez **« Manifeste seul »** : aucun code n'est généré, vous allez écrire le manifeste vous-même. 3. **Récapitulatif** — créer. Vous arrivez sur la page de l'app. Sa barre latérale regroupe ses sections : **Construire** (Général, Manifeste, Code, Studio), **Tester & suivre** (Tests, Journal, Données), **Publier** (Versions, Distribution, Support), **Intégrations** (Backend & webhooks). La section Général tient une checklist « Prochaines étapes » qui se coche au fil du tutoriel. ### 3. Écrire le manifeste Section **Manifeste**, onglet **JSON** : collez ceci en remplaçant `votre-slug` par votre slug de développeur (l'onglet Formulaire montre les mêmes champs, les deux éditent le même objet). ```json { "key": "ma-meteo", "name": "Ma météo", "version": "0.1.0", "author": { "name": "Votre nom", "devAccountSlug": "votre-slug" }, "compatibility": { "colibri": ">=1.0" }, "capabilities": [ "ui.widget", "http.fetch:geocoding-api.open-meteo.com", "http.fetch:api.open-meteo.com" ], "contributes": { "widgets": [ { "key": "meteo", "title": "Météo", "kind": "declarative", "template": "weather", "config": [ { "key": "address", "label": "Votre ville ou adresse", "type": "text", "placeholder": "Paris", "required": true } ], "minHeight": 260 } ] }, "pricing": { "model": "free" }, "i18n": { "fr": "La météo de votre ville sur l'accueil, propulsée par Open-Meteo.", "en": "Your city's weather on the dashboard, powered by Open-Meteo." } } ``` Ce que chaque bloc dit à la plateforme : - `key`, `name`, `version` — l'identité. La `key` doit être **celle du projet** ; la `version` est un semver, chaque changement publié en prend un nouveau. - `author.devAccountSlug` — votre slug, exactement (le portail refuse un manifeste signé par un autre développeur). - `compatibility.colibri` — la version de plateforme visée (`>=1.0` aujourd'hui). `modules` (optionnel) liste les modules Capibara requis. - `capabilities` — ce que l'app a le droit de faire. `ui.widget` pour contribuer un widget d'accueil ; **`http.fetch:`** pour chaque hôte appelé : le template `weather` appelle les deux API Open-Meteo, elles doivent être déclarées, sinon le validateur vous les liste comme manquantes. - `contributes.widgets[]` — le widget : `kind: "declarative"` + `template: "weather"`, et un champ `config` que **l'utilisateur** remplit sur son accueil (sa ville). Capibara géocode l'adresse, interroge la météo et dessine le widget à sa charte. Vous ne collectez ni ne stockez rien. - `pricing` — gratuite ici. Voir [Revenus](/dev/docs/revenus) pour une app payante. - `i18n.fr` / `i18n.en` — l'accroche d'une phrase (les deux sont obligatoires ; le marketplace affiche le français). Cliquez **« Enregistrer la version (brouillon) »**. Le manifeste est validé en direct avec les mêmes règles que le serveur ; une erreur nomme le champ fautif. La version `0.1.0` apparaît dans **Versions**, en brouillon. > Un widget déclaratif n'a pas de code : la section Code reste vide, c'est > normal. La référence complète des champs est dans [Le manifeste](/dev/docs/manifeste), > et [Widgets déclaratifs](/dev/docs/widgets-declaratifs) décrit les templates > `weather`, `kpi` et `list`. ### 4. Installer en test et voir le widget Section **Tests** : choisissez une organisation dont vous êtes propriétaire, puis **« Installer en test »**. L'app est posée sur cette organisation en mode test (sa fiche n'est visible de personne d'autre, elle n'est pas comptée dans les installations). Dans l'organisation : 1. **Accueil** › **« Personnaliser »** › **« Ajouter un widget »** › rubrique **Apps** › « Météo · Ma météo ». 2. Le widget affiche son petit formulaire : saisissez une ville, **« Enregistrer »**. 3. La météo s'affiche (température, ressenti, vent, humidité, ciel, heure locale). Le bouton **« Modifier »** change la ville. L'app apparaît aussi dans **Modules › Apps** de l'organisation, avec un encart « installation de test ». Le **Journal** du portail reste vide pour un widget déclaratif : aucun code ne s'exécute, la plateforme fait la collecte. ### 5. Publier sur le marketplace Section **Versions** › sur la `0.1.0`, **« Soumettre à la review »**. Le manifeste est revalidé, un build automatisé tourne (ici, sans code, il ne fait que valider), puis la version passe en `REVIEW`. Une personne de l'équipe Capibara la relit — les délais et les motifs de refus courants sont dans [Publication et review](/dev/docs/publication). Approuvée, elle passe en `APPROVED` : **« Publier »** la rend installable partout. Section **Distribution** : la **fiche marketplace** a été créée à la première publication (accroche reprise de `i18n.fr`, catégorie du projet). Complétez la description et ajoutez des captures, puis **« Enregistrer la fiche »**. Votre app est visible sur `/marketplace/ma-meteo` et dans le catalogue **Modules › Apps** de chaque organisation. Une adresse de support (`support.email` dans le manifeste) est fortement conseillée : une organisation qui installe votre app doit pouvoir vous écrire. Vous venez de publier une app Capibara sans écrire une ligne de code. --- ## Partie 2 — La même app avec la CLI La CLI `capibara` est la voie des développeurs : un dossier local lié au projet du portail par une **clé de projet**, des déploiements de test à chaque sauvegarde, le journal en direct, la soumission en review — sans tunnel, sans serveur. Référence complète : [La CLI capibara](/dev/docs/cli). ### 1. Installer la CLI et préparer le dossier ```bash npm i -g @capibara-dev/cli # Node.js 18+ ; ou npx @capibara-dev/cli … mkdir ma-meteo && cd ma-meteo ``` Créez `add-on.json` avec le manifeste de la partie 1. ### 2. Lier le dossier au projet Dans le portail, section **Code** › carte **« Clé de projet & CLI »** › **« Générer une clé »** (donnez-lui un libellé : « Portable de Léa »). La clé `cpk_…` s'affiche **une seule fois** ; elle n'ouvre que ce projet, jamais votre compte. ```bash capibara login --key cpk_… ``` La CLI vérifie la clé, l'enregistre dans `.capibara/key` (mode 600, ajouté au `.gitignore` — ne la committez jamais), écrit `capibara.json` (`app`, `manifest`) et vous liste les organisations de test possibles. Si le manifeste porte encore `"devAccountSlug": "votre-slug"`, elle le remplace par votre slug. ### 3. Déployer en test ```bash capibara dev --org --once ``` `dev` envoie le manifeste, crée (ou met à jour) la version brouillon, pose l'installation de test et affiche son adresse. Comme il n'y a pas de code, la CLI note « aucun code hébergé » : c'est attendu. Sans `--once`, `dev` reste ouvert et **redéploie à chaque sauvegarde** du dossier, en suivant le journal. ```bash capibara status # version, canal, installations de test capibara install --org # poser une installation de test sans redéployer capibara install --remove --org # la retirer (ses données sont purgées) ``` ### 4. Publier ```bash capibara deploy # crée la version du manifeste et l'envoie en review capibara deploy --publish # une fois approuvée : publication ``` Le portail et la CLI passent par les **mêmes** fonctions : ce que vous faites d'un côté se voit de l'autre (section Versions, Journal, Tests). --- ## Partie 3 — Ajouter une page avec du code hébergé Un widget déclaratif s'arrête au template. Pour un écran sur mesure, vous écrivez du **code hébergé** : un `defineApp` en TypeScript qui renvoie des écrans en [Kit](/dev/docs/kit) (des composants décrits en JSON, dessinés par Capibara), exécuté dans le bac à sable de la plateforme. ### 1. Partir du starter « Page simple » Créez une **nouvelle app** dans le portail (par exemple `ma-meteo-page`) en choisissant cette fois le starter **« Page simple »** : le projet reçoit une version `0.1.0` avec le manifeste, une page, un widget, un test et l'**Édition rapide** (section Code) déjà remplie. Vous pouvez tout faire depuis le portail — mais faisons-le en local : ```bash mkdir ma-meteo-page && cd ma-meteo-page capibara init --template page --app ma-meteo-page # même code que le starter du portail npm install capibara login --key cpk_… # la clé de CE projet capibara dev --org ``` En quelques secondes, l'organisation de test a une entrée de menu « Ma Meteo Page » (une page rendue par le Kit, un compteur dans le KV) et un widget « Compteur ». Modifiez `src/index.ts`, enregistrez : la version est rebundlée, l'isolate rechargé, le journal défile. Le starter a écrit `add-on.json` avec `main: "src/index.ts"`, les capabilities `ui.menu`, `ui.widget`, `storage.tenant.ro`, `storage.tenant.rw`, une entrée de menu `view: "home"` et un widget `kind: "kit"`. ### 2. Y mettre la météo Ajoutez au manifeste les deux hôtes Open-Meteo dans `capabilities`, et un réglage saisi par l'administrateur de l'organisation : ```json "capabilities": ["ui.menu", "ui.widget", "http.fetch:geocoding-api.open-meteo.com", "http.fetch:api.open-meteo.com"], "settings": { "fields": [{ "key": "city", "label": "Ville par défaut", "type": "text", "placeholder": "Paris" }] } ``` Puis remplacez `src/index.ts` par : ```ts import { defineApp, ui, type AppContext, type KitNode } from '@capibara-dev/sdk'; /** Le corps d'un fetch sortant arrive en base64 : on le décode en UTF-8. */ function b64ToUtf8(b64: string): string { const bin = atob(b64); const bytes = new Uint8Array(bin.length); for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i); return new TextDecoder().decode(bytes); } /** ctx.fetch = HTTP sortant BORNÉ : l'hôte doit être déclaré http.fetch: au manifeste. */ async function fetchJson(ctx: AppContext, url: string): Promise { const res = await ctx.fetch(url); if (res.status !== 200) throw new Error('réponse ' + res.status); return JSON.parse(b64ToUtf8(res.bodyBase64)) as unknown; } async function weather(ctx: AppContext, city: string): Promise { const geo = await fetchJson(ctx, 'https://geocoding-api.open-meteo.com/v1/search?name=' + encodeURIComponent(city) + '&count=1&language=fr&format=json') as { results?: Array<{ latitude: number; longitude: number; name?: string }>; }; const hit = geo.results?.[0]; if (!hit) return ui.note({ tone: 'warning', text: 'Ville « ' + city + ' » introuvable.' }); const fore = await fetchJson(ctx, 'https://api.open-meteo.com/v1/forecast?latitude=' + hit.latitude + '&longitude=' + hit.longitude + '¤t=temperature_2m,wind_speed_10m&timezone=auto') as { current?: { temperature_2m?: number; wind_speed_10m?: number }; }; const t = fore.current?.temperature_2m; if (typeof t !== 'number') return ui.note({ tone: 'warning', text: 'Météo indisponible pour le moment.' }); return ui.kpi({ label: hit.name ?? city, value: Math.round(t) + '°C', hint: 'Vent ' + Math.round(fore.current?.wind_speed_10m ?? 0) + ' km/h', icon: 'globe' }); } /** Le réglage « city » déclaré au manifeste arrive dans ctx.install.config (saisi par un admin de l'organisation). */ function cityOf(ctx: AppContext): string { const c = ctx.install.config.city; return typeof c === 'string' && c.trim() ? c.trim() : 'Paris'; } export default defineApp({ pages: { home: { async render({ ctx }) { return ui.doc( ui.stack({ gap: 'lg' }, [ ui.pageHeader({ title: 'Météo', subtitle: 'Données Open-Meteo, ville réglée par votre organisation.' }), ui.card({ title: 'Conditions actuelles' }, [await weather(ctx, cityOf(ctx))]), ]), { title: 'Météo' }, ); }, }, }, widgets: { compteur: async ({ ctx }) => weather(ctx, cityOf(ctx)), }, }); ``` Enregistrez : `capibara dev` redéploie, la page « Météo » et le widget montrent la météo de la ville réglée par l'organisation (Modules › Apps › votre app › Réglages). `capibara logs --follow` suit les exécutions ; `npm test` lance le test du starter sur le harnais officiel (`@capibara-dev/sdk/testing`), qui exécute votre `defineApp` en local avec un faux `ctx`. Pour aller plus loin, l'app **« Météo (exemple) »** (téléchargeable depuis l'[index de la documentation](/dev/docs)) reprend tout cela avec des actions, un formulaire de réglages, une collection de villes favorites, un bloc et une page pour le site public — commentée ligne à ligne. --- ## Le cycle de vie d'une version ``` DRAFT ──submit──▶ REVIEW ──approuvé──▶ APPROVED ──publish──▶ PUBLISHED ▲ │ └────────────────REJECTED (avec notes) ◀──┘ ``` - **DRAFT** — votre brouillon, enregistrable autant de fois que nécessaire. - **REVIEW** — manifeste revalidé, build automatisé (manifeste, dépendances du dépôt lié, scan des sources ; le code envoyé par la CLI est déjà bundlé et scanné), puis relecture humaine. - **APPROVED** — publiable quand vous le décidez. **PUBLISHED** — installable. **REJECTED** — refusée avec des notes ; corrigez et resoumettez. Une version en `REVIEW`, `APPROVED` ou `PUBLISHED` ne change plus : incrémentez `version` et enregistrez un nouveau brouillon — la section Manifeste vous le propose pré-rempli depuis la dernière version. --- ## Checklist de première publication - [ ] Le manifeste valide sans erreur. - [ ] `permissions` et `capabilities` sont **minimales** — seulement ce que l'app utilise ([Scopes et consentement](/dev/docs/permissions)). - [ ] `i18n.fr` et `i18n.en` décrivent l'app en une phrase claire. - [ ] `support.email` est renseigné. - [ ] Le tarif (`pricing`) correspond à ce que vous annoncez. - [ ] Vous avez testé sur une organisation : installation, utilisation, désinstallation. - [ ] Si l'app est payante, l'onboarding Stripe Connect est fait depuis **Revenus** ([Revenus et rev-share](/dev/docs/revenus)). --- ## Et ensuite ? - [La CLI capibara](/dev/docs/cli) — toutes les commandes, les starters, les fichiers du projet. - [Le manifeste](/dev/docs/manifeste) — chaque champ en détail. - [Le Kit](/dev/docs/kit) et le Kit Studio — les composants de vos écrans. - [Le runtime](/dev/docs/runtime) — `defineApp`, `ctx`, actions, événements, planifications. - [Façades](/dev/docs/facades) et [Scopes](/dev/docs/permissions) — lire et écrire les données de l'organisation (CRM, facturation, boutique…). - [Backend externe](/dev/docs/backend-externe) — héberger la logique chez vous. - [Publication et review](/dev/docs/publication) · [Revenus](/dev/docs/revenus). - [Utiliser cette doc avec votre IA](/dev/docs/llm) — si vous construisez avec un assistant. --- ## La CLI capibara ## Ce que fait la CLI Une app Capibara se développe **comme un bot Discord** : votre code tourne chez Capibara, la CLI l'y envoie. Pas de tunnel, pas d'émulateur, pas de serveur local à exposer — `capibara dev` bundle vos sources sur la plateforme, les pose sur **votre organisation de test** dans la vraie sandbox (un isolate dédié à votre version de test) et vous rend le journal en direct. Chaque sauvegarde redéploie en quelques secondes. ```bash capibara init --template page --app ma-premiere-app # un projet complet capibara login --key cpk_… # la clé de projet capibara dev --org mon-organisation # deploy-on-save + journal capibara deploy # version → review capibara deploy --publish # publication, une fois approuvée ``` --- ## Installation ```bash npm install -D @capibara-dev/cli @capibara-dev/sdk # registre npm public npx capibara --help ``` Zéro dépendance, Node ≥ 18. Sans accès au registre npm, le tarball servi par le portail fait la même chose : ```bash curl -O https://capibara.fr/dev-cli/capibara-dev-cli-0.1.2.tgz npm install -D ./capibara-dev-cli-0.1.2.tgz ``` Les starters installent aussi le [SDK](/dev/docs/sdk) (types + harnais de test). --- ## 1. Le projet et sa clé 1. Créez le projet dans le portail (`/dev`) : son identifiant `key` est immuable, c'est celui que vous donnerez à `capibara init --app`. 2. Sur la page de l'app, section **Code**, carte « Clé de projet & CLI » : **Générer une clé**. La clé `cpk_…` n'est affichée **qu'une fois** ; copiez-la dans `capibara login`. Une clé de projet est **bornée au projet** : ce n'est ni une clé de compte, ni un accès aux données d'une organisation. Elle est stockée hachée, révocable à tout moment (jusqu'à 10 clés par projet), et chaque usage est journalisé (dernier usage, compteur). Les installations de test qu'elle pose ne peuvent viser qu'une organisation dont **vous** (le créateur de la clé) êtes propriétaire. --- ## 2. `capibara init` — un projet complet depuis un starter ```bash capibara init --template page --app ma-premiere-app [--name "Ma première app"] [--dev ] [--dir mon-app] ``` | Starter | Contenu | |---|---| | `page` (défaut) | Une page d'app (entrée de menu `view`) + un widget d'accueil, un compteur en KV, deux actions. | | `panel` | Un panneau sur les fiches contact/société du CRM (lecture par façade, scope feuille minimal). | | `cron` | Une planification (`schedules`) + un widget qui affiche la dernière exécution. | | `external` | Une app hybride : page embarquée (`embedUrl`) + `server/webhook.ts` avec `createServerHandler` (backend chez vous). | | `blank` | Le squelette minimal (`defineApp` vide + manifeste). | Chaque starter crée `add-on.json`, `capibara.json`, `src/index.ts`, un `package.json` (SDK + CLI en devDependencies, `npm test` avec le harnais), `tsconfig.json`, `.gitignore` et un README. Si vous n'indiquez pas `--dev`, `author.devAccountSlug` est complété par `capibara login`. --- ## 3. `capibara login` — lier le dossier au projet ```bash capibara login --key cpk_… [--url https://…] ``` La CLI vérifie la clé auprès de la plateforme, l'enregistre dans `.capibara/key` (mode 600, ajouté au `.gitignore`), aligne `capibara.json` (`app`, `baseUrl` si vous visez une autre instance) et complète `author.devAccountSlug` dans le manifeste. En CI ou dans un conteneur, exportez plutôt `CAPIBARA_PROJECT_KEY`. --- ## 4. `capibara dev` — développer en deploy-on-save ```bash capibara dev --org mon-organisation # --once : un seul déploiement ; --no-logs : sans le journal ``` À chaque sauvegarde : 1. la CLI envoie le manifeste et vos sources (`.ts`, `.tsx`, `.js`, `.mjs`, `.json` — hors `node_modules`, `dist`, `tests`, `server`, fichiers de test et d'outillage ; 80 fichiers, 1,5 Mo au total, 512 Ko par fichier) ; 2. la plateforme **valide le manifeste** (mêmes règles que le portail — la clé et `author.devAccountSlug` doivent être les vôtres), **scanne les sources** (secrets, motifs interdits : refus avant toute construction), **bundle** avec son propre bundler (imports relatifs + `@capibara-dev/sdk` uniquement) et enregistre le bundle sur la version **brouillon** du manifeste (créée si besoin) ; 3. elle pose (ou met à jour) l'**installation de test** sur l'organisation choisie — même consentement, même compte de service qu'une installation réelle, bandeau « version de test », jamais comptée ni listée ; 4. l'isolate de test (`@`, servi à côté de l'app publiée) recharge le nouveau bundle en une dizaine de secondes — **la CLI attend qu'il soit monté avec ce bundle** (jusqu'à 60 s) et l'écrit : `OK Isolate meteo@cmt… monté et à jour (12 s)`. Puis la CLI affiche le **journal** en direct : chaque interaction (page, action, événement, planification, HTTP) avec son statut, sa latence, l'erreur éventuelle et vos `ctx.log`. Les erreurs de validation du Kit renvoyées par la plateforme y apparaissent en clair. ### Si l'isolate ne se monte pas Trois étapes séparent votre déploiement de son exécution : le worker de la plateforme écrit la configuration du runtime, le conteneur du runtime la télécharge et se recharge, le routeur sert votre route. Quand l'une bloque, la CLI (et `capibara status`) nomme l'étape avec le remède, et le journal dit la même chose au lieu d'un « HTTP 404 » muet : | Message | Ce que ça veut dire | |---|---| | *configuration pas régénérée* | Le job `addon-runtime-config` du worker n'a pas encore tourné (il est relancé à chaque déploiement, à chaque exécution en échec et toutes les 5 minutes). S'il ne tourne jamais, le worker de l'instance n'est pas démarré ou pas à jour. | | *pas chargé par le conteneur* | La configuration contient votre route mais le conteneur `addon-runtime` ne l'a pas rechargée (bundle introuvable, SHA-256 refusé, API interne injoignable). | | *bundle antérieur* | L'isolate tourne encore sur le bundle précédent : rechargement en cours (~10–20 s). | | *runtime injoignable* | Le conteneur redémarre (normal pendant un rechargement) ou n'est pas démarré. | Rien de tout cela ne vient de votre code : un exécutant de l'instance (`docker compose logs worker addon-runtime`) règle le point. Vos erreurs à vous — Kit invalide, exception dans un handler — restent dans le journal, sous leur vrai nom. Une version en `REVIEW`, `APPROVED` ou `PUBLISHED` n'est jamais réécrite : la CLI répond `version_locked` — incrémentez `version` dans le manifeste et relancez. Une version `REJECTED` est reprise comme un brouillon. --- ## 5. `capibara deploy` — créer et publier une version ```bash capibara deploy # bundle + version du manifeste → REVIEW (build automatisé + review humaine) capibara deploy --version 1.2.0 # impose le semver capibara deploy --publish # publie une version APPROVED (ou la dernière approuvée) capibara publish # alias de deploy --publish ``` Le cycle reste celui de [Publication et review](/dev/docs/publication) : rien ne se publie sans approbation, et la publication reste un geste explicite. `capibara status` montre l'état de chaque version. --- ## Les autres commandes | Commande | Ce qu'elle fait | |---|---| | `capibara status [--json]` | Projet, clé utilisée, versions (canal, bundle), installations de test **avec l'état de leur isolate** (monté / bundle antérieur / pas chargé / configuration pas régénérée, et le remède), organisations cibles. | | `capibara logs [--org ] [--follow] [--limit N]` | Journal des exécutions sur vos installations de test (`--follow` = flux continu). | | `capibara install [--org ] [--version x.y.z]` | Pose une installation de test sans redéployer ; `--remove` la retire (et purge ses données). | | `capibara scopes` | Les scopes du manifeste avec leur phrase de consentement, et ce que chaque organisation de test a accordé (« manque : … » = re-consentement nécessaire). | | `capibara kit check [--surface page]` | Valide un document (ou un nœud) du Kit avec le **vrai** validateur de la plateforme : erreurs nommées, statistiques. | Options communes : `--url ` (ou `CAPIBARA_URL`), `--debug`, `--no-color`. Codes de sortie : `0` succès, `1` erreur (message + indice), `2` usage incorrect ou document du Kit invalide. --- ## Fichiers et variables | Fichier / variable | Rôle | |---|---| | `capibara.json` (committé) | `{ "app": "", "manifest": "add-on.json", "baseUrl"?: "https://…", "org"?: "" }` — `org` évite de répéter `--org`. | | `.capibara/key` (hors git) | La clé de projet, écrite par `capibara login`. | | `CAPIBARA_PROJECT_KEY` | Alternative à `.capibara/key` (CI, conteneurs). | | `CAPIBARA_URL` / `--url` | Origine de la plateforme (défaut `https://capibara.fr`). | --- ## Limites et sécurité - Le bundle est **toujours** construit par la plateforme : pas de `node_modules`, imports relatifs + `@capibara-dev/sdk` seulement. Les dossiers `tests/` et `server/` restent chez vous. - Corps d'une requête ≤ 3 Mo ; 240 appels par minute et 60 déploiements par minute par clé de projet. - Une installation de test exécute votre code hébergé (`main`) ou appelle votre [backend externe](/dev/docs/backend-externe) (`backend.url`) ; une app hybride (ni l'un ni l'autre) se teste avec son backend chez vous — `capibara status` la marque « hybride ». - Ne committez jamais `.capibara/key`. Une clé compromise se révoque depuis le portail (section Code) — les installations de test restent. --- ## Sans la CLI Tout ce que fait la CLI passe par l'[API de projet](/dev/docs/api-publique) (`/api/public/v1/project/…`, `Authorization: Bearer cpk_…`) : `curl` ou n'importe quel client HTTP fonctionne. Le portail sait aussi tout faire **sans rien installer** : l'**Édition rapide** de la section Code est un éditeur (Monaco, avec les types du SDK `@capibara-dev/sdk` chargés — complétion et erreurs en direct) sur les fichiers de la version en cours. « Enregistrer » crée ou met à jour le brouillon exactement comme `capibara deploy` sans `--publish` ; « Déployer » choisit l'une de vos organisations de test et suit le **même chemin que `capibara dev`** (validation, scan, bundle, installation de test, isolate rechargé). La section Tests montre l'état de l'isolate et le journal en direct ; la section Journal, l'usage par installation. Un projet créé depuis un starter de l'assistant a déjà ses fichiers dans l'Édition rapide ; un projet déployé par la CLI les y retrouve aussi (les sources accompagnent chaque version). Le dépôt Git connecté, l'installation de test depuis la fiche et le Kit Studio restent disponibles. --- ## Utiliser cette doc avec votre IA ## Pourquoi cette page Cette documentation est conçue pour être lue **par un assistant IA autant que par vous**. Chaque page existe en Markdown brut (sans mise en page, sans navigation) à une URL stable, et l'ensemble est disponible sous des formats pensés pour être collés directement dans le contexte d'un agent : vous n'avez jamais besoin d'accéder au code source de Capibara — cette documentation, plus l'[API publique](/dev/docs/api-publique), suffisent. --- ## Les URLs à connaître | URL | Contenu | Format | |---|---|---| | `/dev/llms.txt` | **Index de cette documentation** : toutes les pages, groupées par catégorie, avec un résumé d'une ligne et un lien vers chaque version brute. | `text/plain`, convention [llms.txt](https://llmstxt.org) | | `/llms.txt` | L'index **niveau plateforme** (ce qu'est Capibara, le centre d'aide utilisateur, les fiches d'apps) — il pointe vers `/dev/llms.txt`. C'est ce qu'un agent trouve en arrivant sur `capibara.fr`. | `text/plain` | | `/llms-full.txt` | **Tout, concaténé** : présentation de la plateforme, articles du centre d'aide, puis l'intégralité des pages de cette documentation, dans l'ordre de navigation du hub. | `text/plain` | | `/dev/docs/raw/` | Le Markdown brut d'une seule page (ex. `/dev/docs/raw/manifeste`). | `text/markdown` | | `/dev/docs/download` | Une archive `.zip` contenant un fichier `.md` par page. | `application/zip` | Tout cela est **public** : ni la documentation ni ces URL ne demandent de compte. Ce sont de simples réponses texte, faciles à récupérer avec `curl` ou directement depuis le navigateur de votre agent. ``` curl https://capibara.fr/dev/llms.txt curl https://capibara.fr/llms-full.txt curl https://capibara.fr/dev/docs/raw/manifeste ``` --- ## Ce que contient `/dev/llms.txt` Un index compact, dans le format standard `llms.txt` : un titre, un court résumé de la plateforme, puis une section par catégorie avec un lien vers chaque page — pratique pour qu'un agent **découvre** la documentation disponible sans la charger en entier : ``` # Capibara for Developers > Construisez des apps pour Capibara sans accès à son code source : > manifeste déclaratif, permissions consenties par le tenant, API publique, > OAuth, distribution et rev-share. ## Démarrer - [Démarrer : votre première app, de zéro à la publication](https://capibara.fr/dev/docs/raw/demarrer): … - [Utiliser cette doc avec votre IA](https://capibara.fr/dev/docs/raw/llm): … ## Référence - [Référence du manifeste add-on.json](https://capibara.fr/dev/docs/raw/manifeste): … … ``` `/llms-full.txt`, à l'inverse, ne fait aucun tri : c'est le contenu intégral — plateforme, centre d'aide et toutes les pages de ce hub, séparées par `---` —, pensé pour être collé **une seule fois** dans le contexte d'un agent qui doit ensuite répondre à des questions variées sans repartir chercher chaque page individuellement. Si le contexte de votre agent est compté, la section « Documentation développeur » seule suffit pour construire une app. --- ## Workflow conseillé 1. **Donnez `/llms-full.txt` à votre agent** en tout début de conversation (collé directement, ou récupéré via un outil de navigation web si votre agent en a un), ou `/dev/llms.txt` s'il sait aller chercher les pages lui-même. C'est la référence la plus dense : elle contient déjà le manifeste exhaustif, les capabilities, les permissions, l'OAuth complet, l'API publique et le modèle de revenus. 2. **Faites écrire le manifeste par l'agent**, puis collez-le dans l'éditeur du portail (section **Manifeste** de votre app, `/dev/addons//manifest`) — l'éditeur valide en direct avec le même schéma que le serveur : les erreurs éventuelles de l'agent sont visibles immédiatement, sans attendre une soumission en review. 3. **Itérez** : si une erreur de validation apparaît, recopiez le message exact à votre agent (les messages sont listés dans [Référence du manifeste](/dev/docs/manifeste#erreurs-de-validation-courantes)) — ils sont volontairement explicites et actionnables. 4. Pour une app à [backend externe](/dev/docs/backend-externe), demandez à votre agent d'implémenter l'appel à [l'API publique](/dev/docs/api-publique) et le flux [OAuth](/dev/docs/oauth) directement depuis les séquences `curl` fournies — elles sont écrites pour être traduites telles quelles dans n'importe quel langage. --- ## Une doc, deux lecteurs Rien dans ce hub n'est réservé à l'un ou l'autre : les pages HTML (`/dev/docs/`) et leur version brute (`/dev/docs/raw/`) partagent exactement le même contenu source — pas de version « appauvrie » pour la machine. Si un détail vous semble absent quand vous travaillez avec un agent, c'est probablement qu'il est absent tout court : signalez-le depuis `/dev/support`. --- ## Référence du manifeste add-on.json ## Le fichier add-on.json `add-on.json` est l'unique fichier de configuration d'une app Capibara. Il est validé par un schéma **strict** : tout champ de premier niveau qui n'est pas listé ci-dessous est **refusé** (pas ignoré silencieusement — la validation échoue avec la liste des clés inconnues). Ce document reflète exactement le validateur serveur ; le portail utilise le même schéma pour la complétion et la validation en direct dans l'éditeur de code. ### Champs de premier niveau | Champ | Type | Obligatoire | Contrainte | |---|---|---|---| | `key` | string | oui | `^[a-z0-9](?:[a-z0-9-]{1,48}[a-z0-9])?$` — kebab-case, 3 à 50 caractères en pratique (imposé à la création du projet). **Immuable** : doit rester identique à la `key` du projet sur toute nouvelle version. | | `name` | string | oui | 2 à 80 caractères. | | `version` | string | oui | semver strict `MAJOR.MINOR.PATCH`, avec suffixe de pré-version optionnel (`1.2.0`, `2.0.0-beta.1`). | | `main` | string | non | point d'entrée du **code hébergé** (chemin relatif du dépôt, `.ts`/`.tsx`/`.js`/`.mjs`, jamais de `..` — ex. `src/index.ts`). Le module exporte `export default defineApp({ … })` (cf. [Le runtime](/dev/docs/runtime)) ; il est bundlé automatiquement à la publication depuis votre dépôt Git (imports relatifs + `@capibara-dev/sdk`, pas de node_modules). Requis (ou `backend`) dès qu'une entrée déclare `view`, qu'un widget est `kind: "kit"`, ou que `panels`, `siteBlocks`, `sitePages`, `events`, `schedules` ou `http` sont déclarés ; requis SEUL pour `collections`, `files.private` et les moteurs. | | `backend` | objet | non | `{ url }` — **backend externe** (DV-9) : votre serveur reçoit les requêtes du protocole (écrans, actions, événements, planifications, HTTP) en POST signé et horodaté et répond du Kit (cf. [Le runtime › Backend externe](/dev/docs/runtime)). HTTPS, hôte public (jamais une IP, ni localhost, ni domaine interne). **Exclusif de `main`.** Consentement explicite de l'organisation, badge « Backend chez l'éditeur », review humaine obligatoire. | | `returnHosts` | string[] | non | domaines (minuscules, ≤ 5) vers lesquels vos liens de paiement peuvent renvoyer le client (`returnUrl` de `billing.documents.payLink` / `billing.charges.create`, cf. [Moteurs › Paiements](/dev/docs/moteurs)). Liste blanche stricte. | | `events` | string[] | non | événements de domaine livrés à `defineApp({ events })` (catalogue fermé — cf. [Webhooks](/dev/docs/webhooks)) ; requiert la capability `events.subscribe`. Max 20. | | `schedules` | objet[] | non | `[{ key, cron }]` — planifications exécutées par la plateforme (cron à 5 champs, heure de Paris, intervalle minimum selon le plan du tenant). Max 5. | | `http` | string[] | non | routes HTTP entrantes (`["/stripe-hook"]`) servies par `defineApp({ http })` sur une URL publique signée par installation. Max 5. | | `collections` | objet | non | `{ : { fields: { : "string" | "number" | "boolean" | "date" | "json" }, indexes? } }` — collections de données de l'app (`ctx.data.`), stockées chez l'organisation. Max 10 collections × 30 champs. Requiert la capability `data.collections` + `main`. Cf. [Données](/dev/docs/donnees). | | `settings` | objet | non | `{ fields: [{ key, label, type, options?, required?, placeholder?, help? }] }` — réglages saisis par un administrateur de l'organisation, lus dans `ctx.install.config` ; type `secret` = chiffré au repos, jamais réaffiché. Max 20 champs. Cf. [Données](/dev/docs/donnees). | | `author` | objet | oui | cf. [author](#author). | | `compatibility` | objet | oui | cf. [compatibility](#compatibility). | | `permissions` | string[] | non (défaut `[]`) | format `resource:action` — cf. [Permissions et consentement du tenant](/dev/docs/permissions). | | `capabilities` | string[] | non (défaut `[]`) | sous-ensemble de la liste blanche — cf. [Capabilities, bornes et erreurs](/dev/docs/capabilities). | | `contributes` | objet | non | points d'extension déclaratifs — cf. [contributes](#contributes). | | `pricing` | objet | oui | cf. [pricing](#pricing). | | `i18n` | objet | oui | cf. [i18n](#i18n). | | `support` | objet | non | cf. [support](#support). | --- ### `author` | Champ | Type | Obligatoire | Contrainte | |---|---|---|---| | `author.name` | string | oui | 1 à 80 caractères. Nom affiché. | | `author.devAccountSlug` | string | oui | 1 à 40 caractères. **Doit être exactement** le slug de votre compte développeur (affiché sur votre tableau de bord, champ « Identifiant développeur ») — sinon le serveur refuse l'enregistrement avec le message `author.devAccountSlug doit être ""`. | --- ### `compatibility` | Champ | Type | Obligatoire | Contrainte | |---|---|---|---| | `compatibility.colibri` | string | oui | non vide — plage de version de plateforme requise (ex. `">=1.0"`). | | `compatibility.modules` | string[] | non (défaut `[]`) | clés des modules qui doivent être **actifs chez le tenant** pour que l'app ait un sens (ex. `["crm"]`, `["billing-fr"]`). N'active rien tout seul : c'est une condition affichée/vérifiée, pas une activation automatique. | > **Note de nommage.** Le champ s'appelle `compatibility.colibri` (et non > `capibara`) : c'est un vestige du nom du moteur technique interne de la > plateforme. Il désigne bien la version de **Capibara** — écrivez-le tel > quel dans votre manifeste, la clé ne change pas. --- ### `permissions` Tableau de chaînes au format `resource:action`, validées par `^[a-z][a-z0-9-]*:(read|write|delete|admin)$`. Documentation complète — ressources disponibles, consentement du tenant, bonnes pratiques — dans [Permissions et consentement du tenant](/dev/docs/permissions). --- ### `capabilities` Tableau de chaînes, chacune soit dans la liste blanche fixe — `storage.tenant.ro`, `storage.tenant.rw`, `ui.block`, `ui.menu`, `ui.widget`, `ui.panel`, `ui.site`, `ui.settings`, `ai.tool`, `events.subscribe`, `data.collections`, `files.private`, `mail.send`, `notify.send`, `calendar.project`, `search.index`, `approvals.request` —, soit de la forme `http.fetch:` avec un domaine pleinement qualifié (`^http\.fetch:[a-z0-9.-]+\.[a-z]{2,}$`, ex. `http.fetch:api.example.com`). Détail de chaque capability, des bornes d'exécution et des erreurs dans [Capabilities, bornes et erreurs](/dev/docs/capabilities). Certaines exigent `main` (code hébergé) : `data.collections`, `files.private` et les cinq moteurs (`mail.send`, `notify.send`, `calendar.project`, `search.index`, `approvals.request`). --- ### `contributes` Points d'extension, tous optionnels. Deux familles : **Typées et MONTÉES dès l'installation** : `contributes.menuEntries` (max 5, capability `ui.menu` requise) — chaque entrée apparaît dans la navigation du tenant et ouvre votre page. Deux formes, **exactement une des deux** par entrée : - `view` (mode **hébergé**, recommandé) : la clé d'une page du Kit rendue par votre **code hébergé** — `defineApp({ pages: { : { render } } })`. Capibara affiche le JSON renvoyé avec ses propres composants : même look que le reste de l'application, **aucun serveur à héberger**, aucun HTML ni JavaScript à écrire. Cf. [Le runtime](/dev/docs/runtime) et [Le Kit](/dev/docs/kit). - `embedUrl` (mode **hybride**) : votre page HTTPS, hébergée chez vous, embarquée dans une iframe isolée avec un jeton de contexte signé `?capibara_token=` que votre backend résout via `GET /api/public/v1/embed-context` (cf. [API publique](/dev/docs/api-publique)). | Champ | Type | Règle | |---|---|---| | `key` | string | kebab-case, unique dans l'app, IMMUABLE (devient le segment d'URL `/apps//`). | | `label` | string | 2-40 caractères. | | `labelI18n` | objet | optionnel — `{ fr?, en?, es?, de? }` (≤ 40 caractères chacun). | | `view` | string | mode hébergé — clé kebab-case d'une page de `defineApp({ pages })` ; requiert `main`. | | `embedUrl` | string | mode hybride — **HTTPS obligatoire**, domaine public (jamais d'IP ni de localhost), ≤ 500 caractères. | | `icon` | string | optionnel — nom d'icône Lucide kebab-case (défaut : `puzzle`). | `contributes.widgets` (max 5, capability `ui.widget` requise) — un widget du tableau de bord d'accueil, trois familles : - **Kit** (recommandé) : `{ key, title (2-60), kind: "kit", config?, minHeight? }` — rendu par votre code hébergé (`defineApp({ widgets: { : { render } } })`) ; les champs `config` optionnels (`{ key, label, type?, placeholder?, required? }`) sont saisis par un admin du tenant et arrivent dans `ctx.install.config` ; - **déclaratif** : `{ key, title, kind: "declarative", template, config?, source?, minHeight? }` — **zéro code** : la plateforme collecte la donnée et rend le widget. Référence : [Widgets déclaratifs](/dev/docs/widgets-declaratifs) ; - **embed** : `{ key, title, embedUrl, minHeight? }` — votre page hébergée chez vous, même iframe isolée + jeton que les entrées de menu hybrides. Les utilisateurs du tenant ajoutent les widgets depuis « Personnaliser » sur leur accueil (rubrique Apps du sélecteur). `contributes.panels` (max 5, capability `ui.panel` requise, `main` requis) — `{ key, label (2-60), subject: "party" }` : un panneau rendu par votre code (`defineApp({ panels: { : { render } } })`) sur les **fiches contact et société** du CRM du tenant, avec `ctx.subject = { type: 'party', id }`. Il ne s'affiche qu'aux personnes qui peuvent lire la fiche. `party` est le seul sujet ouvert aujourd'hui (les fiches des autres modules viendront avec leur propre valeur de `subject`). `contributes.siteBlocks` (max 10, capability `ui.block` requise, `main` requis) — `{ key, label (2-60), summary? (≤ 140), props? }` : un **bloc du site public** de l'organisation, rendu par votre code hébergé (`defineApp({ siteBlocks: { : { render } } })`, surface `siteBlock`). L'auteur du site le pose depuis l'éditeur de page (« Ajouter » › groupe « Vos apps ») ; les champs `props` (`{ key, label, type?: "text" | "number", placeholder?, required? }`, ≤ 6) se remplissent dans l'inspecteur du bloc et arrivent dans `params` de votre handler. Sur le site public, `viewer` est toujours `null` : le visiteur (membre du site connecté ou anonyme) arrive dans `visitor` — cf. [Le runtime](/dev/docs/runtime). `contributes.sitePages` (max 5, capability `ui.site` requise, `main` requis) — `{ key, title (2-80), slug?, description? (≤ 160), noindex? }` : une **page entière du site public**, rendue par `defineApp({ sitePages: { : { render } } })` (surface `sitePage`, ≤ 500 composants). `slug` n'est qu'une adresse PROPOSÉE : l'organisation active la page et choisit son adresse dans **Mon site › Apps** (jamais un slug réservé aux pages de Capibara, jamais l'adresse d'une page existante du site — la page du site garde toujours la priorité). Les sous-chemins (`//<…>`) arrivent dans `params.path`, les paramètres d'URL dans `params.query` ; `description` et `noindex` alimentent le référencement et le sitemap. Exemple complet : ```json { "capabilities": ["ui.menu"], "contributes": { "menuEntries": [ { "key": "tableau", "label": "Tableau de bord", "labelI18n": { "en": "Dashboard" }, "embedUrl": "https://app.votre-domaine.com/capibara", "icon": "gauge" } ] } } ``` Votre page reçoit `?capibara_token=…` et s'affiche dans une iframe `sandbox` **sans** `allow-same-origin` : elle ne peut ni lire les cookies Capibara ni toucher le DOM parent — concevez-la comme une page autonome. **Encore libres (typage à l'ouverture de leur montage)** — acceptées comme tableaux libres (≤ 10 entrées chacun), enregistrées et lisibles en review, mais **pas encore montées** côté tenant : ne comptez pas dessus pour un comportement visible. | Clé | Nécessite la capability | En attendant | |---|---|---| | `settingsSections` | `ui.settings` | les réglages passent par `settings.fields` (cf. [Données](/dev/docs/donnees)) — c'est ce qu'un administrateur remplit réellement. | | `aiTools` | `ai.tool` | aucun équivalent : l'assistant IA de la plateforme n'appelle pas encore les apps. | --- ### `pricing` | Champ | Type | Règle | |---|---|---| | `pricing.model` | `'free' \| 'one_time' \| 'subscription'` | obligatoire. | | `pricing.amountEur` | number | requis et `> 0` dès que `model` ≠ `free` ; interdit (doit être absent ou 0) quand `model = free`. | | `pricing.trialDays` | integer 0–30 | autorisé **uniquement** quand `model = subscription`. Sur `one_time`, le renseigner est une erreur. | Trois combinaisons valides, aucune autre : | `model` | `amountEur` | `trialDays` | |---|---|---| | `free` | absent | interdit | | `one_time` | `> 0` requis | interdit | | `subscription` | `> 0` requis | optionnel, 0–30 | Le prix est saisi en euros ; au lancement, la conversion multi-devise au paiement est gérée par Stripe selon le pays du payeur. Le partage de revenu qui s'applique à ce prix est détaillé dans [Revenus et rev-share](/dev/docs/revenus). --- ### `i18n` | Champ | Type | Obligatoire | Contrainte | |---|---|---|---| | `i18n.fr` | string | oui | 1 à 120 caractères — la baseline utilisée comme accroche par défaut de la fiche marketplace. | | `i18n.en` | string | oui | 1 à 120 caractères. | | `i18n.es` | string | non | ≤ 120 caractères. | | `i18n.de` | string | non | ≤ 120 caractères. | `fr` et `en` sont la **baseline obligatoire** — un manifeste sans l'une des deux est invalide, même si le reste est correct. --- ### `support` | Champ | Type | Contrainte | |---|---|---| | `support.email` | string | format e-mail valide. | | `support.docsUrl` | string | URL valide (`http(s)://…`). | Non obligatoire au sens du schéma, mais **fortement attendu en review** : un app sans e-mail de support est plus difficile à faire approuver, et bloque la fonctionnalité « Contacter le développeur » que voit un tenant qui a installé votre app. --- ## Erreurs de validation courantes | Message renvoyé | Cause | Correction | |---|---|---| | `Identifiant invalide (a-z, 0-9, tirets ; 3 à 50 caractères).` | `key` ne respecte pas le format kebab-case, ou commence/finit par un tiret. | Utilisez uniquement minuscules, chiffres et tirets internes (ex. `crm-segments`). | | `Version semver invalide (ex. 1.2.0).` | `version` n'est pas au format `MAJOR.MINOR.PATCH`. | `1.0.0`, pas `v1.0` ni `1.0`. | | `Permission invalide (format resource:action).` | Une entrée de `permissions` ne suit pas `resource:action`. | `crm.contacts:read`, pas `crm.contacts.read` ni `read-crm`. | | `Scope trop large : « crm:read » donnerait tout le module…` | Une entrée de `permissions` vise un module entier au lieu d'une ressource feuille. | Prenez un scope du [catalogue](/dev/docs/permissions) : `crm.contacts:read`, `crm.opportunities:read`… | | `Scope inconnu : « … »` | Le scope n'est pas dans le catalogue (rien ne l'ouvrirait). | Consultez la liste sur [Scopes et consentement](/dev/docs/permissions). | | `Capability inconnue (ou domaine http.fetch manquant/mal formé).` | Une entrée de `capabilities` n'est ni dans la liste blanche, ni un `http.fetch:` valide. | Vérifiez l'orthographe exacte (`ui.widget`, pas `ui.widgets`) ou complétez le domaine (`http.fetch:api.example.com`, pas `http.fetch:` seul). | | `Montant > 0 requis pour une app payante.` | `pricing.model` ≠ `free` mais `amountEur` absent ou ≤ 0. | Renseignez `amountEur`. | | `Une app gratuite ne doit pas avoir de montant.` | `pricing.model = free` avec un `amountEur` > 0. | Retirez `amountEur`, ou changez `model`. | | `Les essais ne s'appliquent qu'aux abonnements.` | `trialDays` renseigné avec `model = one_time`. | Retirez `trialDays`, ou passez en `subscription`. | | `Baseline FR obligatoire` / `Baseline EN obligatoire` | `i18n.fr` ou `i18n.en` vide. | Renseignez une phrase courte dans les deux langues. | | Erreur de type « clé non reconnue » sur le manifeste | Un champ de premier niveau ne fait pas partie de la liste (le schéma est strict). | Retirez le champ, ou vérifiez l'orthographe (`compatibility`, pas `compatibilities`). | | `Le champ "key" doit rester "" (immuable).` | Le `key` du manifeste ne correspond plus à celui du projet créé sur le portail. | Remettez la `key` d'origine — pour changer d'identifiant, créez un nouveau projet. | | `author.devAccountSlug doit être "".` | `author.devAccountSlug` ne correspond pas à votre compte développeur. | Copiez exactement votre slug depuis le tableau de bord du portail. | | `La version X est déjà REVIEW/APPROVED/PUBLISHED et ne peut être modifiée. Incrémentez la version.` | Vous tentez de réenregistrer un brouillon sur un `version` déjà engagé dans le cycle. | Changez `version` (ex. `0.1.0` → `0.1.1`) avant d'enregistrer. | --- ## Trois exemples de manifestes complets Les trois passent le validateur tel quel (à `author.devAccountSlug` près, qui doit être le vôtre). ### 1. Gratuit, avec un widget rendu par du code hébergé ```json { "key": "crm-segments", "name": "Segments avancés CRM", "version": "0.1.0", "main": "src/index.ts", "author": { "name": "Atelier TS", "devAccountSlug": "atelier-ts" }, "compatibility": { "colibri": ">=1.0", "modules": ["crm"] }, "permissions": ["crm.contacts:read"], "capabilities": ["ui.widget", "storage.tenant.rw"], "contributes": { "widgets": [ { "key": "segments", "title": "Mes segments", "kind": "kit", "minHeight": 200 } ] }, "pricing": { "model": "free" }, "i18n": { "fr": "Segmentez vos contacts CRM en un clic.", "en": "Segment your CRM contacts in one click." }, "support": { "email": "support@atelier-ts.example" } } ``` ### 2. Payant, abonnement avec essai — événements, planification, e-mail, réglages ```json { "key": "devis-relance-auto", "name": "Relances automatiques de devis", "version": "1.2.0", "main": "src/index.ts", "author": { "name": "Studio Forge", "devAccountSlug": "studio-forge" }, "compatibility": { "colibri": ">=1.0", "modules": ["billing-fr"] }, "permissions": ["billing-fr.documents:read", "crm.contacts:read"], "capabilities": ["events.subscribe", "mail.send", "storage.tenant.rw"], "events": ["quote.created", "quote.accepted"], "schedules": [{ "key": "relances", "cron": "0 9 * * *" }], "settings": { "fields": [ { "key": "delays", "label": "Délais de relance (jours)", "type": "text", "placeholder": "3, 7, 14" } ] }, "pricing": { "model": "subscription", "amountEur": 9, "trialDays": 14 }, "i18n": { "fr": "Relance automatiquement vos devis non signés après 3, 7 et 14 jours.", "en": "Automatically follows up on unsigned quotes after 3, 7 and 14 days." }, "support": { "email": "support@studio-forge.example", "docsUrl": "https://studio-forge.example/docs/devis-relance" } } ``` ### 3. Hybride : page embarquée + backend chez vous, sans code hébergé ```json { "key": "sync-compta-externe", "name": "Synchronisation comptable externe", "version": "0.3.1", "author": { "name": "Studio Forge", "devAccountSlug": "studio-forge" }, "compatibility": { "colibri": ">=1.0", "modules": ["billing-fr"] }, "permissions": ["billing-fr.documents:read"], "capabilities": ["ui.menu"], "contributes": { "menuEntries": [ { "key": "synchro", "label": "Synchronisation", "embedUrl": "https://app.studio-forge.example/capibara", "icon": "refresh-cw" } ] }, "pricing": { "model": "one_time", "amountEur": 49 }, "i18n": { "fr": "Exporte vos factures vers votre logiciel comptable, depuis un backend hébergé chez l'éditeur.", "en": "Exports your invoices to your accounting software, from a backend hosted by the publisher." }, "support": { "email": "support@studio-forge.example" } } ``` Cette app illustre le modèle **hybride** : ni `main` ni `backend` — son vrai travail tourne dans **votre** backend, qui lit les factures par les [façades](/dev/docs/facades) de l'[API publique](/dev/docs/api-publique) (clé API + `X-Capibara-Install`) et reçoit les [webhooks sortants](/dev/docs/webhooks) ; sa page est montée en iframe isolée avec un jeton de contexte. Aucun `http.fetch:` n'est nécessaire : cette capability n'a de sens que pour le code **hébergé** (`main`), où elle est l'allowlist réseau réellement appliquée par la sandbox — tout appel vers un host non déclaré y est refusé à l'exécution. Pour servir les écrans depuis votre serveur avec le protocole du Kit, voyez plutôt [Backend externe](/dev/docs/backend-externe) (`backend: { url }`). > **Exemple complet téléchargeable.** L'app « Météo (exemple) » réunit tout > ce qui précède dans un projet fonctionnel (page et widget du Kit rendus par le code hébergé > + KV + fetch allowlisté), à télécharger depuis l'[index de la > documentation](/dev/docs) — lisez-le, copiez-le, adaptez-le. --- ## Capabilities, bornes et erreurs ## Capability ou permission ? Deux champs du manifeste se ressemblent mais répondent à des questions différentes : - **`capabilities`** répond à *« à quel type d'extension ou de ressource technique votre app veut-elle accéder ? »* — une entrée de menu, un appel réseau sortant, un espace de stockage clé/valeur… - **`permissions`** répond à *« à quelles données métier du tenant votre app veut-elle accéder ? »* — lire les contacts CRM, écrire des factures… Documentation complète : [Permissions et consentement du tenant](/dev/docs/permissions). Une app qui affiche un widget lisant des contacts CRM déclare donc généralement **les deux** : `"capabilities": ["ui.widget"]` et `"permissions": ["crm.contacts:read"]`. --- ## Liste blanche des capabilities Seules les capabilities explicitement listées ci-dessous (ou un `http.fetch:` bien formé) sont acceptées par le validateur du manifeste — toute autre valeur est rejetée à l'enregistrement. | Capability | Autorise | Quand la demander | |---|---|---| | `storage.tenant.ro` | Lecture d'un espace de stockage clé/valeur scopé au tenant qui a installé l'app. | Votre app a besoin de relire une configuration qu'il a écrite précédemment, sans avoir à la redemander à l'utilisateur. | | `storage.tenant.rw` | Lecture **et** écriture de ce même espace de stockage. | Votre app doit mémoriser un réglage, un état, un cache léger propre à ce tenant. | | `ui.block` | Contribuer un **bloc au site public** de l'organisation via `contributes.siteBlocks` — posé par l'auteur du site dans l'éditeur de page (groupe « Vos apps »), rendu par votre code hébergé (cf. [Le runtime](/dev/docs/runtime)). | Votre app ajoute une section (météo, catalogue, formulaire…) que l'utilisateur pose sur une page publique de son site. | | `ui.menu` | Contribuer une entrée dans la navigation latérale — page du Kit rendue par votre code hébergé (`view`) ou page HTTPS montée en iframe isolée (`embedUrl`) via `contributes.menuEntries` (cf. [le manifeste](/dev/docs/manifeste)). | Votre app a sa propre page dans l'espace de gestion du tenant. | | `ui.widget` | Contribuer un widget sur le tableau de bord d'accueil via `contributes.widgets` — Kit (code hébergé), déclaratif ou embed ; ajout depuis « Personnaliser ». | Votre app affiche un résumé ou un indicateur en un coup d'œil. | | `ui.panel` | Contribuer un panneau sur une **fiche** du tenant (contact/société du CRM) — rendu par votre code hébergé via `contributes.panels` (cf. [Le runtime](/dev/docs/runtime)). | Votre app montre, sur la fiche d'un client, un score, un historique, des actions. | | `ui.site` | Contribuer une **page entière au site public** via `contributes.sitePages` — activée et adressée par l'organisation dans Mon site › Apps, rendue par votre code hébergé. | Votre app a besoin d'une adresse à lui sur le site de l'organisation (catalogue, prise de rendez-vous, espace dédié…). | | `ui.settings` | Réservée : contribuer une section dans la centrale de paramétrage du tenant (`contributes.settingsSections`, **pas encore montée**). Les réglages d'une app passent aujourd'hui par `settings.fields` du manifeste (cf. [Données](/dev/docs/donnees)) — aucune capability nécessaire. | Ne la demandez pas encore : elle n'ouvre rien de visible. | | `ai.tool` | Réservée : exposer un outil à l'assistant IA de la plateforme (`contributes.aiTools`, **pas encore monté**). | Ne la demandez pas encore : l'assistant n'appelle pas les apps aujourd'hui. | | `events.subscribe` | Souscrire aux événements de domaine typés émis par les apps (ex. facture payée, devis accepté) — livrés à votre code hébergé (`events` du manifeste + `defineApp({ events })`) ou à un webhook sortant. | Votre app réagit à un événement métier plutôt que d'interroger l'API en boucle. | | `data.collections` | Lire et écrire les **collections** déclarées dans `collections` du manifeste (`ctx.data.`) — enregistrements typés, validés, stockés chez l'organisation (cf. [Données](/dev/docs/donnees)). | Votre app a de vraies données structurées (favoris, scores, tickets…) et ne veut ni base à gérer ni migration. | | `files.private` | Déposer et relire des **fichiers privés** (`ctx.files`, ≤ 5 Mo, types bornés), servis par une route gardée de l'organisation. | Votre app génère un PDF, une image ou un export à remettre aux personnes autorisées. | | `mail.send` | Envoyer un **e-mail transactionnel** (`ctx.mail.send`) à des personnes liées à l'organisation — ≤ 5 par appel, contenu en blocs, coque de l'organisation, désinscription en un clic, quota par jour (cf. [Moteurs](/dev/docs/moteurs)). | Votre app confirme, rappelle ou relance une personne précise. Jamais une campagne. | | `notify.send` | Notifier dans Capibara (`ctx.notify.user / permission / admins`) — cloche + push, quota par jour. | Votre app a quelque chose à dire à une personne, aux porteurs d'une permission ou aux administrateurs. | | `calendar.project` | Projeter des dates dans le calendrier de l'organisation (`ctx.calendar`, source `app:`, ≤ 500). | Vos objets ont des dates (échéances, interventions, sessions) qui méritent d'apparaître dans le planning. | | `search.index` | Rendre vos fiches trouvables dans la recherche ⌘K (`ctx.search`, ≤ 2 000), groupe au nom de l'app, visible des personnes qui ont « utiliser l'app ». | Vos utilisateurs cherchent vos objets par leur nom depuis n'importe quel écran. | | `approvals.request` | Demander une validation à un humain (`ctx.approvals.request`) — cloche « Validations », décision livrée par l'événement `approval.decided`. | Une action de votre app engage l'organisation (remboursement, commande) et doit être tranchée par quelqu'un. | ### Accès réseau — `http.fetch:` Pas de capability fixe pour le réseau sortant : chaque domaine externe que votre app appelle doit être déclaré explicitement, un par un, sous la forme `http.fetch:` : ```json { "capabilities": ["http.fetch:api.exemple.com", "http.fetch:hooks.exemple.io"] } ``` Un domaine sans point ni TLD d'au moins deux lettres est refusé (`http.fetch:localhost` ou `http.fetch:api` ne valident pas). Il n'y a pas d'accès au réseau interne de la plateforme : seul l'egress vers des domaines publics explicitement déclarés passe, et chaque appel de `ctx.fetch` est proxifié par la plateforme (HTTPS seul, 10 s, réponse ≤ 512 Ko, aucune redirection suivie) et audité — cf. les bornes ci-dessous. Cette capability ne concerne que le **code hébergé** : une app **hybride** ou à **backend externe** fait ses appels réseau depuis son propre serveur, et appelle l'[API publique](/dev/docs/api-publique) de Capibara avec une clé API ou un jeton OAuth, comme n'importe quel client HTTP. --- ## Bornes, quotas et erreurs (référence unique) Tout ce qui borne l'exécution d'une app est réuni ici ; les autres pages y renvoient. Ces valeurs sont **celles appliquées aujourd'hui** par la plateforme — pas des intentions. ### Une interaction (page, action, événement, planification, HTTP entrant) | Borne | Valeur | Dépassement | |---|---|---| | Durée d'une interaction | **15 s** (code hébergé et backend externe) | l'interaction échoue : « L'app n'a pas répondu à temps », ligne d'erreur au journal | | Corps envoyé à votre code | ≤ 256 Ko | refus avant exécution | | Réponse de votre code | ≤ 1 Mo | refus, l'écran dit « L'app n'a pas répondu » | | Appels au broker par interaction (`ctx.kv`, `ctx.fetch`, `ctx.capibara`, moteurs…) | ≤ 100 | `quota_exceeded` : l'appel suivant lève, l'interaction échoue | | Journal `ctx.log` | 200 lignes × 500 caractères par interaction | lignes suivantes ignorées | | État `state` renvoyé | ≤ 8 Ko, signé par la plateforme, lié à l'installation et à la surface, 24 h | rejeté (état absent au prochain appel) | | `followup` après un `ack` | dans les 15 min de l'`ack` | `followup_rejected` | | Document du Kit | `page` / `sitePage` ≤ 500 composants, autres surfaces ≤ 200, profondeur 8, 32 Ko de texte (cf. [Le Kit](/dev/docs/kit)) | non affiché, raison au journal | ### Par app et par organisation | Borne | Valeur | Dépassement | |---|---|---| | Interactions simultanées (par app, tous tenants) | ≤ 8 | `busy` : réponse 503 « occupée », réessayez | | Disjoncteur | ≥ 10 échecs en 5 min **et** ≥ 50 % des appels → app suspendue **5 min**, puis une sonde | `open` : 503 pendant la suspension, visible au journal | | Kill switch | incident posé par l'équipe Capibara (global ou pour une organisation) | `killed` : toute invocation refusée jusqu'à la levée — cf. [Publication et review](/dev/docs/publication) | | Planifications | intervalle minimum Gratuit 1 h · Pro 15 min · Business 5 min ; une seule exécution en vol par planification | occurrences sautées | | HTTP entrant | corps ≤ 256 Ko, JSON ou texte, rate-limit par IP | 413 / 429 au tiers appelant | ### `ctx.*` — bornes par capability | Capability | Bornes | |---|---| | `storage.tenant.*` (`ctx.kv`) | clé 1–128 caractères (`a-z 0-9 _ . : -`), **valeur ≤ 32 Ko**, **200 clés** par installation, `list` paginé | | `http.fetch:` (`ctx.fetch`) | HTTPS seul, host déclaré seul, **10 s**, réponse **≤ 512 Ko** (`truncated: true` au-delà), **aucune redirection** suivie (`redirect: 'error'`) | | `data.collections` (`ctx.data`) | 10 collections × 30 champs, enregistrement ≤ 64 Ko, 100 lignes par page, 5 conditions, lignes par installation : 5 000 / 100 000 / 1 000 000 selon la formule (cf. [Données](/dev/docs/donnees)) | | `files.private` (`ctx.files`) | ≤ 5 Mo par fichier, 500 fichiers par installation, types bornés, quota de stockage de la formule | | `mail.send` | ≤ 5 destinataires liés par appel, quota par jour et par installation 20 / 200 / 1 000 (cf. [Moteurs](/dev/docs/moteurs)) | | `notify.send` | quota par jour 200 / 2 000 / 10 000 ; `permission` ≤ 50 personnes | | `calendar.project` | ≤ 500 projections, ≤ 366 jours | | `search.index` | ≤ 2 000 fiches | | `approvals.request` | ≤ 200 demandes en attente | | Façades `ctx.capibara.*` | `take` ≤ 100 ; en REST, 120 appels / minute par installation (cf. [Façades](/dev/docs/facades)) | ### Les erreurs que votre code voit Un appel `ctx.*` refusé **lève une exception** dans votre handler (le message dit pourquoi) ; l'interaction échoue proprement si vous ne l'attrapez pas, et le journal de l'app porte le code : | Code | Sens | Ce qu'il faut faire | |---|---|---| | `not_granted` | capability absente du manifeste, ou non consentie par l'organisation (scope) | déclarez-la, puis faites re-consentir (nouvelle version) | | `forbidden` | borne dépassée : clé KV invalide, valeur > 32 Ko, quota de clés, host non déclaré, type de fichier refusé… | corrigez l'appel ; le message nomme la borne | | `quota_exceeded` | plus de 100 appels broker dans l'interaction | regroupez vos lectures, mettez en cache dans `state` ou `kv` | | `killed` | incident actif sur la version (kill switch) | attendez la levée ; l'e-mail d'incident vous a dit le motif | | `scope_not_granted`, `invalid_input`, `not_found`, `conflict`, `precondition_failed`, `service_account_missing` | réponses des [façades](/dev/docs/facades) | cf. leur table | | `handler_missing` | la capability existe mais aucune implémentation ne la sert sur cette instance | contactez le support de l'instance | Côté organisation, une app qui échoue trop (disjoncteur) ou qui fait l'objet d'un incident est isolée **sans affecter les autres apps ni les autres organisations** ; chaque appel qui passe par le broker est audité (journal consultable par l'équipe de review). Ni le temps CPU ni la mémoire ne sont mesurés individuellement aujourd'hui : c'est le délai de 15 s et l'isolation de la sandbox qui bornent une interaction. ### Trois façons de faire tourner votre logique **A — Code HÉBERGÉ (sandbox).** Ajoutez `main` à votre manifeste (chemin relatif, ex. `"main": "src/index.ts"`). À la publication, Capibara empaquette ce point d'entrée (sans jamais exécuter votre code au build) et le fait tourner dans un isolate contraint (workerd). Votre module exporte un handler façon worker : ```ts import { defineApp, ui } from '@capibara-dev/sdk'; export default defineApp({ pages: { home: async ({ ctx }) => { // ctx = votre seule porte vers la plateforme (servie par le broker, qui // applique capabilities + permissions + quotas + audit). await ctx.kv.put('compteur', { n: 1 }); // storage.tenant.rw const row = await ctx.kv.get('compteur'); // storage.tenant.ro const r = await ctx.fetch('https://api.exemple.com/x'); // http.fetch:api.exemple.com return ui.text({ markdown: `Compteur ${row?.value?.n} — amont ${r.status}` }); }, }, }); ``` Votre code est invoqué par la plateforme à chaque interaction (page ouverte, clic, formulaire, événement, planification, requête HTTP entrante) — cf. [Le runtime](/dev/docs/runtime). `ctx.kv` expose `get/list/put/delete` (KV cloisonné par organisation) et `ctx.fetch(url, init)` la sortie réseau bornée, vers les domaines `http.fetch:` déclarés. Aucun autre accès : ni DB, ni réseau libre, ni secret. Les bornes ci-dessus s'appliquent à ce code. > **Activation.** Le runtime hébergé est un service de l'instance (profil > Docker `addons`), **actif par défaut** sur capibara.fr — chaque publication > est rechargée automatiquement en quelques secondes. Sur une instance où il > serait désactivé, l'invocation renvoie proprement « runtime non activé » — > votre app reste distribuée et installable, et son mode hybride > (ci-dessous) fonctionne sans dépendre du runtime. **Écrans** : vos pages, widgets et panneaux sont décrits en JSON (le [Kit](/dev/docs/kit)) et rendus par Capibara avec ses composants — jamais de HTML ni de JavaScript côté client. L'exemple « Météo » (téléchargeable depuis l'[index](/dev/docs)) montre le motif complet. **B — BACKEND EXTERNE (`backend: { url }`, sans `main`).** Le même `defineApp`, servi par VOTRE serveur, avec les mêmes bornes et le même disjoncteur ; les façades passent par l'API publique, et collections, fichiers et moteurs restent réservés au code hébergé. Tout est sur la page dédiée [Backend externe](/dev/docs/backend-externe). **C — Mode HYBRIDE (sans `main` ni `backend`).** Votre propre backend appelle l'[API publique](/dev/docs/api-publique), vos pages sont montées côté tenant via `contributes.menuEntries` (iframe isolée + jeton de contexte signé), et les [webhooks sortants](/dev/docs/webhooks) vous poussent les événements. Ce chemin ne dépend d'aucune activation et fonctionne dès aujourd'hui. A et C se combinent librement ; B est exclusif de A. --- ## Déclarer des capabilities : bonnes pratiques - **Minimum nécessaire** — chaque capability demandée est visible par la review ; l'administrateur du tenant voit, lui, les scopes (phrases de consentement) et l'hébergement (« Tourne chez Capibara » / « Backend chez l'éditeur ») au moment de l'installation. N'en demandez que ce que votre app utilise vraiment. - **Cohérence avec `contributes`** — si vous déclarez `ui.widget`, la review s'attend à trouver une entrée correspondante dans `contributes.widgets` (et réciproquement). - **`http.fetch` un domaine à la fois** — pas de joker, pas de sous-domaine générique : un domaine par service tiers que vous appelez réellement. - **Pas de capability « au cas où »** — en ajouter une que vous n'utilisez pas encore ralentit la review et n'apporte rien tant qu'elle n'est pas exercée. --- ## Le Kit — l'UI déclarative des apps ## Le principe Une app Capibara décrit son interface en **JSON** et la plateforme la rend avec **ses** composants : même look que le reste de Capibara dans le back-office, thème du site du tenant sur le public. Vous n'écrivez ni HTML, ni CSS, ni JavaScript côté client — vous composez des blocs, comme les composants d'un message Discord ou les blocs d'un message Slack, mais avec un vrai langage de mise en page (colonnes, volets, onglets, assistants, tableaux paginés, formulaires typés, sections du site builder). Ce que ça vous garantit : accessibilité, responsive, mode sombre, sécurité (aucune injection possible) et une interface que vos utilisateurs reconnaissent immédiatement. Ce que ça vous interdit : du CSS libre, des couleurs hors thème, des scripts. C'est voulu. **Essayez tout de suite** : le [Kit Studio](/dev/kit-studio) rend votre JSON en direct dans chaque surface, avec des données d'exemple, et exporte le code TypeScript équivalent. La palette se **glisse-dépose** sur l'aperçu (le composant s'ajoute au document, comme au clic) et chaque page d'app du portail a son onglet **Studio**, avec un brouillon propre au projet. ## Le document ```json { "kit": 1, "title": "Commandes", "ui": { "type": "stack", "gap": "lg", "children": [ … ] }, "state": "…", "components": { "pill": { "props": ["label"], "ui": { "type": "badge", "text": "{{ props.label }}" } } } } ``` - `kit` : version du contrat (obligatoire). Un composant inconnu d'une version future est rendu par son `fallback` déclaré, sinon par une note « mise à jour requise » — jamais un écran vide. - `ui` : l'arbre de composants. - `state` : un état opaque (≤ 8 Ko), signé par la plateforme, qui voyage avec la surface — pagination, assistants multi-étapes, sans base. - `components` : vos composants réutilisables, instanciés par `{ "type": "$ref", "component": "pill", "props": { "label": "A" } }`. ## Les surfaces | Surface | Où | Contexte reçu | |---|---|---| | `page` | page d'app du back-office (`/apps//`), entrée de menu | utilisateur, route, état | | `panel` | fiche **contact ou société** du CRM (`subject.type = 'party'` — le seul sujet ouvert aujourd'hui ; les fiches des autres modules viendront avec leur propre valeur) | utilisateur + `subject { type, id }` | | `widget` | carte de la grille d'accueil | utilisateur | | `siteBlock` | bloc posé par l'auteur du site dans une page de son site public (« Vos apps » de l'éditeur) | `visitor` (membre du site connecté ou `null`), champs du bloc dans `params` — jamais de `viewer` | | `sitePage` | page publique du site de l'organisation, à l'adresse qu'elle choisit (Mon site › Apps) | `visitor`, `params.path` / `params.query` | | `form` | modal ou page de saisie ouverte par une action | utilisateur + valeurs | | `settings` | réservée : le protocole sait la rendre mais aucun écran du tenant ne l'ouvre encore — les réglages d'une app passent par `settings.fields` du manifeste (cf. [Données](/dev/docs/donnees)) | config courante | ## Gabarits : dessiner puis ne coder que la donnée Le Studio produit un **gabarit** ; votre code le remplit avec `ui.render(template, data)` — le serveur reste la source, le dessin reste le dessin. - `{{ chemin }}` dans une chaîne : interpolation. Une chaîne qui n'est QUE la liaison garde le **type** de la valeur (`"{{ order.total }}"` → nombre). - `{ "$bind": "chemin" }` : remplacé par la valeur (tableau, objet…). - `{ "type": "each", "$each": "orders", "$as": "o", "node": { … } }` : répète `node` pour chaque élément (`{{ o.ref }}`, `{{ $index }}`), dans n'importe quel tableau (`children`, `rows`, `items`, `options`…). - `"$if": "chemin"` sur un élément de tableau : retiré si faux (`"!chemin"` inverse). Chemins : `a.b.c`, `a[0].b`, `$index`, `$data` (racine). Pas d'expression, pas de code : rien ne s'exécute dans un gabarit. ## Actions Un bouton, un menu, une ligne de tableau, un formulaire portent une `action` (identifiant) et des `params`. Au clic, la plateforme invoque votre handler avec l'action, les paramètres, les valeurs du formulaire et l'état ; vous répondez par une nouvelle UI, un `toast`, une navigation interne, un `patch`, l'ouverture d'un formulaire ou un simple `ack` suivi d'un `followup`. Les liens (`href`) acceptent un chemin interne, `https://`, `mailto:` et `tel:` — jamais autre chose. ## Style borné `tone` (neutre, plume, gorge, ambre, rouge), `surface` (plein, carte, muet), `gap`, `size`, `align`, ratios d'image, icônes Lucide par nom. Aucune couleur hexadécimale, aucune police, aucun CSS : c'est le thème qui décide, pas l'app. ## Accessibilité (dans le schéma) `alt` obligatoire sur une image, `label` sur toute saisie, `ariaLabel` sur un bouton sans libellé. Un document qui l'oublie est refusé à la validation. ## Bornes | Borne | Valeur | |---|---| | Composants par document | 200 (page et page de site : 500) | | Profondeur | 8 | | Texte cumulé | 32 Ko | | Images | 20 | | Lignes d'un tableau | 100 | | Éléments d'une liste | 200 | | Options d'une saisie | 200 | | État (`state`) | 8 Ko | | Composants déclarés | 40 (imbrication ≤ 4) | | Types de composants | 38 | ## Catalogue des composants (généré depuis le schéma) Le JSON Schema complet est servi sur [`/dev/kit/schema.json`](/dev/kit/schema.json) (complétion dans le Studio, validation dans votre éditeur, lecture par un assistant IA). ### Mise en page Structurer l'écran : piles, grilles, colonnes, volets, onglets, assistants. #### `stack` — Pile Empile ses enfants verticalement (ou en ligne) avec un espacement régulier — la brique de base de toute page. | Propriété | Type | Requis | |---|---|:-:| | `direction` | `vertical` · `horizontal` | | | `gap` | `none` · `sm` · `md` · `lg` | | | `align` | `start` · `center` · `end` · `stretch` | | | `justify` | `start` · `center` · `end` · `between` | | | `wrap` | booléen | | | `children` | liste de nœuds | oui | #### `grid` — Grille Répartit ses enfants en colonnes égales (2 à 4), qui se replient sur mobile. | Propriété | Type | Requis | |---|---|:-:| | `columns` | `2` · `3` · `4` | | | `gap` | `none` · `sm` · `md` · `lg` | | | `children` | liste de nœuds | oui | #### `columns` — Colonnes Deux ou trois colonnes à largeurs choisies (1/2, 2/3…), chacune avec son propre contenu. | Propriété | Type | Requis | |---|---|:-:| | `gap` | `none` · `sm` · `md` · `lg` | | | `columns` | liste de objets (≤ 4) | oui | #### `card` — Carte Un bloc encadré avec titre optionnel, pour isoler un contenu ou un formulaire. | Propriété | Type | Requis | |---|---|:-:| | `title` | texte (≤ 200) | | | `subtitle` | texte (≤ 200) | | | `tone` | `neutral` · `plume` · `gorge` · `amber` · `red` | | | `surface` | `plain` · `card` · `muted` | | | `actions` | liste de objets (≤ 4) | | | `children` | liste de nœuds | oui | #### `section` — Section Un titre de section, une phrase d'explication et le contenu en dessous. | Propriété | Type | Requis | |---|---|:-:| | `title` | texte (≤ 200) | oui | | `description` | texte (≤ 2000) | | | `children` | liste de nœuds | oui | #### `sidebar` — Volet latéral Un contenu principal et un volet à gauche ou à droite (filtres, résumé, aide). | Propriété | Type | Requis | |---|---|:-:| | `side` | `left` · `right` | | | `width` | `sm` · `md` | | | `sidebar` | liste de nœuds | oui | | `children` | liste de nœuds | oui | #### `pageHeader` — En-tête de page Titre, sous-titre et boutons d'action alignés à droite — à poser en tête d'une page. | Propriété | Type | Requis | |---|---|:-:| | `title` | texte (≤ 200) | oui | | `subtitle` | texte (≤ 2000) | | | `breadcrumbs` | liste de objets (≤ 6) | | | `actions` | liste de nœuds (≤ 4) | | | `tabs` | liste de objets (≤ 12) | | | `activeTab` | texte | | #### `toolbar` — Barre d'outils Recherche et filtres en ligne, envoyés à une action à chaque changement (formulaire en direct). | Propriété | Type | Requis | |---|---|:-:| | `search` | objet | | | `children` | liste de nœuds | | #### `statsRow` — Rangée d'indicateurs Plusieurs chiffres clés côte à côte (des composants `kpi`). | Propriété | Type | Requis | |---|---|:-:| | `items` | liste de objets (≤ 6) | oui | #### `split` — Liste + détail Une liste à gauche (maître) et le détail de l'élément choisi à droite. | Propriété | Type | Requis | |---|---|:-:| | `ratio` | `1/3` · `1/2` · `2/3` | | | `master` | liste de nœuds | oui | | `detail` | liste de nœuds | oui | #### `stickyBar` — Barre collante Une barre d'actions qui reste visible en bas de l'écran (Enregistrer, Annuler…). | Propriété | Type | Requis | |---|---|:-:| | `children` | liste de nœuds | oui | #### `spacer` — Espace Un espace vertical vide, de xs à xl. | Propriété | Type | Requis | |---|---|:-:| | `size` | `sm` · `md` · `lg` | | #### `divider` — Séparateur Un filet horizontal, avec un libellé optionnel au milieu (« Ou »). | Propriété | Type | Requis | |---|---|:-:| | `label` | texte (≤ 200) | | #### `tabs` — Onglets Plusieurs volets de contenu, un seul visible à la fois. | Propriété | Type | Requis | |---|---|:-:| | `defaultTab` | texte | | | `items` | liste de objets (≤ 12) | oui | #### `accordion` — Accordéon Des sections repliables (questions-réponses, détails secondaires). | Propriété | Type | Requis | |---|---|:-:| | `items` | liste de objets (≤ 30) | oui | #### `stepper` — Assistant par étapes Un parcours en étapes numérotées, l'étape courante ouverte. | Propriété | Type | Requis | |---|---|:-:| | `current` | nombre (≥ 0) | oui | | `steps` | liste de objets (≤ 10) | oui | | `actions` | liste de nœuds (≤ 3) | | ### Texte & indicateurs Titres, paragraphes, badges, chiffres clés, notes, états vides. #### `heading` — Titre Un titre de niveau 1 à 4. | Propriété | Type | Requis | |---|---|:-:| | `text` | nœud ou nombre | oui | | `level` | `1` · `2` · `3` | | | `align` | `start` · `center` · `end` | | #### `text` — Texte Un paragraphe en Markdown léger (gras, italique, liens, listes). | Propriété | Type | Requis | |---|---|:-:| | `markdown` | texte (≤ 20000) | oui | | `size` | `sm` · `md` · `lg` | | | `tone` | `neutral` · `plume` · `gorge` · `amber` · `red` | | | `align` | `start` · `center` · `end` | | #### `badge` — Badge Une petite pastille de statut colorée (Nouveau, Payée, En retard). | Propriété | Type | Requis | |---|---|:-:| | `text` | nœud ou nombre | oui | | `tone` | `neutral` · `plume` · `gorge` · `amber` · `red` | | #### `kpi` — Chiffre clé Un indicateur chiffré avec libellé, variation et icône — seul ou dans une rangée. | Propriété | Type | Requis | |---|---|:-:| | `label` | texte (≤ 200) | oui | | `value` | nœud ou nombre | oui | | `delta` | nœud ou nombre | | | `deltaTone` | `neutral` · `plume` · `gorge` · `amber` · `red` | | | `hint` | texte (≤ 200) | | | `icon` | `award` · `bar-chart` · `briefcase` · `calendar` · `check-circle` · `clock` · `code` · `coffee` · `credit-card` · `file-text` · `gift` · `globe` · `heart` · `image` · `layers` · `lightbulb` · `lock` · `mail` · `message-circle` · `monitor` · `package` · `phone` · `rocket` · `settings` · `shield` · `shopping-cart` · `smartphone` · `sparkles` · `star` · `target` · `trending-up` · `trophy` · `truck` · `users` · `video` · `wrench` · `zap` | | #### `note` — Note Un encadré d'information, d'avertissement, de succès ou d'erreur. | Propriété | Type | Requis | |---|---|:-:| | `tone` | `info` · `success` · `warning` · `error` | | | `title` | texte (≤ 200) | | | `text` | texte (≤ 2000) | oui | #### `empty` — État vide Le message affiché quand il n'y a encore rien, avec un bouton pour commencer. | Propriété | Type | Requis | |---|---|:-:| | `title` | texte (≤ 200) | oui | | `description` | texte (≤ 2000) | | | `icon` | `award` · `bar-chart` · `briefcase` · `calendar` · `check-circle` · `clock` · `code` · `coffee` · `credit-card` · `file-text` · `gift` · `globe` · `heart` · `image` · `layers` · `lightbulb` · `lock` · `mail` · `message-circle` · `monitor` · `package` · `phone` · `rocket` · `settings` · `shield` · `shopping-cart` · `smartphone` · `sparkles` · `star` · `target` · `trending-up` · `trophy` · `truck` · `users` · `video` · `wrench` · `zap` | | | `action` | objet | | ### Données Tableaux paginés, listes, chronologies, graphiques, images. #### `table` — Tableau Colonnes typées (texte, montant, date, badge, lien), actions par ligne et pagination « Charger plus ». | Propriété | Type | Requis | |---|---|:-:| | `columns` | liste de objets (≤ 12) | oui | | `rows` | liste de objets (≤ 100) | oui | | `emptyText` | texte (≤ 200) | | | `pagination` | objet | | | `caption` | texte (≤ 200) | | #### `list` — Liste Des lignes titre + sous-titre avec avatar, badge ou action — pour des éléments courts. | Propriété | Type | Requis | |---|---|:-:| | `items` | liste de objets (≤ 200) | oui | | `emptyText` | texte (≤ 200) | | #### `timeline` — Chronologie Des événements datés les uns sous les autres (historique, journal). | Propriété | Type | Requis | |---|---|:-:| | `items` | liste de objets (≤ 100) | oui | #### `chart` — Graphique Courbes dans le temps ou barres comparatives, dessinées par les graphiques de Capibara. | Propriété | Type | Requis | |---|---|:-:| | `kind` | `timeseries` · `bars` | oui | | `height` | nombre (≥ 120, ≤ 480) | | | `series` | liste de objets (≤ 4) | | | `points` | liste de objets (≤ 400) | | | `bars` | liste de objets (≤ 40) | | | `unit` | texte (≤ 20) | | #### `progress` — Progression Une barre de progression (0 à 100 %) avec son libellé. | Propriété | Type | Requis | |---|---|:-:| | `value` | nombre (≥ 0, ≤ 100) | oui | | `label` | texte (≤ 200) | | | `tone` | `neutral` · `plume` · `gorge` · `amber` · `red` | | #### `image` — Image Une image de la médiathèque ou en https, avec ratio et largeur bornés, texte alternatif obligatoire. | Propriété | Type | Requis | |---|---|:-:| | `src` | texte (≤ 2048) | oui | | `alt` | texte (≤ 300) | oui | | `ratio` | `auto` · `16/9` · `4/3` · `1/1` · `3/4` | | | `width` | `sm` · `md` · `full` | | | `rounded` | booléen | | | `caption` | texte (≤ 200) | | #### `avatar` — Avatar Le rond d'initiales ou la photo d'une personne. | Propriété | Type | Requis | |---|---|:-:| | `name` | texte (≤ 200) | oui | | `src` | texte (≤ 2048) | | | `size` | `sm` · `md` · `lg` | | ### Formulaires Champs typés validés par la plateforme, envoyés à une action de l'app. #### `field` — Champ Un champ de saisie typé (texte, nombre, date, choix, sélecteur de contact…) — à placer dans un formulaire. | Propriété | Type | Requis | |---|---|:-:| | `kind` | `text` · `textarea` · `number` · `money` · `select` · `multiselect` · `toggle` · `date` · `datetime` · `file` · `party` · `product` · `user` · `document` · `project` | oui | | `name` | texte | oui | | `label` | texte (≤ 200) | oui | | `placeholder` | texte (≤ 200) | | | `hint` | texte (≤ 2000) | | | `required` | booléen | | | `disabled` | booléen | | | `value` | texte (≤ 20000) ou nombre ou booléen ou liste de texte (≤ 200) (≤ 200) ou null | | | `options` | liste de objets (≤ 200) | | | `min` | nombre | | | `max` | nombre | | | `pattern` | texte (≤ 200) | | | `rows` | nombre (≥ 2, ≤ 20) | | | `accept` | texte (≤ 200) | | #### `form` — Formulaire Regroupe des champs, valide les saisies (requis, bornes, motif) et envoie l'action de son bouton. | Propriété | Type | Requis | |---|---|:-:| | `name` | texte | oui | | `layout` | `stack` · `grid` | | | `children` | liste de nœuds | oui | | `submit` | objet | oui | | `cancel` | objet | | ### Actions & navigation Boutons, liens et menus qui déclenchent vos actions ou naviguent. #### `button` — Bouton Déclenche une action de votre app, ouvre un formulaire ou navigue — avec confirmation possible. | Propriété | Type | Requis | |---|---|:-:| | `label` | texte (≤ 200) | | | `ariaLabel` | texte (≤ 200) | | | `icon` | `award` · `bar-chart` · `briefcase` · `calendar` · `check-circle` · `clock` · `code` · `coffee` · `credit-card` · `file-text` · `gift` · `globe` · `heart` · `image` · `layers` · `lightbulb` · `lock` · `mail` · `message-circle` · `monitor` · `package` · `phone` · `rocket` · `settings` · `shield` · `shopping-cart` · `smartphone` · `sparkles` · `star` · `target` · `trending-up` · `trophy` · `truck` · `users` · `video` · `wrench` · `zap` | | | `action` | texte | | | `params` | objet | | | `href` | texte (≤ 2048) | | | `variant` | `primary` · `secondary` · `outline` · `ghost` · `danger` · `link` | | | `size` | `sm` · `md` · `lg` | | | `confirm` | texte (≤ 2000) | | | `disabled` | booléen | | | `submits` | texte | | #### `link` — Lien Un lien vers une page de Capibara ou une adresse https. | Propriété | Type | Requis | |---|---|:-:| | `label` | texte (≤ 200) | oui | | `href` | texte (≤ 2048) | oui | #### `menu` — Menu Un bouton qui déroule plusieurs actions (Exporter, Supprimer…). | Propriété | Type | Requis | |---|---|:-:| | `label` | texte (≤ 200) | | | `ariaLabel` | texte (≤ 200) | | | `icon` | `award` · `bar-chart` · `briefcase` · `calendar` · `check-circle` · `clock` · `code` · `coffee` · `credit-card` · `file-text` · `gift` · `globe` · `heart` · `image` · `layers` · `lightbulb` · `lock` · `mail` · `message-circle` · `monitor` · `package` · `phone` · `rocket` · `settings` · `shield` · `shopping-cart` · `smartphone` · `sparkles` · `star` · `target` · `trending-up` · `trophy` · `truck` · `users` · `video` · `wrench` · `zap` | | | `items` | liste de objets (≤ 12) | oui | ### Site public Les blocs du constructeur de site, rendus au thème du site du tenant. #### `siteSection` — Section du site Un des blocs du constructeur de site (héro, tarifs, FAQ…), rendu au thème du site public. | Propriété | Type | Requis | |---|---|:-:| | `block` | texte | oui | | `props` | objet | oui | ### Gabarits & composants Réutiliser un composant, répéter un gabarit, prévoir un repli. #### `$ref` — Composant réutilisable Instancie un composant déclaré dans `components` avec ses propres props. | Propriété | Type | Requis | |---|---|:-:| | `component` | texte | oui | | `props` | objet | | #### `fallback` — Repli Le texte affiché à la place d'un composant qu'une version plus ancienne de Capibara ne connaît pas. | Propriété | Type | Requis | |---|---|:-:| | `text` | texte (≤ 2000) | oui | #### `each` — Répétition Répète un gabarit pour chaque élément d'une liste de données (`$each`, `$as`). | Propriété | Type | Requis | |---|---|:-:| | `$each` | texte (≤ 200) | oui | | `$as` | texte | | | `$if` | texte (≤ 200) | | | `node` | objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou nœud ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou objet ou nœud ou objet ou objet ou objet ou objet ou objet ou objet | oui | --- ## Le runtime — defineApp ## Le principe Une app Capibara fonctionne **comme un bot Discord** : la plateforme lui envoie des interactions (ouverture d'une page, clic, soumission d'un formulaire, événement métier, planification, requête HTTP d'un tiers) ; votre code répond par une **description d'écran** (le [Kit](/dev/docs/kit)) ou par des **effets** (toast, navigation, rafraîchissement…). Vous n'hébergez rien : le code déclaré par `main` est bundlé à la publication et tourne dans la sandbox Capibara (workerd sous gVisor), sans Node.js, sans réseau libre, sans secret. Sa seule porte vers le monde est le `ctx` reçu par chaque handler. ```ts import { defineApp, ui, toast } from '@capibara-dev/sdk'; export default defineApp({ pages: { home: { async render({ ctx, viewer }) { const row = await ctx.kv.get('greeting'); return ui.doc(ui.stack({ gap: 'md' }, [ ui.pageHeader({ title: 'Bonjour ' + (viewer?.name ?? '') }), ui.text({ markdown: String(row?.value ?? 'Aucun message.') }), ui.form({ name: 'greet', submit: ui.button({ label: 'Enregistrer', action: 'save', variant: 'primary' }) }, [ ui.field({ kind: 'text', name: 'value', label: 'Message', required: true }), ]), ]), { title: 'Accueil' }); }, }, }, actions: { save: async ({ ctx, form }) => { await ctx.kv.put('greeting', form?.value); return { ...toast('Enregistré.', 'success'), refresh: true }; }, }, }); ``` Le module `@capibara-dev/sdk` est **fourni par la plateforme** dans la sandbox (il n'est jamais lu dans votre dépôt) ; le paquet npm du même nom expose les mêmes signatures pour le typage et vos tests locaux. ## Les familles de handlers | Clé de `defineApp` | Déclaration dans le manifeste | Ce que reçoit le handler | Ce qu'il renvoie | |---|---|---|---| | `pages` | `contributes.menuEntries[].view` | `{ ctx, params, viewer, state }` | un nœud du Kit ou `ui.doc(…)` | | `widgets` | `contributes.widgets[]` avec `kind: "kit"` | idem (config du widget dans `ctx.install.config`) | idem (surface `widget`, ≤ 200 composants) | | `panels` | `contributes.panels[]` (`subject: "party"`) | idem + `subject: { type, id }` = la fiche affichée | idem (surface `panel`) | | `forms` | aucune (ouverts par une action `openForm`) | idem + `params` de l'ouverture | idem (surface `form`, rendu en modal) | | `siteBlocks` | `contributes.siteBlocks[]` + capability `ui.block` | `{ ctx, params, visitor, state }` — `params` = champs du bloc remplis par l'auteur du site, `visitor` = membre du site ou `null`, `viewer` = `null` | idem (surface `siteBlock`, ≤ 200 composants) | | `sitePages` | `contributes.sitePages[]` + capability `ui.site` | idem — `params.path` (sous-chemin), `params.query` (paramètres d'URL) | idem (surface `sitePage`, ≤ 500 composants) | | `actions` | aucune (les boutons du Kit les nomment) | `{ ctx, action, params, form, formName, state, viewer }` | des **effets** (ci-dessous) | | `events` | `events: ["invoice.paid", …]` + capability `events.subscribe` | `{ ctx, event: { id, type, occurredAt, data } }` | rien (idempotent : un même événement peut être rejoué) | | `schedules` | `schedules: [{ key, cron }]` | `{ ctx, key }` | rien | | `http` | `http: ["/stripe-hook"]` | `{ ctx, method, path, query, headers, body, json() }` | `{ status?, json? }` ou `{ status?, body? }` | Un handler de surface peut être une fonction ou un objet `{ render }`. Une page, un widget ou un panneau **doit être déclaré dans le manifeste** pour être rendu (c'est ce que le tenant voit au consentement) ; les formulaires sont libres. ## Le contexte `ctx` | `ctx.…` | Contenu | |---|---| | `tenant` | `{ id, slug, name, plan, locale: 'fr' }` | | `viewer` | `{ userId, name, permissions[] }` — **absent** (`null`) en contexte app (événement, planification, HTTP) et sur les surfaces du site public. `permissions` = droits accordés à l'installation **∩** droits RBAC de la personne. | | `visitor` | surfaces du site public (`siteBlock`/`sitePage`) : `{ memberId, name }` du membre du site connecté (jamais son e-mail), sinon `null`. `null` aussi hors du site. | | `install` | `{ id, version, config }` — `config` = [réglages déclarés](/dev/docs/donnees) (`settings`, secrets déchiffrés pour votre code seul) + champs de config des widgets. | | `subject` | `{ type: 'party', id }` pour un panneau, sinon `null`. | | `state` | l'état opaque renvoyé par votre précédent rendu/action (≤ 8 Ko, signé par la plateforme). | | `kv` (alias `storage`) | `get / put / delete / list` — clé/valeur cloisonné (votre app × l'organisation), capabilities `storage.tenant.ro/rw`. | | `data.` | `get / set / query / count / delete` sur les [collections déclarées](/dev/docs/donnees) au manifeste (typées, validées, quotas par formule) — capability `data.collections`. | | `files` | `put / get / url / list / delete` — [fichiers privés](/dev/docs/donnees) de l'app (≤ 5 Mo, route gardée) — capability `files.private`. | | `mail.send` | e-mail transactionnel en blocs à des personnes LIÉES à l'organisation (≤ 5, quota par jour) — capability `mail.send`, cf. [Moteurs](/dev/docs/moteurs). | | `notify.user / permission / admins` | notification dans Capibara (cloche + push, quota par jour) — capability `notify.send`. | | `calendar.project / remove / clear` | dates de l'app dans le calendrier de l'organisation (source `app:`) — capability `calendar.project`. | | `search.index / remove / clear` | fiches de l'app dans la recherche ⌘K — capability `search.index`. | | `approvals.request / get / cancel` | demande de validation à un humain, décision par l'événement `approval.decided` — capability `approvals.request`. | | `fetch(url, init?)` | HTTP sortant vers les hosts déclarés `http.fetch:` **uniquement** ; réponse `{ status, headers, bodyBase64, truncated }`. | | `log.info / warn / error` | journal d'app (200 lignes × 500 caractères par interaction), visible du développeur et de l'admin du tenant. | | `followup(result)` | après une réponse `{ ack: true }` : pousse le complément (≤ 15 minutes). | ## Les façades des modules — `ctx.capibara` Lire et écrire dans les modules de l'organisation passe par les [façades](/dev/docs/facades) : `await ctx.capibara.crm.contacts.list({ q })`, `ctx.capibara.billing.documents.createDraft({ … })`, etc. Chaque façade exige un [scope feuille](/dev/docs/permissions) déclaré ET accordé, et s'exécute sous la personne qui interagit (pages, actions) ou sous le compte de service de votre app (événements, planifications, HTTP) — droits, journal et notifications de Capibara compris. Pas de requête libre : le registre est le contrat. ## Le protocole d'interaction **Rendu** — votre handler renvoie un nœud (`ui.stack(…)`) ou un document `{ kit: 1, ui, title?, data?, components?, state? }`. Les gabarits (`{{ chemin }}`, `each`, `$if`, `$ref`) sont remplis avec `data`, puis le document est **validé** (schéma strict, bornes de la surface) avant d'être rendu avec les composants Capibara. Un document invalide n'est jamais affiché : l'écran dit « L'app n'a pas répondu » et le journal donne la raison. **Action** — un bouton `{ action: 'save', params }` ou la soumission d'un `form` appelle `actions.save`. La réponse combine librement : | Effet | Signification | |---|---| | `ui` (+ `data`, `components`, `title`) | remplace la surface par ce document | | `patch: { path, ui }` | remplace le nœud au chemin (`children.1.children.0`) | | `toast: { tone, text }` | message éphémère | | `navigate: '/crm/contacts/…'` | navigation interne (chemin re-sanitisé par la plateforme) | | `openForm: { key, params?, title? }` | ouvre `forms[key]` en modal — jamais sur le site public (dessinez le formulaire dans la surface elle-même) | | `close: true` | ferme le formulaire modal | | `refresh: true` | re-rend la surface | | `ack: true` | « bien reçu » — puis `ctx.followup(…)` dans les 15 min | | `state` | nouvel état opaque (≤ 8 Ko) | Un handler qui lève une exception renvoie une erreur propre (`{ ok: false, error }`) : l'utilisateur voit un message honnête, le journal garde le détail. ## Le site public : blocs et pages d'app Une app installée peut vivre sur le **site public** de l'organisation : des **blocs** que l'auteur du site pose dans ses pages depuis l'éditeur (« Ajouter » › « Vos apps »), et des **pages entières** à l'adresse choisie par l'organisation (Mon site › Apps). Mêmes handlers, même Kit, même validation — avec trois différences : - **Jamais de `viewer`** : personne du personnel n'est connecté sur le site. Le visiteur arrive dans `visitor` — `{ memberId, name }` s'il est connecté à son compte membre du site, `null` sinon. Ne montrez rien de privé, et traitez `params` (champs du bloc, sous-chemin, paramètres d'URL) comme des entrées non fiables. - **Compte de service** : votre code s'exécute sous le compte de service de l'app (`ctx.capibara.*` borné aux scopes consentis) — un formulaire public peut créer un contact CRM si le scope `crm.contacts:write` a été accordé. - **Actions** : boutons et formulaires du Kit fonctionnent (route publique, rate-limitée) ; `ui`, `patch`, `toast`, `refresh`, `navigate` et `ack` s'appliquent ; `openForm` n'existe pas sur le site (dessinez le formulaire dans la surface). Le rendu d'un visiteur anonyme est mis en cache **60 s** par (installation, surface, paramètres) ; un membre connecté est toujours rendu à la demande. Dans l'éditeur de site, l'aperçu est le vrai rendu de votre bloc (visiteur anonyme) ; ses actions y sont simulées. Le harnais de test rend ces surfaces comme la plateforme : `renderSurface(app, 'siteBlock', 'promo', t, { params, visitor: { memberId: 'm1', name: 'Zoé' } })`. ## Événements, planifications, HTTP entrant - **Événements** : déclarez `events: ["invoice.paid"]` (catalogue fermé, cf. [Webhooks sortants](/dev/docs/webhooks) pour la liste) et la capability `events.subscribe`. La plateforme livre chaque événement du tenant à votre handler par son ledger idempotent — sans webhook, sans serveur. Livraison **au moins une fois** : rendez vos handlers idempotents. - **Planifications** : `schedules: [{ key: "nightly", cron: "0 3 * * *" }]` (5 champs, heure de Paris). Intervalle minimum selon le plan du tenant : **Gratuit 1 h, Pro 15 min, Business 5 min**. Une seule exécution en vol ; une occurrence manquée n'en déclenche qu'une. - **HTTP entrant** : `http: ["/stripe-hook"]` expose une URL publique `/api/apps///` par installation (visible de l'admin du tenant dans Modules › Apps › Réglages, carte « Adresses entrantes » ; « Régénérer l'adresse » invalide l'ancienne, et une désinstallation aussi). Sans session, rate-limitée, corps ≤ 256 Ko, réponse JSON ou texte — jamais du Kit ni du HTML. ## Limites et journal - 15 s par interaction, corps ≤ 256 Ko, réponse ≤ 1 Mo, ≤ 100 appels broker par interaction ; un isolate par app, ≤ 8 interactions simultanées, **disjoncteur** (10 échecs en 5 min à ≥ 50 % → 5 min de suspension, visible dans le journal). La table complète des bornes et des codes d'erreur vit sur [Capabilities, bornes et erreurs](/dev/docs/capabilities). - Chaque interaction laisse une ligne dans le **journal de l'app** (kind, clé, statut, latence, erreur, vos `ctx.log`), consultable par l'admin de l'organisation (Modules › Apps) et conservée 7 jours. - Un isolate **pas encore monté** (configuration du runtime pas régénérée ou pas rechargée) est dit tel quel dans le journal — « L'isolate de test « clé@version » n'est pas monté dans le runtime… » — et la plateforme redemande sa configuration toute seule : ce n'est jamais une erreur de votre code. `capibara status` nomme l'étape qui bloque (cf. [La CLI capibara](/dev/docs/cli), « Si l'isolate ne se monte pas »). - Compatibilité : un module `{ fetch(request, env) }` (contrat v1) reste exécuté tel quel, mais ne peut plus contribuer de page — passez à `defineApp` + `view`. ## Backend externe — le même code, chez vous Vous préférez héberger votre logique ? Déclarez au manifeste `backend: { url }` (HTTPS, hôte public) **à la place** de `main` — les deux sont exclusifs. Capibara POSTe alors à cette URL les requêtes du protocole ci-dessus, signées et horodatées, et rend le Kit que vous renvoyez avec les mêmes bornes et le même disjoncteur ; avec le SDK, `createBackend` sert le MÊME `defineApp`. `ctx.capibara` passe par l'API publique ; KV, collections, fichiers, moteurs et `followup` restent réservés au code hébergé ; les organisations consentent à l'envoi de leurs interactions vers votre hôte et la review humaine est obligatoire. Tout est détaillé sur la page dédiée [Backend externe](/dev/docs/backend-externe). ## Tester - **En local, sans réseau** : le harnais `@capibara-dev/sdk/testing` exécute vos handlers avec un `ctx` simulé (KV, collections, fichiers, `fetch` et façades par faux déclarés, journal) — `createTestContext()`, `renderSurface()`, `runAction()`, `runEvent()`, `runSchedule()`, `runHttp()` + assertions sur le Kit rendu. Cf. [SDK](/dev/docs/sdk) et le test de l'exemple « Météo ». - **Kit Studio** (`/dev/kit-studio`) : vos documents rendus en direct dans chaque surface, avec des données d'exemple ; `capibara kit check ` applique le même validateur depuis le terminal. - **Sur une organisation de test** : `capibara dev --org ` bundle et déploie à chaque sauvegarde sur une installation de test (isolate dédié à votre version de test, journal en direct) — cf. [La CLI capibara](/dev/docs/cli). Depuis la fiche de l'app du portail, l'installation de test d'une version exécute son code hébergé dès qu'un bundle existe (déployé par la CLI, ou publié). --- ## Widgets déclaratifs ## Le principe Un widget **déclaratif** est la façon la plus légère d'apparaître sur l'accueil d'un tenant : vous ne livrez **ni page, ni code**. Vous décrivez le widget dans le manifeste — un `template` fourni par Capibara, d'éventuels champs `config` que l'utilisateur du tenant remplit (ex. une adresse), une `source` de données — et la plateforme fait tout le reste : 1. elle **collecte** la donnée côté serveur (fetch borné, HTTPS, host allowlisté par vos capabilities `http.fetch:`) ; 2. elle **rend** le widget avec ses propres composants, à la charte graphique Capibara — jamais d'iframe, jamais de site externe ; 3. elle **stocke** la configuration saisie par l'utilisateur sur son installation. Votre code n'y touche jamais (et n'existe d'ailleurs pas, pour un widget purement déclaratif). C'est le même esprit qu'un bot Discord : vous déclarez, la plateforme exécute. ## Déclaration dans le manifeste ```json { "capabilities": [ "ui.widget", "http.fetch:geocoding-api.open-meteo.com", "http.fetch:api.open-meteo.com" ], "contributes": { "widgets": [ { "key": "meteo", "title": "Météo", "kind": "declarative", "template": "weather", "config": [ { "key": "address", "label": "Votre ville ou adresse", "type": "text", "placeholder": "Paris", "required": true } ], "minHeight": 220 } ] } } ``` | Champ | Type | Règle | |---|---|---| | `kind` | `"declarative"` | obligatoire — distingue le widget déclaratif d'un widget `embedUrl`. | | `template` | string | `weather`, `kpi` ou `list` (catalogue plateforme, il s'étoffera). | | `config` | tableau | optionnel, max 6 champs — `{ key, label (≤ 60), type: "text"\|"number", placeholder?, required? }`. Saisis par l'utilisateur SUR le widget, stockés par la plateforme. | | `source` | objet | optionnel — `{ url, map? }` : URL HTTPS templatée avec les champs de config (`…?q={address}`) + mapping `champ de sortie → chemin dans la réponse JSON` (`"value": "data.count"`). | | `minHeight` | number | optionnel, 120-1200 px. | **Règle d'allowlist (bloquante à la validation)** : tout host appelé — celui de `source.url`, ou les hosts intégrés du template — doit être déclaré en capability `http.fetch:`. Le validateur du manifeste vous liste les capabilities manquantes. ## Les templates ### `weather` — météo (source intégrée) Aucune `source` à fournir : le template embarque Open-Meteo (géocodage de l'adresse saisie puis conditions actuelles — température, ressenti, vent, humidité, ciel, heure locale). Déclarez les deux hosts : `http.fetch:geocoding-api.open-meteo.com` et `http.fetch:api.open-meteo.com`. Champ de config attendu : `address` (requis). ### `kpi` — un chiffre clé Sans `source` : rend les valeurs de config `value` et `label` telles quelles (mode statique). Avec `source` : la réponse JSON est mappée via `map` (ex. `{ "value": "stats.total" }`) — chemins pointés, index de tableau autorisés (`results.0.name`). ### `list` — une liste d'éléments La `source` doit produire un champ `items` (via `map`, ex. `{ "items": "data.entries" }`) : tableau d'objets `{ title | name | label, subtitle? | description? }` — 6 éléments affichés au maximum. ## Ce que voit l'utilisateur - Il ajoute votre widget depuis « Personnaliser » › « Ajouter un widget » sur son accueil (rubrique **Apps** du sélecteur — le widget porte le nom de votre app). - Si un champ `required` n'est pas rempli, le widget affiche directement le petit formulaire de configuration ; ensuite, un bouton « Modifier » discret permet de changer la saisie (ex. changer de ville). - La donnée est rafraîchie à l'affichage (avec un cache client de quelques minutes) — prévoyez une `source` qui supporte des lectures régulières. ## Bornes d'exécution Le fetch plateforme applique les mêmes bornes que la sandbox : HTTPS obligatoire, host allowlisté, **redirections refusées**, timeout 10 s, réponse ≤ 512 Ko, JSON uniquement. Une source injoignable produit un message d'erreur sobre dans le widget — jamais de widget cassé. ## Exemple complet Le tutoriel [Démarrer](/dev/docs/demarrer) construit pas à pas un widget météo déclaratif (manifeste seul, sans code), l'installe en test puis le publie. L'app « Météo (exemple) », téléchargeable depuis l'[index de la documentation](/dev/docs), montre ensuite la version avec code hébergé (page et widget rendus par le Kit). --- ## Scopes et consentement de l'organisation ## Le principe Le tableau `permissions` du manifeste liste des **scopes** : un par accès réel à des données de l'organisation. Un scope s'écrit `ressource:action` avec une ressource **feuille** (`crm.contacts`, `shop.orders`, `billing-fr.documents`…) et une action `read` ou `write`. ```json { "permissions": ["crm.contacts:read", "crm.activities:write"] } ``` Deux règles, appliquées à la validation du manifeste : - **Jamais un module entier.** `crm:read` est refusé : par la hiérarchie des droits de Capibara, il donnerait tout `crm.*` d'un coup. Le message d'erreur nomme les scopes feuilles à demander à la place. - **Uniquement le catalogue ci-dessous.** Chaque scope accepté ouvre au moins une [façade](/dev/docs/facades) ; un scope hors catalogue n'ouvrirait rien, il est refusé. ## Le catalogue (généré) ### CRM | Scope | Ce que l'organisation accepte | |---|---| | `crm.contacts:read` | Lire vos contacts (nom, coordonnées, étiquettes, notes) | | `crm.contacts:write` | Créer et modifier des contacts | | `crm.companies:read` | Lire vos sociétés | | `crm.companies:write` | Créer et modifier des sociétés | | `crm.opportunities:read` | Lire vos opportunités (pipeline, montants) | | `crm.opportunities:write` | Créer et faire avancer des opportunités | | `crm.activities:read` | Lire l'historique et les tâches du CRM | | `crm.activities:write` | Ajouter des notes et des tâches dans le CRM | ### Facturation | Scope | Ce que l'organisation accepte | |---|---| | `billing-fr.documents:read` | Lire vos devis, factures et avoirs (statut, lignes, totaux) | | `billing-fr.documents:write` | Créer des brouillons de devis et de factures, les émettre et les envoyer | | `billing-fr.pos:read` | Lire vos encaissements par carte (statut, montant) | | `billing-fr.pos:write` | Créer des encaissements par carte (montant + libellé) réglés sur votre page de paiement | ### Boutique | Scope | Ce que l'organisation accepte | |---|---| | `shop.products:read` | Lire votre catalogue (produits, déclinaisons, stock vendable) | | `shop.products:write` | Modifier des produits (nom, description, prix, publication) | | `shop.orders:read` | Lire vos commandes | | `shop.orders:write` | Faire avancer vos commandes (expédiée, livrée) et poser un numéro de suivi | ### Projets | Scope | Ce que l'organisation accepte | |---|---| | `projects:read` | Lire vos projets et leurs tâches | | `projects.tasks:write` | Créer et déplacer des tâches, commenter, enregistrer du temps | ### Planning | Scope | Ce que l'organisation accepte | |---|---| | `planning.resources:read` | Lire vos ressources réservables | | `planning.bookings:read` | Lire vos réservations | | `planning.bookings:write` | Créer des réservations (mêmes gardes que la réservation en ligne) | ### Site | Scope | Ce que l'organisation accepte | |---|---| | `site.members:read` | Lire les membres de votre site (nom, e-mail, statut) | ### Formation | Scope | Ce que l'organisation accepte | |---|---| | `formation.catalogue:read` | Lire votre catalogue de formations | | `formation.sessions:read` | Lire vos sessions inter-entreprises et leurs inscriptions | ## Ce que voit l'administrateur À l'installation, l'écran de consentement affiche chaque scope **en français** (la colonne de droite ci-dessus), avec son module et l'identifiant technique en petit. Les scopes sont **tout ou rien** : l'app s'installe avec l'ensemble ou pas du tout (patron Discord / Shopify). Une version qui **ajoute** un scope n'est jamais appliquée automatiquement chez les organisations déjà installées : l'administrateur voit la liste avec les nouveaux scopes marqués « nouveau » et ré-accepte — ou reste sur sa version. Tant qu'il n'a pas ré-accepté, vos handlers ne s'exécutent pas et vos surfaces l'expliquent. ## Le compte de service À l'installation, Capibara crée dans l'organisation un **compte de service** `app:` : un utilisateur technique, masqué des listes, sans connexion possible, dont l'avatar est l'icône de votre app, et dont l'unique rôle porte exactement les scopes accordés. **Toute écriture de votre app passe par les services de la plateforme sous ce compte** — les mêmes que ceux d'un humain : contrôle des droits, journal d'activité (« App Météo a créé le contact Dupont »), notifications, événements de domaine. Il n'existe aucune seconde porte d'écriture. Deux contextes d'exécution : - **contexte utilisateur** — pages, panneaux, widgets, actions : les façades s'exécutent sous **la personne qui interagit**, bornée par vos scopes (une app ne fait jamais plus que l'humain qui clique) ; - **contexte app** — événements, planifications, HTTP entrant, backend externe : les façades s'exécutent sous le **compte de service**. ## « Utiliser l'app » Chaque app installée génère une ressource `app.` : `app.:read` = ouvrir ses pages, widgets et panneaux. Les rôles par défaut Manager et Employé la reçoivent à l'installation (l'Administrateur a le wildcard) ; pour un rôle personnalisé, l'administrateur coche « Utiliser l'app » dans *Mon organisation › Rôles*. Sans ce droit, l'app n'apparaît ni dans le menu, ni dans le sélecteur de widgets, ni sur les fiches. ## Revalidés en base, jamais en confiance À chaque appel de façade, la plateforme vérifie : scope déclaré dans le manifeste **et** accordé à l'installation **et** porté par l'acteur (compte de service ou personne) dans les droits de l'organisation. Un scope retiré (app désinstallée, module désactivé) est refusé immédiatement. ## Bonnes pratiques - **Un scope par usage réel** — lire les contacts pour un résumé = `crm.contacts:read`, pas `crm.contacts:write` « au cas où ». - **Lecture et écriture sont distinctes** — demandez `write` seulement si vous créez ou modifiez. - **Moins de scopes = review plus rapide et plus d'installations** : une longue liste fait hésiter. - **Expliquez les scopes inhabituels** dans votre fiche : un scope sans rapport visible avec l'app est un motif de refus fréquent en review. --- ## Les façades — l'API des modules ## Le principe Une façade = une opération nommée `module.entité.op` avec un contrat d'entrée et de sortie fixé par la plateforme. Il n'y a **pas de requête libre** : ce que le registre expose, rien d'autre. Chaque façade exige un [scope feuille](/dev/docs/permissions) et passe par les services de Capibara sous **l'acteur** (la personne qui interagit, ou le compte de service de votre app) — droits, journal, notifications et événements sont ceux d'un humain. ## Depuis le code hébergé — `ctx.capibara` ```ts import { defineApp, ui } from '@capibara-dev/sdk'; export default defineApp({ pages: { home: async ({ ctx }) => { const { items } = await ctx.capibara.crm.contacts.list({ q: 'dupont', take: 10 }); return ui.list({ items: items.map((c) => ({ title: c.displayName, subtitle: c.email ?? '' })) }); }, }, actions: { 'quote.create': async ({ ctx, form }) => { const doc = await ctx.capibara.billing.documents.createDraft({ type: 'QUOTE', partyId: String(form?.partyId), lines: [{ description: 'Prestation', quantity: 1, unitPriceCents: 45000 }], }); return { toast: { tone: 'success', text: `Brouillon ${doc.id} créé` }, navigate: `/facturation/documents/${doc.id}` }; }, }, }); ``` `ctx.capibara` est typé par le SDK (`AppApi`). Un scope manquant renvoie une erreur `scope_not_granted` qui nomme le scope à ajouter. ## Depuis votre backend — REST ```http POST /api/public/v1/crm/contacts/list Authorization: Bearer ck_live_… (clé API ou access token OAuth du dev) X-Capibara-Install: (l'installation visée) Content-Type: application/json { "q": "dupont", "take": 10 } ``` - `installId` vous est donné par [embed-context](/dev/docs/api-publique) (jeton d'iframe) ou par le portail ; il désigne l'organisation ET votre app. Seul le développeur de l'app peut agir au nom de ses installations. - Les façades de **lecture** s'appellent aussi en `GET` (l'entrée en query string) ; les **écritures** en `POST`, avec un en-tête `Idempotency-Key` recommandé (rejouer la même clé ne crée pas deux fois). - Réponse : `{ "ok": true, "result": … }` ou `{ "ok": false, "error": "", "message": "…" }` (+ `issues` sur une entrée invalide). - La clé du dev doit couvrir la famille du module (`crm:read`…) en plus du scope feuille accordé à l'installation. - Catalogue lisible par machine : `GET /api/public/v1/facades` (schémas JSON d'entrée et de sortie). - Deux quotas se cumulent : **120 requêtes / minute par clé** (comme le reste de l'API publique) et **120 appels / minute par installation**. Avec le SDK : `new CapibaraClient({ token }).install(installId).crm.contacts.list({ q })`. ## Codes d'erreur Communs aux deux transports (`ctx.capibara` lève une exception portant le code ; REST renvoie `{ ok: false, error, message }`) : | Code | HTTP | Sens | |---|---|---| | `unknown_facade` | 404 | Le nom n'existe pas dans le registre. | | `scope_not_granted` | 403 | Scope absent du manifeste ou non accordé par l'organisation (le message nomme le scope). | | `forbidden` | 403 | L'acteur (personne ou compte de service) n'a pas le droit dans l'organisation. | | `invalid_input` | 400 | L'entrée ne respecte pas le contrat (`issues` détaille). | | `conflict` / `not_found` / `precondition_failed` / `bad_request` | 409 / 404 / 412 / 400 | Règles métier du module (e-mail déjà connu, document émis…) — les codes des services de Capibara, en minuscules. | | `service_account_missing` | 412 | Compte de service absent (organisation en cours de mise à jour) : réinstallez. | | `bad_output` | 502 | La réponse du module ne correspond plus au contrat de la façade (à signaler). | | `internal` | 500 | Erreur interne (journalisée côté plateforme). | Propres au transport REST (avant même d'atteindre la façade) : | Code | HTTP | Sens | |---|---|---| | `unauthorized` | 401 | `Authorization` absent ou invalide. | | `key_scope_missing` | 403 | Votre clé ne couvre pas la famille du module (`crm:read`…). | | `missing_install` | 400 | En-tête `X-Capibara-Install` absent. | | `install_not_found` | 404 | Installation inconnue, inactive ou en pause. | | `forbidden` | 403 | L'installation n'est pas celle d'une de **vos** apps. | | `no_version` | 412 | Aucune version publiée pour cette installation. | | `consent_outdated` | 412 | La version demande de nouveaux scopes qu'un administrateur n'a pas encore acceptés. | | `killed` | 423 | Incident actif sur la version (kill switch). | | `method_not_allowed` | 405 | Façade d'écriture appelée en `GET`. | | `rate_limited` | 429 | Quota de la clé ou de l'installation dépassé (`Retry-After: 60`). | ## Pagination Les listes renvoient `items` et `nextCursor` : repassez `cursor` pour la page suivante ; `take` est borné (100 au plus). ## Référence (générée depuis le registre) ### CRM #### `crm.contacts.list` Lecture · scope `crm.contacts:read` Liste paginée des contacts (recherche nom / e-mail / téléphone, étiquettes, vue contacts ou clients). | Entrée | Type | Requis | |---|---|:-:| | `q` | texte | | | `view` | `contacts` · `clients` · `all` (défaut `"all"`) | | | `tags` | liste de texte | | | `cursor` | texte | | | `take` | nombre (défaut `40`) | | Sortie : `items` (liste de objets), `nextCursor` (texte), `total` (nombre). #### `crm.contacts.get` Lecture · scope `crm.contacts:read` Une fiche contact par identifiant. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | Sortie : `id` (texte), `kind` (texte), `displayName` (texte), `firstName` (texte), `lastName` (texte), `email` (texte), `phone` (texte), `jobTitle` (texte), `website` (texte), `siret` (texte), `vatNumber` (texte), `addressLine1` (texte), `addressLine2` (texte), `postalCode` (texte), `city` (texte), `country` (texte), `isCustomer` (booléen), `tags` (liste de texte), `companyId` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `crm.contacts.create` Écriture · scope `crm.contacts:write` Crée un contact (au moins un nom ou un e-mail ; un e-mail déjà connu = conflit qui nomme la fiche existante). | Entrée | Type | Requis | |---|---|:-:| | `firstName` | texte | | | `lastName` | texte | | | `email` | texte | | | `phone` | texte | | | `jobTitle` | texte | | | `companyId` | texte | | | `addressLine1` | texte | | | `addressLine2` | texte | | | `postalCode` | texte | | | `city` | texte | | | `country` | texte | | | `tags` | liste de texte | | | `notes` | texte | | | `isCustomer` | booléen | | Sortie : `id` (texte), `kind` (texte), `displayName` (texte), `firstName` (texte), `lastName` (texte), `email` (texte), `phone` (texte), `jobTitle` (texte), `website` (texte), `siret` (texte), `vatNumber` (texte), `addressLine1` (texte), `addressLine2` (texte), `postalCode` (texte), `city` (texte), `country` (texte), `isCustomer` (booléen), `tags` (liste de texte), `companyId` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `crm.contacts.update` Écriture · scope `crm.contacts:write` Met à jour un contact (seuls les champs fournis changent). | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `firstName` | texte | | | `lastName` | texte | | | `email` | texte | | | `phone` | texte | | | `jobTitle` | texte | | | `companyId` | texte | | | `addressLine1` | texte | | | `addressLine2` | texte | | | `postalCode` | texte | | | `city` | texte | | | `country` | texte | | | `tags` | liste de texte | | | `notes` | texte | | | `isCustomer` | booléen | | Sortie : `id` (texte), `kind` (texte), `displayName` (texte), `firstName` (texte), `lastName` (texte), `email` (texte), `phone` (texte), `jobTitle` (texte), `website` (texte), `siret` (texte), `vatNumber` (texte), `addressLine1` (texte), `addressLine2` (texte), `postalCode` (texte), `city` (texte), `country` (texte), `isCustomer` (booléen), `tags` (liste de texte), `companyId` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `crm.companies.list` Lecture · scope `crm.companies:read` Liste paginée des sociétés. | Entrée | Type | Requis | |---|---|:-:| | `q` | texte | | | `view` | `contacts` · `clients` · `all` (défaut `"all"`) | | | `tags` | liste de texte | | | `cursor` | texte | | | `take` | nombre (défaut `40`) | | Sortie : `items` (liste de objets), `nextCursor` (texte), `total` (nombre). #### `crm.companies.get` Lecture · scope `crm.companies:read` Une fiche société par identifiant. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | Sortie : `id` (texte), `kind` (texte), `displayName` (texte), `firstName` (texte), `lastName` (texte), `email` (texte), `phone` (texte), `jobTitle` (texte), `website` (texte), `siret` (texte), `vatNumber` (texte), `addressLine1` (texte), `addressLine2` (texte), `postalCode` (texte), `city` (texte), `country` (texte), `isCustomer` (booléen), `tags` (liste de texte), `companyId` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `crm.companies.create` Écriture · scope `crm.companies:write` Crée une société. | Entrée | Type | Requis | |---|---|:-:| | `name` | texte | oui | | `email` | texte | | | `phone` | texte | | | `website` | texte | | | `siret` | texte | | | `vatNumber` | texte | | | `addressLine1` | texte | | | `addressLine2` | texte | | | `postalCode` | texte | | | `city` | texte | | | `country` | texte | | | `tags` | liste de texte | | | `notes` | texte | | | `isCustomer` | booléen | | Sortie : `id` (texte), `kind` (texte), `displayName` (texte), `firstName` (texte), `lastName` (texte), `email` (texte), `phone` (texte), `jobTitle` (texte), `website` (texte), `siret` (texte), `vatNumber` (texte), `addressLine1` (texte), `addressLine2` (texte), `postalCode` (texte), `city` (texte), `country` (texte), `isCustomer` (booléen), `tags` (liste de texte), `companyId` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `crm.companies.update` Écriture · scope `crm.companies:write` Met à jour une société (seuls les champs fournis changent). | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `name` | texte | | | `email` | texte | | | `phone` | texte | | | `website` | texte | | | `siret` | texte | | | `vatNumber` | texte | | | `addressLine1` | texte | | | `addressLine2` | texte | | | `postalCode` | texte | | | `city` | texte | | | `country` | texte | | | `tags` | liste de texte | | | `notes` | texte | | | `isCustomer` | booléen | | Sortie : `id` (texte), `kind` (texte), `displayName` (texte), `firstName` (texte), `lastName` (texte), `email` (texte), `phone` (texte), `jobTitle` (texte), `website` (texte), `siret` (texte), `vatNumber` (texte), `addressLine1` (texte), `addressLine2` (texte), `postalCode` (texte), `city` (texte), `country` (texte), `isCustomer` (booléen), `tags` (liste de texte), `companyId` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `crm.opportunities.list` Lecture · scope `crm.opportunities:read` Les opportunités visibles par l'acteur (≤ 1000, les plus récentes d'abord). | Entrée | Type | Requis | |---|---|:-:| | `stage` | `NEW` · `QUALIFIED` · `PROPOSAL` · `NEGOTIATION` · `WON` · `LOST` | | Sortie : `items` (liste de objets). #### `crm.opportunities.create` Écriture · scope `crm.opportunities:write` Crée une opportunité (référence OPP attribuée par la plateforme). | Entrée | Type | Requis | |---|---|:-:| | `title` | texte | oui | | `partyId` | texte | | | `contactPartyId` | texte | | | `amountCents` | nombre (défaut `0`) | | | `currency` | texte (défaut `"EUR"`) | | | `stage` | `NEW` · `QUALIFIED` · `PROPOSAL` · `NEGOTIATION` · `WON` · `LOST` (défaut `"NEW"`) | | | `probability` | nombre (défaut `50`) | | | `source` | texte | | | `closeDate` | date (ISO 8601) | | | `notes` | texte | | Sortie : `id` (texte), `reference` (texte), `title` (texte), `partyId` (texte), `contactPartyId` (texte), `ownerId` (texte), `amountCents` (nombre), `currency` (texte), `stage` (texte), `probability` (nombre), `source` (texte), `closeDate` (date (ISO 8601) ou null), `lostReason` (texte), `notes` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `crm.opportunities.moveStage` Écriture · scope `crm.opportunities:write` Fait avancer (ou perdre, avec motif) une opportunité. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `stage` | `NEW` · `QUALIFIED` · `PROPOSAL` · `NEGOTIATION` · `WON` · `LOST` | oui | | `lostReason` | texte | | Sortie : `id` (texte), `reference` (texte), `title` (texte), `partyId` (texte), `contactPartyId` (texte), `ownerId` (texte), `amountCents` (nombre), `currency` (texte), `stage` (texte), `probability` (nombre), `source` (texte), `closeDate` (date (ISO 8601) ou null), `lostReason` (texte), `notes` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `crm.activities.list` Lecture · scope `crm.activities:read` Historique et tâches d'un contact ou d'une opportunité (≤ 200, récentes d'abord). | Entrée | Type | Requis | |---|---|:-:| | `partyId` | texte | | | `opportunityId` | texte | | Sortie : `items` (liste de objets). #### `crm.activities.create` Écriture · scope `crm.activities:write` Ajoute une note, un appel, un e-mail, un rendez-vous ou une tâche (rattaché à un contact ou une opportunité). | Entrée | Type | Requis | |---|---|:-:| | `type` | `CALL` · `MEETING` · `EMAIL` · `NOTE` · `TASK` (défaut `"NOTE"`) | | | `subject` | texte | oui | | `notes` | texte | | | `partyId` | texte | | | `opportunityId` | texte | | | `scheduledAt` | date (ISO 8601) | | | `dueAt` | date (ISO 8601) | | Sortie : `id` (texte), `type` (texte), `subject` (texte), `notes` (texte), `scheduledAt` (date (ISO 8601) ou null), `dueAt` (date (ISO 8601) ou null), `completedAt` (date (ISO 8601) ou null), `partyId` (texte), `opportunityId` (texte), `assigneeId` (texte), `createdAt` (date (ISO 8601)). ### Facturation #### `billing.documents.list` Lecture · scope `billing-fr.documents:read` Liste paginée des devis, factures et avoirs (statut effectif, nom du client, totaux). | Entrée | Type | Requis | |---|---|:-:| | `type` | `QUOTE` · `INVOICE` · `CREDIT_NOTE` · `DEPOSIT_INVOICE` | | | `status` | texte | | | `q` | texte | | | `cursor` | texte | | | `take` | nombre (défaut `30`) | | Sortie : `items` (liste de objets), `nextCursor` (texte). #### `billing.documents.get` Lecture · scope `billing-fr.documents:read` Un document avec ses lignes, ses totaux et les avoirs qui le couvrent. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | Sortie : `id` (texte), `type` (texte), `status` (texte), `number` (texte), `currency` (texte), `finalizedAt` (date (ISO 8601) ou null), `issuedAt` (date (ISO 8601) ou null), `sentAt` (date (ISO 8601) ou null), `dueDate` (date (ISO 8601) ou null), `paidAt` (date (ISO 8601) ou null), `validUntil` (date (ISO 8601) ou null), `acceptedAt` (date (ISO 8601) ou null), `totalHtCents` (nombre), `totalTvaCents` (nombre), `totalTtcCents` (nombre), `discountBps` (nombre), `notes` (texte), `partyId` (texte), `buyerName` (texte), `relatedDocumentId` (texte), `opportunityId` (texte), `projectId` (texte), `creditedCents` (nombre), `lines` (liste de objets), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `billing.documents.createDraft` Écriture · scope `billing-fr.documents:write` Crée un BROUILLON de devis ou de facture (client par fiche CRM ou saisi) — jamais émis d'office. | Entrée | Type | Requis | |---|---|:-:| | `type` | `QUOTE` · `INVOICE` | oui | | `partyId` | texte | | | `buyer` | objet | | | `lines` | liste de objets | oui | | `notes` | texte | | | `dueDate` | date (ISO 8601) | | | `validUntil` | date (ISO 8601) | | | `discountBps` | nombre (défaut `0`) | | | `opportunityId` | texte | | | `projectId` | texte | | Sortie : `id` (texte), `type` (texte), `status` (texte), `number` (texte), `currency` (texte), `finalizedAt` (date (ISO 8601) ou null), `issuedAt` (date (ISO 8601) ou null), `sentAt` (date (ISO 8601) ou null), `dueDate` (date (ISO 8601) ou null), `paidAt` (date (ISO 8601) ou null), `validUntil` (date (ISO 8601) ou null), `acceptedAt` (date (ISO 8601) ou null), `totalHtCents` (nombre), `totalTvaCents` (nombre), `totalTtcCents` (nombre), `discountBps` (nombre), `notes` (texte), `partyId` (texte), `buyerName` (texte), `relatedDocumentId` (texte), `opportunityId` (texte), `projectId` (texte), `creditedCents` (nombre), `lines` (liste de objets), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `billing.documents.finalize` Écriture · scope `billing-fr.documents:write` Émet un brouillon (numéro attribué, archive PDF + Factur-X) ; e-mail au client si une adresse est connue. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `sendEmail` | booléen (défaut `true`) | | Sortie : `id` (texte), `type` (texte), `status` (texte), `number` (texte), `currency` (texte), `finalizedAt` (date (ISO 8601) ou null), `issuedAt` (date (ISO 8601) ou null), `sentAt` (date (ISO 8601) ou null), `dueDate` (date (ISO 8601) ou null), `paidAt` (date (ISO 8601) ou null), `validUntil` (date (ISO 8601) ou null), `acceptedAt` (date (ISO 8601) ou null), `totalHtCents` (nombre), `totalTvaCents` (nombre), `totalTtcCents` (nombre), `discountBps` (nombre), `notes` (texte), `partyId` (texte), `buyerName` (texte), `relatedDocumentId` (texte), `opportunityId` (texte), `projectId` (texte), `creditedCents` (nombre), `lines` (liste de objets), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `billing.documents.send` Écriture · scope `billing-fr.documents:write` Envoie un document ÉMIS au client par e-mail (adresse de la fiche, ou fournie). | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `email` | texte | | Sortie : `ok` (booléen), `toEmail` (texte). #### `billing.documents.payLink` Écriture · scope `billing-fr.documents:write` Lien de paiement en ligne d'une facture ÉMISE (ou d'une échéance) sur la page de paiement de l'organisation ; `returnUrl` (domaine déclaré dans `returnHosts`) ajoute un bouton de retour vers votre site après règlement. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `installmentId` | texte | | | `returnUrl` | texte | | Sortie : `url` (texte), `path` (texte). #### `billing.charges.create` Écriture · scope `billing-fr.pos:write` Crée un encaissement par carte (montant TTC + libellé) que le client règle sur la page de paiement de l'organisation — même rail que le TPE virtuel, valable 5 à 15 min ; `returnUrl` = bouton de retour vers votre site après règlement. | Entrée | Type | Requis | |---|---|:-:| | `amountCents` | nombre | oui | | `label` | texte | | | `ttlMinutes` | nombre | | | `returnUrl` | texte | | Sortie : `id` (texte), `code` (texte), `formattedCode` (texte), `amountCents` (nombre), `currency` (texte), `expiresAt` (date (ISO 8601)), `url` (texte). #### `billing.charges.get` Lecture · scope `billing-fr.pos:read` État d'un encaissement par carte (en attente, payé, expiré, annulé) — à interroger après le retour du client, ou écouter l'événement `pos.charge.paid`. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | Sortie : `id` (texte), `status` (texte), `amountCents` (nombre), `currency` (texte), `paidAt` (date (ISO 8601) ou null), `expiresAt` (date (ISO 8601)). ### Boutique #### `shop.products.list` Lecture · scope `shop.products:read` Catalogue paginé (60 par page) avec le stock VENDABLE fusionné de chaque produit. | Entrée | Type | Requis | |---|---|:-:| | `q` | texte | | | `status` | `all` · `published` · `draft` (défaut `"all"`) | | | `cursor` | texte | | Sortie : `items` (liste de objets), `nextCursor` (texte). #### `shop.products.get` Lecture · scope `shop.products:read` Un produit avec ses déclinaisons et ses images. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | Sortie : `id` (texte), `sku` (texte), `name` (texte), `slug` (texte), `description` (texte), `priceCents` (nombre), `vatRateBps` (nombre), `currency` (texte), `isPublished` (booléen), `isVirtual` (booléen), `ean` (texte), `categoryId` (texte), `brandId` (texte), `variants` (liste de objets), `images` (liste de objets), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `shop.products.update` Écriture · scope `shop.products:write` Modifie un produit : nom, description, prix HT, TVA, publication (jamais le stock — il vit dans les mouvements). | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `name` | texte | | | `description` | texte | | | `priceCents` | nombre | | | `vatRateBps` | nombre | | | `isPublished` | booléen | | Sortie : `id` (texte), `sku` (texte), `name` (texte), `slug` (texte), `priceCents` (nombre), `vatRateBps` (nombre), `currency` (texte), `isPublished` (booléen), `isVirtual` (booléen), `ean` (texte), `categoryId` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `shop.orders.list` Lecture · scope `shop.orders:read` Les commandes (récentes d'abord), filtrables par statut. | Entrée | Type | Requis | |---|---|:-:| | `status` | `PENDING` · `PAID` · `SHIPPED` · `DELIVERED` · `CANCELED` · `REFUNDED` | | | `take` | nombre (défaut `50`) | | Sortie : `items` (liste de objets). #### `shop.orders.get` Lecture · scope `shop.orders:read` Une commande avec ses lignes. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | Sortie : `id` (texte), `number` (texte), `status` (texte), `channel` (texte), `currency` (texte), `customerEmail` (texte), `customerName` (texte), `customerPartyId` (texte), `totalCents` (nombre), `totalHtCents` (nombre), `totalVatCents` (nombre), `shippingCents` (nombre), `discountCents` (nombre), `paidAmountCents` (nombre), `paidAt` (date (ISO 8601) ou null), `trackingNumber` (texte), `trackingCarrier` (texte), `items` (liste de objets), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `shop.orders.setStatus` Écriture · scope `shop.orders:write` Passe une commande en expédiée ou livrée (le client est prévenu à l'expédition). Jamais payée/remboursée : ce sont des flux d'argent. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `status` | `SHIPPED` · `DELIVERED` | oui | Sortie : `id` (texte), `number` (texte), `status` (texte), `channel` (texte), `currency` (texte), `customerEmail` (texte), `customerName` (texte), `customerPartyId` (texte), `totalCents` (nombre), `totalHtCents` (nombre), `totalVatCents` (nombre), `shippingCents` (nombre), `discountCents` (nombre), `paidAmountCents` (nombre), `paidAt` (date (ISO 8601) ou null), `trackingNumber` (texte), `trackingCarrier` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). #### `shop.orders.setTracking` Écriture · scope `shop.orders:write` Pose le numéro et le transporteur d'une expédition (repris dans l'e-mail « expédiée »). | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `trackingNumber` | texte ou null | oui | | `trackingCarrier` | texte ou null | | Sortie : `id` (texte), `number` (texte), `status` (texte), `channel` (texte), `currency` (texte), `customerEmail` (texte), `customerName` (texte), `customerPartyId` (texte), `totalCents` (nombre), `totalHtCents` (nombre), `totalVatCents` (nombre), `shippingCents` (nombre), `discountCents` (nombre), `paidAmountCents` (nombre), `paidAt` (date (ISO 8601) ou null), `trackingNumber` (texte), `trackingCarrier` (texte), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)). ### Projets #### `projects.list` Lecture · scope `projects:read` Les projets (≤ 300, récents d'abord) avec leur avancement. | Entrée | Type | Requis | |---|---|:-:| | `status` | `OPEN` · `ALL` · `ACTIVE` · `ON_HOLD` · `DONE` · `ARCHIVED` (défaut `"OPEN"`) | | | `search` | texte | | Sortie : `items` (liste de objets). #### `projects.get` Lecture · scope `projects:read` Un projet avec ses colonnes et ses tâches. | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | Sortie : `id` (texte), `reference` (texte), `name` (texte), `status` (texte), `clientPartyId` (texte), `ownerId` (texte), `billingMode` (texte), `startDate` (date (ISO 8601) ou null), `endDate` (date (ISO 8601) ou null), `completedAt` (date (ISO 8601) ou null), `createdAt` (date (ISO 8601)), `updatedAt` (date (ISO 8601)), `stages` (liste de objets), `tasks` (liste de objets). #### `projects.tasks.create` Écriture · scope `projects.tasks:write` Crée une tâche dans un projet (colonne d'entrée par défaut). | Entrée | Type | Requis | |---|---|:-:| | `projectId` | texte | oui | | `title` | texte | oui | | `stageId` | texte | | | `description` | texte | | | `ownerId` | texte | | | `dueDate` | texte | | | `estimateMinutes` | nombre | | Sortie : `id` (texte). #### `projects.tasks.move` Écriture · scope `projects.tasks:write` Déplace une tâche dans une autre colonne (le statut suit la colonne). | Entrée | Type | Requis | |---|---|:-:| | `id` | texte | oui | | `stageId` | texte | oui | Sortie : `ok` (booléen). #### `projects.tasks.comment` Écriture · scope `projects.tasks:write` Poste un commentaire sur une tâche (fil de la tâche, notifications habituelles). | Entrée | Type | Requis | |---|---|:-:| | `taskId` | texte | oui | | `body` | texte | oui | Sortie : `ok` (booléen). #### `projects.time.log` Écriture · scope `projects.tasks:write` Enregistre du temps sur une tâche, au nom de l'acteur (compte de service ou personne). | Entrée | Type | Requis | |---|---|:-:| | `taskId` | texte | oui | | `minutes` | nombre | oui | | `date` | texte | | | `description` | texte | | | `billable` | booléen | | Sortie : `id` (texte). ### Planning #### `planning.resources.list` Lecture · scope `planning.resources:read` Les ressources réservables (salles, personnes, matériel) et leur mode de paiement. Aucune entrée. Sortie : `items` (liste de objets). #### `planning.bookings.list` Lecture · scope `planning.bookings:read` Les réservations qui croisent une fenêtre [from, to], filtrables par ressource et statut. | Entrée | Type | Requis | |---|---|:-:| | `from` | date (ISO 8601) | | | `to` | date (ISO 8601) | | | `resourceId` | texte | | | `status` | `SCHEDULED` · `CONFIRMED` · `CANCELLED` · `DONE` | | Sortie : `items` (liste de objets). #### `planning.bookings.create` Écriture · scope `planning.bookings:write` Crée une réservation (conflit de créneau refusé, confirmation e-mail au client rattaché). | Entrée | Type | Requis | |---|---|:-:| | `title` | texte | oui | | `resourceId` | texte | | | `clientPartyId` | texte | | | `startsAt` | date (ISO 8601) | oui | | `endsAt` | date (ISO 8601) | oui | | `notes` | texte | | Sortie : `id` (texte), `title` (texte), `resourceId` (texte), `clientPartyId` (texte), `assigneeUserId` (texte), `startsAt` (date (ISO 8601)), `endsAt` (date (ISO 8601)), `status` (texte), `notes` (texte), `priceCents` (nombre), `paymentStatus` (texte), `createdAt` (date (ISO 8601)). ### Site #### `site.members.list` Lecture · scope `site.members:read` Les membres du site public (comptes clients), paginés, filtrables par statut et recherche. | Entrée | Type | Requis | |---|---|:-:| | `search` | texte | | | `status` | `ACTIVE` · `PENDING` · `BLOCKED` | | | `cursor` | texte | | | `take` | nombre (défaut `30`) | | Sortie : `items` (liste de objets), `nextCursor` (texte). ### Formation #### `formation.catalogue.list` Lecture · scope `formation.catalogue:read` Le catalogue de formations (actives ; archivées sur demande). | Entrée | Type | Requis | |---|---|:-:| | `includeArchived` | booléen (défaut `false`) | | Sortie : `items` (liste de objets). #### `formation.sessions.list` Lecture · scope `formation.sessions:read` Les sessions inter-entreprises (à venir par défaut) avec places restantes et inscriptions payées. | Entrée | Type | Requis | |---|---|:-:| | `productId` | texte | | | `includePast` | booléen (défaut `false`) | | Sortie : `items` (liste de objets). --- ## Données : collections, fichiers, réglages ## Le principe Une app Capibara ne possède pas de base de données : **ses données vivent dans l'organisation qui l'a installée**, cloisonnées par app. Trois familles, toutes servies par `ctx` (code hébergé) : | Famille | `ctx` | Capability | Pour quoi | |---|---|---|---| | **Collections** | `ctx.data.` | `data.collections` | des enregistrements typés, déclarés au manifeste (scores, favoris, tickets…) | | **Clé/valeur** | `ctx.kv` | `storage.tenant.ro` / `.rw` | curseurs, caches, petits réglages (32 Ko / 200 clés) | | **Fichiers privés** | `ctx.files` | `files.private` | pièces jointes, exports, images générées (≤ 5 Mo) | Et une quatrième, saisie par un **administrateur** de l'organisation, jamais par votre code : les **réglages** (`settings` du manifeste → `ctx.install.config`), avec des champs `secret` chiffrés au repos. Conséquences, toutes voulues : la donnée est **supprimée avec l'organisation**, **incluse dans son export RGPD**, **conservée 30 jours** après une désinstallation (réinstaller la retrouve) puis **purgée** par la plateforme — l'admin peut aussi purger tout de suite depuis la fiche de l'app. Vous ne gérez ni migration, ni sauvegarde, ni DDL : le manifeste est le contrat. ## Déclarer des collections ```json { "capabilities": ["data.collections"], "collections": { "favorites": { "fields": { "city": "string", "addedAt": "date" } }, "scores": { "fields": { "partyId": "string", "value": "number", "label": "string", "meta": "json" }, "indexes": ["partyId"] } } } ``` - Types de champ : `string` (≤ 20 000 caractères), `number`, `boolean`, `date` (ISO 8601, normalisée à l'écriture), `json` (valeur libre ≤ 16 Ko). - Au plus **10 collections** et **30 champs** par collection ; noms = identifiants simples (`a-z` puis lettres/chiffres/`_`). Le nom `$files` est réservé. - `indexes` est documentaire : les égalités sont déjà indexées (GIN). - Requiert `main` : seules les apps hébergées y accèdent — un [backend externe](/dev/docs/backend-externe) n'a ni collections, ni KV, ni fichiers (le manifeste les refuse sans `main`). Toute écriture est **validée contre la déclaration** : un champ non déclaré, un type faux ou un enregistrement > 64 Ko sont refusés avec un message qui nomme le champ. Un `null` est accepté partout (champ vide). ## Lire et écrire — `ctx.data` ```ts // Créer ou remplacer (clé fournie) — la clé est générée (« rec_… ») si absente. const fav = await ctx.data.favorites.set({ city: 'Lyon', addedAt: new Date().toISOString() }, 'lyon'); // Lire une ligne par sa clé. const row = await ctx.data.favorites.get('lyon'); // { id, key, data, createdAt, updatedAt } | null // Interroger : where + orderBy + curseur, ≤ 100 lignes par page. const page = await ctx.data.scores.query({ where: { partyId: 'p_123', value: { gte: 10 } }, orderBy: { field: 'createdAt', dir: 'desc' }, limit: 20, }); const next = page.nextCursor ? await ctx.data.scores.query({ where: { partyId: 'p_123' }, cursor: page.nextCursor }) : null; // Compter, supprimer. const { count } = await ctx.data.scores.count({ partyId: 'p_123' }); await ctx.data.favorites.delete('lyon'); ``` Opérateurs de `where` par type (au plus **5 conditions**, `in` ≤ 20 valeurs) : | Type | Opérateurs | |---|---| | `string` | `eq`, `ne`, `in`, `contains` | | `number` | `eq`, `ne`, `in`, `gt`, `gte`, `lt`, `lte` | | `date` | `eq`, `ne`, `gt`, `gte`, `lt`, `lte` | | `boolean` | `eq`, `ne` | | `json` | aucun (stockage seulement) | `{ champ: valeur }` vaut `{ champ: { eq: valeur } }`. Le tri porte sur `updatedAt` (défaut, décroissant), `createdAt` ou `key` — le tri par champ de données viendra plus tard ; en attendant, triez la page côté code ou utilisez la clé. **Quota de lignes par app installée** (toutes collections) : 5 000 (Gratuit), 100 000 (Pro), 1 000 000 (Business). Au-delà, `set` d'une NOUVELLE clé échoue avec un message clair — remplacer une ligne existante passe toujours. ## Fichiers privés — `ctx.files` ```json { "capabilities": ["files.private"] } ``` ```ts const f = await ctx.files.put('rapport.pdf', pdfBytes); // Uint8Array, ArrayBuffer ou base64 // f = { id, name, contentType, size, url, createdAt } return ui.link({ label: 'Télécharger le rapport', href: f.url }); // ou ui.image({ src: f.url, alt: '…' }) const { dataBase64 } = await ctx.files.get(f.id); const { files } = await ctx.files.list(); await ctx.files.delete(f.id); ``` - Types acceptés : `png`, `jpg`, `webp`, `gif` (vérifiés par leurs octets de signature), `pdf`, `csv`, `txt`, `md`, `json` — ≤ **5 Mo** par fichier, 500 fichiers par installation ; l'espace compte dans le **quota de stockage de la formule** de l'organisation (comme sa médiathèque). - `url` est un chemin **relatif** vers une route gardée : seule une personne connectée à l'organisation ET autorisée à « utiliser l'app » peut l'ouvrir. Jamais d'URL publique, jamais de lien devinable. ## Réglages — `settings` ```json { "settings": { "fields": [ { "key": "defaultCity", "label": "Ville par défaut", "type": "text", "placeholder": "Paris" }, { "key": "mode", "label": "Mode", "type": "select", "options": [{ "value": "simple", "label": "Simple" }, { "value": "expert", "label": "Expert" }] }, { "key": "apiKey", "label": "Clé API du service tiers", "type": "secret", "required": true, "help": "Trouvez-la dans votre compte du service." } ] } } ``` - Types : `text`, `textarea`, `number`, `boolean`, `select` (avec `options`), `secret`. Au plus 20 champs. - Un **administrateur** remplit ces réglages sur la fiche de l'app (« Réglages de l'app ») ; votre code les lit dans `ctx.install.config` (`ctx.install.config.defaultCity`). - Un champ `secret` est **chiffré au repos** (contexte imposé par la plateforme) et **jamais renvoyé à l'écran** : l'admin voit « défini » et peut le remplacer ; seul votre code hébergé reçoit la valeur en clair. Ne le journalisez pas (`ctx.log` est visible de l'admin). - Les champs `config` des widgets continuent d'arriver dans le même `ctx.install.config` ; en cas de clé identique, le réglage déclaré prime. ## Cycle de vie, export, test - **Désinstallation** : tout est conservé 30 jours (l'organisation voit « Données conservées » sur la fiche, avec « Effacer maintenant ») ; passé ce délai, la plateforme purge lignes, fichiers, KV et réglages. - **Export** : l'admin exporte les données de votre app en JSON depuis la fiche ; elles font aussi partie de l'export RGPD de l'organisation (collections + métadonnées des fichiers + KV). - **Pendant le développement** : la section **Données** de votre app (portail) montre les collections, le KV et les fichiers de vos installations de **test**, avec suppression ligne à ligne — jamais ceux d'une installation réelle. Retirer une install de test efface ses données. --- ## Moteurs : e-mail, notifications, calendrier, recherche, validations ## Le principe Une app n'envoie pas d'e-mail, ne pousse pas de notification et n'écrit pas dans le calendrier **elle-même** : elle demande à Capibara de le faire, par `ctx`, et la plateforme applique ses règles (destinataires liés à l'organisation, désinscription, quotas, liens sanitisés, droits d'accès). Chaque moteur correspond à une **capability** du manifeste — sans elle, l'appel est refusé — et exige du code hébergé (`main`). | Moteur | `ctx.…` | Capability | Quota (par installation, par jour UTC) | |---|---|---|---| | E-mail transactionnel | `ctx.mail.send` | `mail.send` | Gratuit 20 · Pro 200 · Business 1 000 | | Notifications | `ctx.notify.user / permission / admins` | `notify.send` | Gratuit 200 · Pro 2 000 · Business 10 000 | | Calendrier | `ctx.calendar.project / remove / clear` | `calendar.project` | 500 projections par app | | Recherche ⌘K | `ctx.search.index / remove / clear` | `search.index` | 2 000 fiches par app | | Validations | `ctx.approvals.request / get / cancel` | `approvals.request` | 200 demandes en attente par app | Un quota atteint renvoie une erreur explicite (`Quota … atteint`) — votre code la reçoit comme une exception, le journal de l'app la garde. Les quotas vivent dans un réglage de la plateforme et peuvent évoluer sans nouvelle version de votre app. --- ## E-mail transactionnel — `ctx.mail.send` La règle : **jamais un module qui spamme**. Un e-mail d'app est un message *transactionnel* adressé à une personne qui a une relation avec l'organisation — jamais une campagne (la newsletter reste le module Newsletter de l'organisation, avec ses propres règles). ```ts await ctx.mail.send({ to: [{ userId: viewer.userId }, { partyId: contact.id }], subject: 'Votre relevé de la semaine', blocks: [ { type: 'title', text: 'Relevé hebdomadaire' }, { type: 'text', text: 'Bonjour,\n\nvoici le résumé de la semaine.' }, { type: 'meta', items: [{ label: 'Période', value: '1–7 septembre' }] }, { type: 'summary', rows: [{ label: 'Total', value: '12 interventions', strong: true }] }, { type: 'button', label: 'Ouvrir le détail', href: '/apps/mon-app/releves' }, { type: 'note', text: 'Ce message est envoyé automatiquement chaque lundi.' }, ], key: 'releve.hebdo', }); // → { ok: true, queued: 2, suppressed: 0, remainingToday: 198 } ``` **Destinataires** (`to`, ≤ 5 par appel) — chacun doit être **lié** à l'organisation : | Forme | Résolu vers | |---|---| | `{ userId }` | un utilisateur actif de l'espace (ex. `viewer.userId`) | | `{ partyId }` | une fiche CRM (contact ou société) qui a un e-mail et n'est pas anonymisée | | `{ memberId }` | un membre actif du site de l'organisation | | `{ email }` | une adresse qui figure dans l'une de ces trois tables — sinon refus `not_related` | **Contenu en blocs** — jamais de HTML libre. Le texte est échappé, les liens des boutons sont vérifiés : chemin interne de Capibara (`/apps/…`), `https://`, `mailto:` ou `tel:` ; tout autre lien rend le bouton en simple texte. L'e-mail est habillé par la **coque de l'organisation** (logo, couleur), signé par l'identité d'expéditeur de la plateforme (jamais par votre app), et porte en pied « Message envoyé par l'app « X » installée par » avec un lien de préférences. **Ce que fait la plateforme** : file d'envoi de l'organisation (priorité intermédiaire — après le transactionnel de Capibara et du tenant, avant les campagnes), en-têtes de désinscription en un clic (`List-Unsubscribe`), catégorie de préférences propre à votre app (`app.`) — une personne peut couper les e-mails de **votre** app sans toucher au reste ; ces adresses sont écartées avant l'envoi (`suppressed`) et ne consomment pas le quota. Plafond existant de 4 sollicitations par destinataire et par 7 jours, toutes apps et modules confondus. Pièces jointes : pas en v1 (utilisez un bouton vers `ctx.files.url(id)`). --- ## Notifications — `ctx.notify` Une notification apparaît dans la cloche de Capibara (et en push sur l'application installée), sous le type `app..`, avec l'icône des apps. Trois cibles : ```ts await ctx.notify.user(viewer.userId, { title: 'Export prêt', link: '/apps/mon-app/exports' }); await ctx.notify.permission('crm.contacts:write', { title: '3 fiches à vérifier', severity: 'warning', key: 'a-verifier' }); await ctx.notify.admins({ title: 'Clé API expirée', body: 'Renseignez une nouvelle clé dans les réglages de l’app.', severity: 'destructive' }); ``` - `user` : une personne de l'espace (jamais un compte de service). - `permission` : toutes les personnes dont les rôles couvrent `ressource:action` (≤ 50, les administrateurs compris). - `admins` : les administrateurs de l'organisation. - `link` doit être un **chemin interne** (défaut : la page de votre app). - Le mode « Ne pas déranger » de chacun est respecté (persistée, sans push). --- ## Calendrier — `ctx.calendar` Vos dates apparaissent dans le calendrier de l'organisation, badge « App », entrée de légende « Apps », source `app:` — en lecture (la fiche renvoie vers votre app pour qui a le droit « utiliser l'app »). ```ts await ctx.calendar.project({ id: 'inspection:42', // stable : reprojeter le même id met à jour title: 'Inspection annuelle — site de Lyon', startsAt: '2026-10-01T09:00:00.000Z', endsAt: '2026-10-01T12:00:00.000Z', // défaut : +1 h (ou la journée si allDay) location: 'Lyon', color: '#7c3aed', visibility: 'ORG', // ou 'PRIVATE' + ownerUserId }); await ctx.calendar.remove('inspection:42'); await ctx.calendar.clear(); // toutes les projections de l'app ``` Bornes : 500 projections par app, 366 jours de durée maximum, titre 200 caractères, description 2 000. Une projection `PRIVATE` n'est visible que de son propriétaire. --- ## Recherche ⌘K — `ctx.search` Rendez vos fiches trouvables dans la recherche transversale de l'organisation : un groupe au nom de votre app, visible des personnes qui ont « utiliser l'app » (`app.:read`). Sans Meilisearch, le repli base de données cherche dans le texte replié (accents et casse ignorés). ```ts await ctx.search.index({ id: 'client:12', title: 'Dupont & fils', subtitle: 'Client premium', text: 'Contrat 2026, Lyon', href: '/apps/mon-app/clients/12' }); await ctx.search.remove('client:12'); ``` Bornes : 2 000 fiches par app, texte 2 000 caractères, `href` interne (défaut : la page de l'app). Les fiches vivent chez l'organisation (collection réservée `$search`) et disparaissent avec la désinstallation. --- ## Validations — `ctx.approvals` Votre app peut demander à un humain de trancher : la demande arrive dans la cloche **Validations** de Capibara (titre « Nom de l'app · votre titre »), et la décision revient à votre code par l'événement `approval.decided` — déclarez-le dans `events` du manifeste. ```ts // Demander (une seule demande EN ATTENTE par sujet + subjectId ; la seconde renvoie la première) const a = await ctx.approvals.request({ subject: 'refund', // kebab-case → sujet app..refund subjectId: 'order:42', title: 'Rembourser 120 € à Dupont ?', summary: 'Retour reçu le 3 septembre, produit intact.', approver: { resource: 'billing-fr', action: 'write' }, // défaut : tenant:write (administrateur) }); // a = { id, status: 'PENDING', … } // Recevoir la décision export default defineApp({ events: { 'approval.decided': async ({ ctx, event }) => { const { requestId, subjectId, decision, comment } = event.data; if (decision === 'APPROVED') await ctx.data.refunds.set({ orderId: subjectId, status: 'approved' }, requestId); }, }, }); ``` Seule la personne qui porte la permission `approver` peut décider. `get(id)` relit l'état, `cancel(id)` retire une demande encore en attente. Vous ne recevez que les décisions de **vos** demandes — jamais celles des modules (congés, bons de commande…). --- ## Paiements — `ctx.capibara.billing.*` Une app n'encaisse jamais elle-même : elle remet au client un lien vers **la page de paiement de l'organisation** (rail marchand de Capibara — direct charge sur le compte Stripe de l'organisation, commission de la plateforme selon sa formule, montant figé par Stripe). Trois façades, sous le compte de service de l'app : | Façade | Scope | Ce qu'elle fait | |---|---|---| | `billing.documents.payLink({ id, installmentId?, returnUrl? })` | `billing-fr.documents:write` | Lien de paiement d'une facture ÉMISE (ou d'une échéance) sur le site de l'organisation (`https:///payer-document/…`). Refus honnête si la facture n'est pas payable (déjà réglée, avoir, montant < 0,50 €, Stripe non relié). | | `billing.charges.create({ amountCents, label?, ttlMinutes?, returnUrl? })` | `billing-fr.pos:write` | Encaissement par carte (montant TTC + libellé), réglé par le client sur la page de paiement de l'organisation — même rail que son TPE virtuel, valable 5 à 15 min, attribué à l'app dans son journal. | | `billing.charges.get({ id })` | `billing-fr.pos:read` | État de l'encaissement (`PENDING`, `PAID`, `EXPIRED`, `CANCELED`). | `returnUrl` : après le règlement, la page propose « Retourner sur ». L'URL doit être en HTTPS et son hôte déclaré dans `returnHosts` du manifeste (liste blanche, ≤ 5) — sinon la façade refuse. Elle voyage signée (`?r=`), jamais en clair : la page ne suit pas une URL brute. Pour savoir qu'un paiement est arrivé : déclarez `sales.document.paid` ou `pos.charge.paid` dans `events` (code hébergé) ou souscrivez-les en [webhook](/dev/docs/webhooks) (backend externe — avec les liens de documents et l'identité du client si vous cochez ces options). ```ts actions: { 'facture.payer': async ({ ctx, params }) => { const { url } = await ctx.capibara.billing.documents.payLink({ id: String(params.documentId), returnUrl: 'https://boutique.exemple.fr/merci', // hôte déclaré dans returnHosts }); return { navigate: url }; }, 'acompte.encaisser': async ({ ctx }) => { const charge = await ctx.capibara.billing.charges.create({ amountCents: 4500, label: 'Acompte atelier' }); return { toast: { text: `Code ${charge.formattedCode} — ${charge.url}` } }; }, }, ``` ## Tester en local Le harnais `@capibara-dev/sdk/testing` simule les cinq moteurs en mémoire : ```ts const t = createTestContext(); await runAction(app, t, 'envoyer', {}); t.mails[0].subject; // e-mails « envoyés » t.notifications[0].target; // { kind: 'admins' } t.calendar.get('inspection:42'); // projection t.searchDocs.size; // fiches indexées const req = [...t.approvals.values()][0]; await runEvent(app, t, t.decideApproval(req.id, 'APPROVED')); // rejoue la décision ``` --- ## Ce qui est volontairement hors du contrat - Pas de liste de diffusion, pas d'accès aux abonnés newsletter, pas de Cci de masse : une app n'écrit qu'à des personnes liées, cinq par appel. - Pas de HTML libre dans les e-mails, pas de lien vers un domaine arbitraire autre qu'en `https://`. - Pas d'e-mail ni de notification à « tout le monde » : ciblez une personne, une permission ou les administrateurs. - Pièces jointes, `ctx.events.emit`, `ctx.ai.generate` : différés. --- ## SDK @capibara-dev/sdk ## Statut : disponible (v0.3.0, registre npm) ```bash npm install -D @capibara-dev/sdk ``` Sans accès au registre npm, le tarball servi par le portail fait la même chose (`curl -O https://capibara.fr/dev-sdk/capibara-dev-sdk-0.3.0.tgz && npm install -D ./capibara-dev-sdk-0.3.0.tgz`). Zéro dépendance, compatible Node ≥ 18, navigateurs et workers (`fetch` + WebCrypto). Les starters de la [CLI](/dev/docs/cli) l'installent d'office. Dans la sandbox, `@capibara-dev/sdk` est **fourni par la plateforme** (même API, résolu par le bundler) : le paquet npm sert au **typage**, aux **tests locaux** et au **backend externe**. --- ## Généré depuis les schémas de la plateforme Le cœur du paquet (`generated.ts`) est produit par la plateforme à partir des mêmes schémas Zod qui valident vos manifestes, vos documents du Kit et les appels de façades. Un test anti-dérive dans la CI de Capibara garantit qu'il correspond exactement au validateur — vous n'aurez jamais un type qui accepte ce que le portail refuse. | Export | Contenu | |---|---| | `KitNode`, `KitStackNode`, `KitTableNode`, `KitFieldNode`… | Un type par composant du [Kit](/dev/docs/kit) (38), plus `KitRefNode`, `KitEachNode`, `KitFallbackNode`. | | `KitStackProps`, `KitButtonProps`… + `KitUiBuilders` | Les propriétés de chaque constructeur `ui.` — l'autocomplétion connaît chaque prop, chaque énumération. | | `APP_SCOPES`, `AppScope`, `APP_SCOPE_DEFS` | Le catalogue des [scopes feuilles](/dev/docs/permissions) acceptés dans `permissions`, avec leur phrase de consentement. | | `AppApi`, `APP_FACADES`, `APP_FACADE_NAMES`, `CrmContactsListInput`… | Les [façades](/dev/docs/facades) typées : `ctx.capibara.crm.contacts.list()` côté hébergé, `client.install(id).crm.contacts.list()` côté externe, avec leurs entrées et sorties. | | `APP_EVENTS`, `AppEventType` | Le catalogue fermé des événements (`events` du manifeste, [webhooks](/dev/docs/webhooks)). | | `ADDON_CAPABILITIES`, `ADDON_CATEGORIES`, `APP_SURFACES`, `PANEL_SUBJECTS`, `DECLARATIVE_WIDGET_TEMPLATES` | Les listes fermées du [manifeste](/dev/docs/manifeste). | --- ## Le code hébergé : `defineApp` + `ui` ```ts import { defineApp, ui, toast, type AppContext } from '@capibara-dev/sdk'; export default defineApp({ pages: { home: async ({ ctx }) => ui.doc(ui.stack({ gap: 'md' }, [ ui.pageHeader({ title: 'Bonjour ' + (ctx.viewer?.name ?? 'vous') }), ui.kpi({ label: 'Compteur', value: (await ctx.kv.get('count')) ?? 0 }), ui.button({ label: '+1', action: 'count.add' }), ])), }, actions: { 'count.add': async ({ ctx }) => { const n = ((await ctx.kv.get('count')) ?? 0) + 1; await ctx.kv.put('count', n); return { ...toast('Compteur : ' + n, 'success'), refresh: true }; }, }, }); ``` - `ui.(props, children?)` pour chacun des 38 composants, plus `ui.doc(root, { title, data, components, state })`, `ui.ref(component, props)` (instance d'un composant réutilisable), `ui.each(path, as, gabarit)` (répétition liée aux données) et `ui.fallback(text)` (texte de repli). - `toast()`, `navigate()`, `json()`, `text()` : les réponses prêtes à renvoyer depuis une action ou une route HTTP. - Types du contrat : `AppDefinition`, `AppContext` (`kv`, `data`, `files`, `fetch`, `capibara`, `log`, `followup`…), `RenderArgs`, `ActionArgs`, `ActionResult`, `KitDocument`. Tout est décrit dans [Le runtime](/dev/docs/runtime). - Surfaces du **site public** : `siteBlocks` et `sitePages` — mêmes handlers, `viewer` toujours `null`, le visiteur dans `visitor` (`AppVisitor`) ; le harnais les rend avec `renderSurface(app, 'siteBlock', 'promo', t, { params, visitor })`. --- ## Tester en local : `@capibara-dev/sdk/testing` Le harnais exécute vos handlers **hors de la plateforme**, avec un `ctx` simulé en mémoire — sans réseau, sans compte : ```ts import { test } from 'node:test'; import assert from 'node:assert/strict'; import { createTestContext, renderSurface, runAction, findNodes, hasText } from '@capibara-dev/sdk/testing'; import app from '../src/index'; test('la page et le compteur', async () => { const t = createTestContext({ viewer: { name: 'Léa' }, // null = anonyme (surface publique) install: { config: { defaultCity: 'Lyon' } }, // vos réglages / config de widget fetch: { 'api.example.com': { json: { ok: true } } }, // un faux par host déclaré capibara: { 'crm.contacts.list': async () => ({ items: [], nextCursor: null }) }, data: { favorites: [{ key: 'lyon', data: { city: 'Lyon' } }] }, }); const doc = await renderSurface(app, 'page', 'home', t); // KitDocument normalisé assert.equal(hasText(doc, 'Bonjour Léa'), true); assert.equal(findNodes(doc, 'kpi').length, 1); const r = await runAction(app, 'count.add', t); // { toast, refresh, ui… } assert.equal(r.refresh, true); assert.equal(t.kv.get('count'), 1); assert.deepEqual(t.logs, []); // ctx.log capturé }); ``` - `createTestContext({ tenant, viewer, visitor, install, subject, state, fetch, capibara, kv, data, now })` → `{ ctx, kv, collections, files, logs, followups, calls, mails, notifications, calendar, searchDocs, approvals, decideApproval, tick }` — `kv`/`collections`/`files` sont des `Map` inspectables, `calls` le journal de chaque appel `ctx.*`, `mails` / `notifications` / `calendar` / `searchDocs` / `approvals` ce que les [moteurs](/dev/docs/moteurs) ont reçu, `decideApproval(id, décision)` fabrique l'événement `approval.decided` à rejouer avec `runEvent`. Un host non déclaré dans `fetch` ou une façade non simulée lève une erreur explicite — comme la plateforme refuserait. - `renderSurface(app, surface, key, t, { params, subject, state })`, `runAction(app, action, t, { form, params, formName, state })`, `runEvent(app, { type, data }, t)`, `runSchedule(app, key, t)`, `runHttp(app, path, t, { method, query, headers, body })`. - Assertions : `walkKit`, `findNodes(doc, type)`, `kitStrings`, `hasText`, `jsonResponse`, `textResponse`. Le harnais ne remplace pas la validation du Kit (bornes, a11y) : elle vit dans [Kit Studio](/dev/kit-studio), `capibara kit check` et, en dernier ressort, dans le journal de votre installation de test. --- ## Hors de la sandbox : client API, backend externe, webhooks - **`CapibaraClient`** — client typé de l'[API publique](/dev/docs/api-publique) : `Bearer` clé API (`ck_live_…`) ou jeton OAuth, `me()`, `facades()`, `install(installId)` → les façades typées de cette installation (`X-Capibara-Install`), erreurs `CapibaraApiError` (statut, corps, `retryAfterSeconds` sur 429). - **`createBackend({ app, secret, capibara?, maxSkewSec?, onLog? })`** → `{ handle, fetch, dispatch }` — votre serveur sert le MÊME `defineApp` (manifeste `backend: { url }`). Tout le détail (signature, protocole, `ctx` réduit, tests) est sur [Backend externe](/dev/docs/backend-externe). - **`verifyBackendSignature(rawBody, header, secret)`** si vous branchez vous-même. - **`createServerHandler({ secret, handlers, maxAgeSec? })`** — un seul endpoint pour vos [webhooks sortants](/dev/docs/webhooks) : signature HMAC vérifiée sur le corps **brut** (`401` sinon), enveloppe typée `{ id, event, occurredAt, tenantId, data }`, dispatch par type d'événement, `500` si votre handler lève (Capibara réessaie). `handle(rawBody, headers)` pour Express et consorts, `fetch(request)` pour les runtimes à `Request`. `maxAgeSec` refuse (`401 stale`) une livraison dont l'en-tête `x-capibara-timestamp` est absent ou trop ancien. - **`verifyWebhookSignature(rawBody, header, secret)`** si vous préférez brancher vous-même. - **Aides OAuth PKCE** — `generateCodeVerifier()`, `codeChallengeS256()`, `buildAuthorizeUrl()`, `exchangeAuthorizationCode()`, `clientCredentialsToken()` : [Sign in with Capibara](/dev/docs/oauth). ```ts import { createServerHandler } from '@capibara-dev/sdk'; const webhooks = createServerHandler({ secret: process.env.CAPIBARA_WEBHOOK_SECRET!, handlers: { 'invoice.paid': async ({ tenantId, data }) => { /* votre traitement, idempotent */ }, }, }); // Cloudflare Workers / Deno / Bun : export default { fetch: (req) => webhooks.fetch(req) } // Node/Express : const { status, body } = await webhooks.handle(rawBody, req.headers); ``` --- ## Types du manifeste `AddonManifest`, `AddonCapability`, `AddonPermission` (= `AppScope`), `AddonPricing`, `AddonMenuEntry`, `AddonWidgetContribution` (`AddonKitWidget` | `AddonDeclarativeWidget` | `AddonEmbedWidget`), `AddonPanelContribution`, `AddonSiteBlockContribution`, `AddonSitePageContribution`, `AddonSchedule`, `AddonCollectionDecl`, `AddonSettingField` — le miroir typé de [add-on.json](/dev/docs/manifeste). La validation autoritaire reste celle du portail et de `capibara dev`. --- ## Construire sans le SDK reste possible Le SDK est un confort, pas un prérequis : - L'éditeur du portail applique en direct le **même JSON Schema** que les types du SDK — vos manifestes sont validés à la même source de vérité. - Le [Kit](/dev/docs/kit) se décrit en JSON ; `ui.*` ne fait que le construire. - L'[API publique](/dev/docs/api-publique) s'appelle avec n'importe quel client HTTP (`fetch`, `curl`…), le flux [OAuth PKCE](/dev/docs/oauth) est documenté avec des séquences complètes. Cette documentation (les pages du hub + les endpoints `llms.txt` décrits dans [Utiliser cette doc avec votre IA](/dev/docs/llm)) est conçue pour suffire, avec l'aide d'un assistant IA si vous le souhaitez, à construire une app complète. --- ## Backend externe : servir une app depuis votre serveur ## Deux façons de faire tourner une app - **Code hébergé** (`main`) — votre `defineApp` tourne chez Capibara, dans un bac à sable (workerd sous gVisor, réseau limité aux hôtes déclarés). C'est la voie par défaut : rien à héberger, données et moteurs à portée de `ctx`. - **Backend externe** (`backend: { url }`) — le MÊME `defineApp`, mais c'est **votre serveur** qui reçoit les requêtes du protocole (écrans, actions, événements, planifications, HTTP entrant), signées et horodatées, et qui répond du Kit. Capibara rend l'interface, applique les mêmes bornes et le même disjoncteur. Choisissez le backend externe quand vous avez déjà un serveur, une base ou des dépendances lourdes. Les contreparties sont explicites : l'organisation voit **« Backend chez l'éditeur (votre hôte) »** et consent à l'envoi de ses interactions vers votre serveur, la **review humaine est obligatoire**, la latence réseau s'ajoute à chaque écran, et la disponibilité comme la sécurité de ce serveur vous incombent ([CGV marketplace](/legal/cgv-marketplace) §11 : incident notifié sous 48 h, données effacées 30 jours après désinstallation). --- ## 1. Déclarer le backend au manifeste ```json { "key": "mon-app", "name": "Mon app", "version": "1.0.0", "backend": { "url": "https://api.mon-app.example/capibara" }, "returnHosts": ["mon-app.example"], "contributes": { "menuEntries": [{ "key": "home", "label": "Mon app", "view": "home" }] } } ``` - `backend.url` : **HTTPS**, hôte **public** (jamais une IP, ni localhost, ni un domaine interne). **Exclusif de `main`** : une app est hébergée OU externe, jamais les deux. - Ce qu'un backend peut servir : entrées de menu `view`, widgets `kind: "kit"`, panneaux, blocs et pages du site public, `events`, `schedules`, `http`. - Ce qui reste **réservé au code hébergé** : `collections`, `files.private` et les capabilities des [moteurs](/dev/docs/moteurs) (`mail.send`, `notify.send`, `calendar.project`, `search.index`, `approvals.request`). Le manifeste les refuse sans `main` et renvoie vers les [façades](/dev/docs/facades). - `returnHosts` (≤ 5) : les domaines vers lesquels vos liens de paiement peuvent ramener le client (§5). Référence complète des champs : [Le manifeste](/dev/docs/manifeste). --- ## 2. Le secret et la signature Le secret `cbk_…` se génère dans le portail, sur la page de l'app, section **Backend & webhooks › « Backend externe »**. Il est affiché **une fois**, chiffré au repos, et se régénère à volonté (l'ancien est invalidé aussitôt). Il vit dans les variables d'environnement de votre serveur, jamais dans le dépôt. **Tant qu'aucun secret n'est posé, Capibara n'envoie rien** (journal de l'app : `backend_secret_missing`). Chaque requête arrive ainsi : ```http POST /capibara HTTP/1.1 content-type: application/json x-capibara-timestamp: 1756900000 x-capibara-signature: t=1756900000,v1= x-capibara-kind: render x-capibara-delivery: ``` Vérification : recalculez `hmac-sha256(secret, t + "." + corps BRUT)`, comparez en temps constant, refusez si le `t` s'écarte de plus de **300 s** de votre horloge (`stale`). `x-capibara-delivery` identifie l'invocation : servez-vous-en pour rendre vos traitements idempotents. Avec le SDK, tout cela est fait par `createBackend` (§4). --- ## 3. Le protocole Le corps JSON est la même enveloppe que celle reçue par le code hébergé ([Le runtime › Le protocole d'interaction](/dev/docs/runtime)) : `kind` (`render`, `action`, `event`, `schedule`, `http`), la surface, l'installation (identifiant, configuration, réglages déchiffrés), `viewer` ou `visitor`, le sujet, l'état signé, les paramètres ou le formulaire. Vous répondez `{ ok, result, logs }` — `result` est un document du [Kit](/dev/docs/kit) pour un rendu, le résultat d'action (`ui`, `patch`, `toast`, `navigate`, `openForm`, `close`, `refresh`) sinon. Bornes, identiques au code hébergé : **15 s** par requête, réponse ≤ **1 Mo**, corps entrant ≤ 256 Ko, journal ≤ 200 lignes de 500 caractères, **8 invocations simultanées** par app, disjoncteur (10 échecs sur 5 minutes à ≥ 50 % d'erreurs → app suspendue 5 minutes, puis une sonde). Une réponse hors enveloppe est une erreur pour l'utilisateur, jamais un rendu partiel. --- ## 4. Avec le SDK : `createBackend` ```ts import { createBackend, defineApp, ui, CapibaraClient } from '@capibara-dev/sdk'; const app = defineApp({ pages: { home: () => ui.text({ markdown: 'Rendu depuis mon serveur.' }) }, }); export const backend = createBackend({ app, secret: process.env.CAPIBARA_BACKEND_SECRET!, // cbk_…, jamais dans le dépôt capibara: new CapibaraClient({ token: process.env.CAPIBARA_API_KEY! }), // ctx.capibara.* via l'API publique }); // Node / Express : const { status, body } = await backend.handle(rawBody, req.headers); // Next.js, Cloudflare Workers, Deno, Bun : export default { fetch: (req) => backend.fetch(req) }; ``` - `handle(rawBody, headers)` pour les serveurs à corps brut, `fetch(request)` pour les runtimes à `Request`, `dispatch(req)` pour vos tests. - `maxSkewSec` (défaut 300) et `onLog` sont optionnels ; `verifyBackendSignature(rawBody, header, secret)` et `parseBackendSignature` si vous branchez vous-même. - Le `CapibaraClient` porte une clé API `ck_live_…` (portail › Clés & API) ou un jeton OAuth : `createBackend` en dérive `ctx.capibara` pour l'installation appelante (en-tête `X-Capibara-Install`, compte de service de l'app, scopes consentis par l'organisation). Détail des exports : [SDK › Backend externe](/dev/docs/sdk). --- ## 5. Ce qui change dans `ctx` | Membre | Code hébergé | Backend externe | |---|---|---| | `ctx.capibara.*` (façades) | pont interne | [API publique](/dev/docs/api-publique) via le `CapibaraClient` fourni | | `ctx.fetch` | réseau limité aux hôtes `http.fetch:` du manifeste | le `fetch` de votre serveur, sans restriction | | `ctx.kv`, `ctx.data`, `ctx.files` | disponibles | rejettent avec une explication : vos données vivent chez vous | | `ctx.mail`, `ctx.notify`, `ctx.calendar`, `ctx.search`, `ctx.approvals` | disponibles | rejettent ; l'écriture métier passe par les façades | | `ctx.followup` | disponible | rejette | | `ctx.log` | journal de l'invocation | identique, renvoyé dans `logs` | | `ctx.install.config` | réglages déchiffrés | identiques (transmis dans la requête signée) | **Paiements et retour sur votre site.** Les façades `billing.documents.payLink` et `billing.charges.create` acceptent un `returnUrl` : il est validé contre `returnHosts` puis signé ; le client règle sur le site de l'organisation et voit un bouton « Retourner sur votre-hôte ». Les événements `sales.document.paid` et `pos.charge.paid` vous préviennent (`events` du manifeste, ou [webhooks](/dev/docs/webhooks)). Cf. [Moteurs › Paiements](/dev/docs/moteurs). --- ## 6. Tester et déployer - `capibara init --template external` livre le starter « Intégration externe » : manifeste `backend` + `returnHosts`, une page et un widget Kit, `server/backend.ts` sur `createBackend`. - Le harnais `@capibara-dev/sdk/testing` fonctionne tel quel (`defineApp` est le même) ; `backend.dispatch(req)` rejoue une requête du protocole. - Une installation de test (`capibara dev --org ` ou section Tests du portail) appelle **votre URL** : elle doit être joignable en HTTPS public — Capibara ne fournit pas de tunnel, prévoyez une adresse de préproduction. - `capibara logs` et la section Journal montrent chaque invocation (latence, erreur, vos `logs`). --- ## 7. Publication, consentement, review Le badge **« Backend chez l'éditeur (hôte) »** et la phrase de consentement sont dérivés du manifeste et affichés partout : catalogue des apps, écran d'installation, fiche marketplace, panneau de review. Une version à backend externe n'est **jamais auto-approuvée** : un humain la relit ([Publication](/dev/docs/publication)). --- ## Backend externe ≠ webhooks Les [webhooks sortants](/dev/docs/webhooks) (`createServerHandler`) vous **notifient** des événements d'une organisation — pour toute app, hébergée ou non. Le backend externe **sert** l'app (écrans, actions, planifications). Les deux se combinent : une app hébergée peut recevoir des webhooks, un backend externe peut aussi s'abonner aux événements. --- ## Sign in with Capibara (OAuth) ## Deux grants, deux usages Capibara expose un fournisseur OAuth 2.0 maison (JWT HMAC-SHA256, sans dépendance externe) avec **deux grants réellement fonctionnels** : | Grant | Usage | Nécessite un utilisateur ? | |---|---|---| | `client_credentials` | Votre backend appelle l'API pour son propre compte (tâches de fond, synchronisation). | non | | `authorization_code` + PKCE | « Se connecter avec Capibara » — un utilisateur autorise votre application à agir en son nom. | oui, avec écran de consentement | Les deux grants émettent le même type de jeton : un JWT compact signé HS256, valable **1 heure** (`expires_in: 3600`). Ce jeton est **opaque pour vous** : vous pouvez le décoder pour en lire l'expiration, mais vous ne pouvez pas vérifier sa signature (elle est scellée avec un secret serveur) — utilisez-le tel quel comme `Authorization: Bearer `, il n'y a ni endpoint d'introspection ni JWKS public à ce stade. Décodé, il porte `typ: "access"` (son usage), `knd` (`client` pour `client_credentials`, `user` pour `authorization_code`), `sub`, `cid` (votre `client_id`), `scopes`, `iat` et `exp`. Un jeton sans `typ` (émis avant son introduction) est refusé : redemandez-en un. **Débit limité** : `POST /api/oauth/token` accepte au plus **30 requêtes par 5 minutes par IP appelante** ; au-delà, `429` avec un en-tête `Retry-After: 300`. --- ## Créer un client OAuth Depuis `/dev/keys`, section « Clients OAuth » : | Champ | Contrainte | |---|---| | Nom | 2 à 80 caractères — affiché à l'utilisateur sur l'écran de consentement. | | URLs de redirection | jusqu'à 10, chacune une URL absolue en `https://` (`http://` accepté seulement vers `localhost`, `127.0.0.1` ou `[::1]`, pour le développement), sans identifiants ni fragment `#`. Doivent correspondre **exactement** à l'URL utilisée dans la requête d'autorisation. | | Scopes | sous-ensemble de : `crm:read`, `crm:write`, `shop:read`, `shop:write`, `billing:read`, `billing:write`, `site:read`, `media:read`, `projects:read`, `projects:write`, `planning:read`, `planning:write`, `formation:read` (familles de module ; l'accès aux données d'une organisation exige en plus les [scopes feuilles](/dev/docs/permissions) accordés à l'installation). | La création renvoie un `client_id` (`cid_…`) et un `client_secret` (`csec_…`) affichés **une seule fois** — seul le hash du secret est conservé côté serveur. Notez-les tout de suite dans votre gestionnaire de secrets. --- ## Grant `client_credentials` (serveur-à-serveur) ``` POST https://capibara.fr/api/oauth/token Content-Type: application/json { "grant_type": "client_credentials", "client_id": "cid_VOTRE_CLIENT_ID", "client_secret": "csec_VOTRE_CLIENT_SECRET", "scope": "crm:read shop:read" } ``` Réponse (`200`) : ```json { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.…", "token_type": "Bearer", "expires_in": 3600, "scope": "crm:read shop:read" } ``` `scope` est optionnel dans la requête : si omis, le jeton reçoit tous les scopes déjà accordés au client. S'il est fourni, seule l'**intersection** entre les scopes demandés et ceux du client est accordée — demander un scope que le client ne possède pas ne provoque pas d'erreur, il est simplement absent du jeton final. Le corps peut aussi être envoyé en `application/x-www-form-urlencoded` (format historique OAuth) — les deux formats sont acceptés par l'endpoint. --- ## Grant `authorization_code` + PKCE (connexion utilisateur) PKCE (`S256` uniquement — `plain` est refusé) est **obligatoire**, y compris pour un client confidentiel : c'est la seule méthode de preuve de possession acceptée par cet endpoint. ### 1. Générez un `code_verifier` et son `code_challenge` ```js const crypto = require('node:crypto'); const codeVerifier = crypto.randomBytes(32).toString('base64url'); const codeChallenge = crypto.createHash('sha256').update(codeVerifier).digest('base64url'); ``` Conservez `codeVerifier` en mémoire côté serveur (associé à la session de l'utilisateur qui démarre le flux) — vous en aurez besoin à l'étape 4. ### 2. Redirigez l'utilisateur vers l'autorisation ``` GET https://capibara.fr/api/oauth/authorize ?response_type=code &client_id=cid_VOTRE_CLIENT_ID &redirect_uri=https%3A%2F%2Fmon-app.example%2Foauth%2Fcallback &scope=crm%3Aread%20shop%3Aread &state=UN_JETON_ANTI_CSRF_ALEATOIRE &code_challenge=LE_CODE_CHALLENGE_CALCULE &code_challenge_method=S256 ``` Validations effectuées par cet endpoint avant de continuer : `response_type` doit valoir `code`, `client_id`/`redirect_uri`/`code_challenge` sont requis, `code_challenge_method` doit être `S256`, le client doit exister et `redirect_uri` doit correspondre **exactement** à l'une de ses URLs enregistrées. Les scopes accordés sont réduits à l'intersection avec ceux du client, silencieusement (pas d'erreur si vous en demandez un de trop). Tant que le client et son `redirect_uri` ne sont pas validés (client inconnu, `redirect_uri` absent, non enregistré ou non sûr), la réponse est un JSON `400 { "error": "invalid_client" | "invalid_request", "error_description": "…" }`, **sans redirection** : Capibara ne renvoie jamais un utilisateur vers une adresse que vous n'avez pas enregistrée. Une fois ce couple validé, les autres erreurs repartent vers votre `redirect_uri` avec `?error=&error_description=…&state=…` — traitez donc `error` sur votre callback. Si tout est valide, l'utilisateur est redirigé vers l'écran de consentement Capibara (`/oauth/consent`) — connecté d'abord si nécessaire. ### 3. L'utilisateur autorise (ou refuse) L'écran de consentement affiche le nom de votre application, votre nom de développeur, et la liste des scopes demandés en clair (ex. `crm:read`). Deux issues : - **Refus** → redirection vers `redirect_uri?error=access_denied&state=…`. - **Acceptation** → un code d'autorisation à usage unique est généré (valable **10 minutes**), et l'utilisateur est redirigé vers : `redirect_uri?code=UN_CODE&state=…` ### 4. Échangez le code contre un jeton ``` POST https://capibara.fr/api/oauth/token Content-Type: application/json { "grant_type": "authorization_code", "code": "LE_CODE_RECU_SUR_VOTRE_REDIRECT_URI", "client_id": "cid_VOTRE_CLIENT_ID", "redirect_uri": "https://mon-app.example/oauth/callback", "code_verifier": "LE_CODE_VERIFIER_DE_L_ETAPE_1" } ``` Réponse (`200`) — identique en forme à celle du grant `client_credentials` : ```json { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.…", "token_type": "Bearer", "expires_in": 3600, "scope": "crm:read shop:read" } ``` > **Note.** Cet échange ne demande **pas** `client_secret` : la preuve de > possession repose uniquement sur `code_verifier` (PKCE), ce qui permet à > ce même grant de fonctionner pour une application qui ne peut pas garder un > secret confidentiel (mobile, SPA). Le code est vérifié sur `client_id`, > `redirect_uri` (doit correspondre exactement à celui de l'étape 2) et > `code_verifier` (son empreinte SHA-256 doit correspondre au > `code_challenge` envoyé à l'étape 2) ; il est **consommé** au premier > échange réussi — le réutiliser renvoie `invalid_grant`. --- ## Erreurs standard renvoyées Sur `POST /api/oauth/token` (corps JSON `{ "error": "" }`) : | HTTP | `error` | Quand | |---|---|---| | 400 | `invalid_request` | paramètre requis manquant (`code`, `code_verifier`, `client_secret`…). | | 401 | `invalid_client` | `client_id`/`client_secret` incorrects, ou client inconnu (grant `client_credentials`). | | 400 | `invalid_grant` | code d'autorisation expiré, déjà consommé, ou ne correspondant pas au `client_id`/`redirect_uri`/`code_verifier` fournis. | | 400 | `unsupported_grant_type` | `grant_type` ni `client_credentials` ni `authorization_code`. | | 400 | `unauthorized_client` | votre compte développeur est suspendu. | | 429 | `rate_limited` | plus de 30 requêtes/5 min depuis la même IP. En-tête `Retry-After: 300`. | Sur `GET /api/oauth/authorize`, en **JSON 400, sans redirection** (le couple client + adresse n'est pas validé) : | `error` | Quand | |---|---| | `invalid_request` | `client_id` ou `redirect_uri` manquant ; `redirect_uri` non enregistré pour ce client, ou non sûr. | | `invalid_client` | client inconnu. | Puis en **paramètres de la redirection** vers votre `redirect_uri` : | `error` | Quand | |---|---| | `unsupported_response_type` | `response_type` ≠ `code`. | | `invalid_request` | `code_challenge` manquant ; `code_challenge_method` ≠ `S256`. | | `unauthorized_client` | votre compte développeur est suspendu. | | `access_denied` | l'utilisateur a refusé le consentement. | --- ## Utiliser le jeton obtenu Le jeton du grant `client_credentials` s'utilise contre l'[API publique](/dev/docs/api-publique), comme une clé d'API. Le jeton du grant `authorization_code` (émis au nom d'un utilisateur) **n'ouvre pas encore** l'API publique : ce qu'il donnera le droit de lire est en cours de définition. Tout jeton est revérifié à chaque appel : un client supprimé ou un compte développeur suspendu le rend inutilisable avant son expiration. ``` GET https://capibara.fr/api/public/v1/me Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.… ``` --- ## API publique ## Base et authentification L'API publique est servie sur le domaine principal de l'application : ``` https://capibara.fr/api/public/v1/… ``` Un seul mécanisme d'authentification, trois porteurs possibles dans l'en-tête `Authorization` : ``` Authorization: Bearer ``` - **Clé API** (`ck_live_…`) — générée depuis `/dev/keys`, section « Clés API ». C'est le chemin le plus simple pour une app hybride : la clé ne change pas tant que vous ne la révoquez pas. - **Jeton d'accès OAuth** — obtenu via l'un des deux grants décrits dans [Sign in with Capibara (OAuth)](/dev/docs/oauth). Valable 1 heure ; à renouveler en refaisant le flux (il n'y a pas de `refresh_token` à ce stade). - **Clé de projet** (`cpk_…`) — générée sur la page d'une app (section **Code**, carte « Clé de projet & CLI »), bornée à CE projet : elle n'ouvre que l'[API de projet](#lapi-de-projet-cle-de-projet) ci-dessous (celle de la [CLI](/dev/docs/cli)), jamais `/me` ni les façades. Aucune requête n'aboutit sans l'un des trois : une absence ou une valeur invalide renvoie `401` avec un en-tête `WWW-Authenticate: Bearer`. --- ## `GET /api/public/v1/me` L'endpoint de test d'authentification et d'identité (clé API ou jeton OAuth) : ``` GET https://capibara.fr/api/public/v1/me Authorization: Bearer ck_live_VOTRE_CLE ``` Réponse (`200`) : ```json { "developer": { "slug": "studio-forge", "displayName": "Studio Forge", "partner": false }, "scopes": ["crm:read", "shop:read"], "auth": "api_key" } ``` `auth` vaut `"api_key"` ou `"oauth"` selon le porteur utilisé — utile pour distinguer vos deux modes d'intégration dans vos propres journaux. `scopes` reflète exactement ceux de la clé (ou du jeton) utilisé, pas l'ensemble des scopes possibles. > Cet endpoint ne coûte pas de quota différent des autres : il compte comme > n'importe quel appel dans la limite ci-dessous. Utilisez-le pour vérifier > qu'une intégration est bien configurée avant de construire dessus, pas en > polling répété. --- ## Scopes disponibles Les scopes d'une clé API (ou d'un client OAuth) sont des **familles de module** : ils disent ce que la CLÉ du développeur peut toucher. Pour agir sur une organisation, il faut en plus qu'une installation de votre app y ait accordé le [scope feuille](/dev/docs/permissions) correspondant. | Scope de clé | Couvre | |---|---| | `crm:read` / `crm:write` | Façades du CRM (contacts, sociétés, opportunités, activités). | | `billing:read` / `billing:write` | Façades de la facturation (devis, factures, avoirs). | | `shop:read` / `shop:write` | Façades de la boutique (produits, commandes). | | `projects:read` / `projects:write` | Façades des projets (projets, tâches, temps). | | `planning:read` / `planning:write` | Façades du planning (ressources, réservations). | | `site:read` | Membres du site. | | `formation:read` | Catalogue et sessions de formation. | | `media:read` | Réservé (médiathèque, à venir). | ## `GET /api/public/v1/embed-context` (mode hybride) Une page montée par `embedUrl` (entrée de menu ou widget embed) reçoit `?capibara_token=` dans son URL. Votre backend l'échange ici — avec SA clé API ou son jeton OAuth — contre le contexte de la visite : ``` GET https://capibara.fr/api/public/v1/embed-context?token= Authorization: Bearer ck_live_VOTRE_CLE ``` ```json { "addonKey": "sync-compta-externe", "tenant": { "id": "cm9x…", "slug": "mon-organisation" }, "userAccountId": "acc_…", "grantedPermissions": ["billing-fr.documents:read"], "installId": "inst_…", "expiresAt": "2026-09-04T10:05:00.000Z" } ``` Le jeton vaut **5 minutes**, n'est résolu que par le développeur de l'app visée (`403 forbidden` sinon), et ne contient jamais l'e-mail de la personne. `installId` est la valeur à passer ensuite dans `X-Capibara-Install`. Erreurs propres : `missing_token` et `invalid_token` (400). ## Façades par installation `POST /api/public/v1///` avec `X-Capibara-Install: ` exécute une [façade](/dev/docs/facades) au nom du compte de service de votre app dans cette organisation — lectures en `GET` possibles, écritures idempotentes par `Idempotency-Key`, 120 appels / minute par installation (en plus du quota de la clé). `GET /api/public/v1/facades` renvoie le catalogue complet (schémas d'entrée et de sortie) ; les codes d'erreur sont sur la page des [façades](/dev/docs/facades). Le SDK expose la même chose via `client.install(installId)`. ## L'API de projet (clé de projet) `/api/public/v1/project/…` est l'API que la [CLI](/dev/docs/cli) utilise — et que vous pouvez appeler directement. Elle s'authentifie par une **clé de projet** `cpk_…` (`Authorization: Bearer cpk_…`) et n'agit que sur le projet qui l'a émise. Les installations de test qu'elle pose ne visent qu'une organisation dont le créateur de la clé est propriétaire. Chaque réponse est enveloppée : `{ "ok": true, "result": … }` ou `{ "ok": false, "error": "", "message": "…", …détails }`. | Méthode et chemin | Rôle | |---|---| | `GET /project` | État du projet : versions (canal, bundle), fiche, installations de test, organisations cibles, runtime. | | `GET /project/scopes` | Scopes de la dernière version avec leur phrase de consentement + ce que chaque organisation de test a accordé. | | `GET /project/logs?org=&installId=&after=&limit=` | Journal des exécutions sur les installations de test (curseur `after` = dernier id reçu). | | `GET /project/runtime?route=[@]&hash=` | L'isolate de cette route est-il monté, et avec quel bundle ? Renvoie `state` (nommé) + `message` + `expectedHash`/`mountedHash` — ce sur quoi `capibara dev` attend et que `capibara status` affiche. | | `POST /project/dev` `{ manifest, files, org? }` | Valide le manifeste, scanne et bundle les sources, enregistre le brouillon et pose/actualise l'installation de test (deploy-on-save). | | `POST /project/deploy` `{ manifest, files }` | Même construction, puis la version part en review (build automatisé). | | `POST /project/publish` `{ semver? }` | Publie une version `APPROVED` (la dernière approuvée sans `semver`). | | `POST /project/install` `{ org?, semver? }` · `POST /project/uninstall` `{ org? }` | Pose ou retire une installation de test (retirer purge ses données). | | `POST /project/kit-check` `{ doc, surface? }` | Valide un document (ou un nœud) du Kit avec le validateur réel. | `manifest` est le texte brut de `add-on.json` ; `files` un objet `{ "src/index.ts": "…" }` (80 fichiers, 1,5 Mo au total, 512 Ko par fichier, corps ≤ 3 Mo). Codes d'erreur propres à cette API : `version_locked` (409 : la version du manifeste est en review, approuvée ou publiée — incrémentez `version`), `invalid_manifest` (400, avec `issues[]`), `key_mismatch` / `author_mismatch` / `main_missing` (400), `invalid_sources` et `forbidden_pattern` (400, avec `findings[]` du scan), `bundle_failed` (400), `no_test_org` (412, avec `targets[]`), `org_required` / `org_not_found`, `no_version` / `not_approved` (412), `version_not_found` (404), `invalid_route` (400), `invalid_json` (400), `payload_too_large` (413), `unauthorized` (401), `rate_limited` (429). Quota dédié : **240 appels par minute** et **60 déploiements par minute** par clé de projet. --- ## Quotas **120 requêtes par minute**, par identifiant authentifié — pas par adresse IP. L'identifiant est votre clé API (ou votre compte développeur, si vous appelez via OAuth) : plusieurs backends utilisant la même clé partagent le même quota, et à l'inverse, une même IP appelant pour plusieurs devs ne les fait pas se gêner entre eux. Au-delà du quota : ``` HTTP/1.1 429 Too Many Requests Retry-After: 60 Content-Type: application/json { "error": "rate_limited" } ``` Attendez le délai indiqué par `Retry-After` (en secondes) avant de réessayer — un retry immédiat en boucle prolonge votre propre exclusion sans bénéfice. --- ## Conventions d'erreur Deux formes, selon la famille d'endpoints — le champ `error` est la valeur stable dans les deux cas, le message peut évoluer : - `/me` et `/embed-context` : `{ "error": "" }`. - Les **façades** et l'**API de projet** : une enveloppe `{ "ok": false, "error": "", "message": "…" }` (+ `issues`, `findings`, `targets`… selon le cas), et `{ "ok": true, "result": … }` en succès. Codes communs : | HTTP | `error` | Sens | |---|---|---| | 401 | `unauthorized` | en-tête `Authorization` absent, mal formé, ou clé/jeton invalide (`WWW-Authenticate: Bearer`). | | 403 | `forbidden` / `key_scope_missing` | authentification valide mais scope insuffisant, ou ressource d'un autre développeur. | | 404 | `not_found` / `unknown_facade` / `install_not_found` | ressource absente ou hors de portée du compte authentifié. | | 429 | `rate_limited` | quota dépassé (voir ci-dessus), `Retry-After` fourni. | Les codes propres aux façades (`scope_not_granted`, `consent_outdated`, `killed`…) sont listés sur [Les façades](/dev/docs/facades) ; ceux de l'API de projet ci-dessus. --- ## Et pour le reste de la plateforme ? Si votre app a besoin d'une ressource qui n'est pas encore exposée publiquement, décrivez le besoin depuis `/dev/support` — la priorité des prochains endpoints suit les demandes réelles des développeurs du portail, et sera documentée ici au fur et à mesure de sa sortie. --- ## Webhooks sortants ## Principe Quand une organisation qui a **installé votre app** déclenche un événement métier (commande passée, facture payée, devis accepté…), Capibara envoie un `POST` JSON **signé** à l'URL que vous avez configurée. Vous n'interrogez plus l'API en boucle : votre backend réagit en temps réel. Configuration : portail développeur → votre app → section **Backend & webhooks** → « Ajouter un webhook ». Vous choisissez l'URL (HTTPS obligatoire) et les événements souscrits. Le **secret** est affiché **une seule fois** à la création — stockez-le immédiatement (variable d'environnement, jamais dans le code : le scan de review le détecterait). > 5 webhooks maximum par app. Les adresses IP littérales et les hôtes > locaux/internes sont refusés. ## Format de livraison ```http POST /votre/endpoint HTTP/1.1 Content-Type: application/json User-Agent: Capibara-Webhooks/1.0 x-capibara-signature: sha256=3f5a…e2c1 x-capibara-timestamp: 1756900000 x-capibara-event: invoice.paid x-capibara-delivery: 018f3c2e-7b1a-4c5d-9e8f-2a6b4c8d0e1f ``` ```json { "id": "018f3c2e-7b1a-4c5d-9e8f-2a6b4c8d0e1f", "event": "invoice.paid", "occurredAt": "2026-07-02T14:32:05.120Z", "tenantId": "cm9x…", "data": { "invoiceId": "inv_…", "totalCents": 12050 } } ``` - `id` (= `x-capibara-delivery`) est **stable à travers les retries** d'une même livraison : c'est votre clé d'**idempotence** — si vous l'avez déjà traité, répondez 2xx sans retraiter. - `tenantId` identifie l'organisation émettrice (le même que dans l'API). - `data` porte les champs métier de l'événement — aucun identifiant interne de compte plateforme n'est transmis. - `x-capibara-timestamp` (secondes epoch) date l'envoi : avec `createServerHandler({ maxAgeSec })`, une livraison plus ancienne est refusée (401 `stale`). L'en-tête n'est pas couvert par la signature (contrat figé) : c'est un filet contre le rejeu d'une vieille capture, pas une preuve — l'idempotence par `id` reste la règle. ## Richesse de l'enveloppe (par souscription) Par défaut l'enveloppe porte l'événement tel quel (identifiants, montants). Deux options, cochées à la création du webhook ou à tout moment sur sa ligne, complètent `data` **à la livraison** (un réessai relit l'état à jour) : | Option | Ajoute | Pour | Accès requis | |---|---|---|---| | **Joindre les liens des documents** | `data.document = { id, number, type, status, totalTtcCents, currency, pdfUrl, payUrl? }` (PDF public signé, **valable 7 jours** ; `payUrl` seulement s'il reste un solde) | `sales.document.paid` | `billing-fr.documents:read` | | | `data.charge = { id, code, label, amountCents, currency, paidAt }` | `pos.charge.paid` | `billing-fr.pos:read` | | **Joindre l'identité du client** | `data.customer = { name, email }` (figés sur le document) ou `{ email }` (saisi au paiement d'une charge) | les deux | l'accès du document **et** `crm.contacts:read` | Une option n'est appliquée que si l'organisation destinataire a **accordé à l'installation** l'accès indiqué (vérifié à chaque livraison) ; sinon l'enveloppe part sans ce complément, sans erreur. Le lien `pdfUrl` expire au bout de **7 jours** : si vous devez conserver le document, téléchargez-le à réception (ou relisez-le plus tard par l'[API publique](/dev/docs/api-publique)). L'identité du client est une donnée personnelle : n'activez cette option que si votre backend en a besoin, et traitez-la comme telle. ## Vérifier la signature (obligatoire) Chaque requête est signée **HMAC-SHA256** sur le **corps brut** avec votre secret : en-tête `x-capibara-signature: sha256=`. Rejetez (401) toute requête dont la signature ne correspond pas — sinon n'importe qui pouvant deviner votre URL peut vous injecter de faux événements. Avec [@capibara-dev/sdk](/dev/docs/sdk) : ```ts import { verifyWebhookSignature, WEBHOOK_SIGNATURE_HEADER } from '@capibara-dev/sdk'; // ⚠️ TOUJOURS sur le corps BRUT reçu (string/octets), jamais sur un JSON // re-sérialisé : la signature porte sur les octets exacts. const ok = await verifyWebhookSignature(rawBody, req.headers[WEBHOOK_SIGNATURE_HEADER], process.env.CAPIBARA_WEBHOOK_SECRET!); if (!ok) return res.status(401).end(); ``` Sans SDK (Node.js) : ```ts import { createHmac, timingSafeEqual } from 'node:crypto'; function verify(rawBody: string, header: string, secret: string): boolean { const m = /^sha256=([0-9a-f]{64})$/i.exec(header ?? ''); if (!m) return false; const expected = Buffer.from(m[1], 'hex'); const actual = createHmac('sha256', secret).update(rawBody, 'utf8').digest(); return expected.length === actual.length && timingSafeEqual(actual, expected); } ``` ## Accusé de réception, retries, désactivation - Répondez **2xx en moins de 10 secondes** pour accuser réception. Faites le traitement lourd en asynchrone chez vous (queue) — répondez d'abord. - Toute autre réponse (ou timeout) déclenche des **retries à backoff croissant** : 1 min, 5 min, 15 min, 1 h, 3 h, 6 h, 12 h, 24 h. - Après **8 échecs consécutifs**, la souscription est **désactivée automatiquement** et vous êtes prévenu par e-mail. Corrigez votre endpoint puis réactivez-la depuis la section Backend & webhooks (le compteur repart à zéro). - Le bouton **Tester** envoie un ping signé (`"event": "ping"`) immédiat, sans pénaliser la souscription. ## Événements disponibles Un webhook ne livre jamais ce que votre app ne pourrait pas lire par l'API : chaque événement exige que l'organisation ait **accordé à l'installation** l'accès de lecture indiqué (les [scopes feuilles](/dev/docs/permissions) de votre manifeste). Sans cet accès, l'événement ne vous est pas envoyé par cette organisation. | Événement | Émis quand… | Accès requis | |---|---|---| | `contact.created` | Un contact est créé (CRM, formulaire du site, import…). | `crm.contacts:read` | | `quote.created` / `quote.accepted` | Un devis est créé / accepté. | `billing-fr.documents:read` | | `opportunity.won` | Une opportunité CRM est gagnée. | `crm.opportunities:read` | | `invoice.created` / `invoice.sent` / `invoice.paid` / `invoice.voided` | Cycle de vie d'une facture. | `billing-fr.documents:read` | | `order.placed` / `order.shipped` | Une commande boutique est passée / expédiée. | `shop.orders:read` | | `product.created` / `product.updated` | Catalogue produit. | `shop.products:read` | | `stock.low` / `stock.movement.recorded` | Stock. | `shop.products:read` | | `booking.created` | Une réservation est prise (planning). | `planning.bookings:read` | | `sales.document.paid` | Un document de vente v2 (facture, acompte) ou l'une de ses échéances est encaissé — le montant est dans l'événement ; enrichissable par les options ci-dessus. | `billing-fr.documents:read` | | `pos.charge.paid` | Une charge TPE est payée (caisse, ou `billing.charges.create` de votre app). | `billing-fr.pos:read` | | `approval.decided` | Une demande de validation **posée par votre app** (`ctx.approvals.request`) a été tranchée par un humain — jamais les validations des modules. | aucun (la demande vient de votre app) | **Non livrés par webhook** — aucun accès d'app ne couvre encore ces domaines, la souscription les refuse : `goods.received` (achats), `employee.created`, `leave.requested`, `leave.approved` (RH), `document.attached` (médias). Les apps hébergées (`events` du manifeste) utilisent le même catalogue fermé, ces cinq événements compris : une clé absente des deux listes ci-dessus est refusée à la validation. > Vous ne recevez que les événements des organisations qui ont **installé > votre app** (installation active) et accordé l'accès requis — jamais ceux > du reste de la plateforme. Ces conditions sont **revérifiées à chaque > envoi**, réessais compris : une installation mise en pause ou désinstallée, > un accès retiré ou un compte développeur suspendu arrêtent aussi les > livraisons déjà en file. ## Bonnes pratiques - **Idempotence** : déduplicable par `id` (les retries renvoient le même). - **Ordre non garanti** : datez vos traitements avec `occurredAt`, pas avec l'ordre d'arrivée. - **Secret par webhook** : régénérez-le au moindre doute (l'ancien est invalidé immédiatement) et limitez sa diffusion à l'endpoint de réception. --- ## Publication et review ## Soumettre une version en review Depuis un brouillon (`DRAFT`) valide, la soumission déclenche deux choses immédiatement : 1. Une **revalidation complète du manifeste**, avec le même schéma que l'éditeur du portail. Si elle échoue, la version repart directement en `REJECTED` avec le détail des erreurs — sans attendre personne. 2. Un **build automatisé** : validation du manifeste, audit des dépendances du dépôt lié (registre npm), scan des sources (secrets, motifs interdits) et, pour le code hébergé, le bundle — construit par la plateforme au moment de `capibara deploy` (ou à la publication si la version vient de l'éditeur du portail). Aucun code tiers n'est exécuté hors de la sandbox. Un build rouge bloque la version avec le détail ; un build vert n'est pas une approbation : la review humaine juge le fond. > Ne soumettez pas une app que vous n'avez pas testée : le harnais > `@capibara-dev/sdk/testing` en local, puis `capibara dev` sur votre > organisation de test (cf. [La CLI capibara](/dev/docs/cli)). ### Depuis la CLI ```bash capibara deploy # bundle + version du manifeste → REVIEW capibara deploy --version 1.2.0 # impose le semver capibara deploy --publish # publie une version APPROVED capibara status # l'état de chaque version ``` `capibara dev` ne passe **jamais** par la review : il n'alimente que votre installation de test (version brouillon). Une version en `REVIEW`, `APPROVED` ou `PUBLISHED` n'est jamais réécrite (`version_locked`) : incrémentez `version` dans le manifeste. --- ## Ce que la review vérifie - **Le manifeste** — champs cohérents, permissions et capabilities proportionnées à ce que l'app annonce faire (cf. [Permissions et consentement du tenant](/dev/docs/permissions) et [Capabilities, bornes et erreurs](/dev/docs/capabilities)). - **Les accès demandés, version par version** — le panneau de review affiche le **diff des permissions** avec la dernière version publiée (ajoutées, retirées, conservées, chacune avec sa phrase de consentement) et les **surfaces déclarées** (menus, widgets, panneaux, blocs et pages du site, planifications, routes HTTP, événements, collections, réglages). Un accès nouveau est jugé au regard de ce qu'il sert. - **Un backend tiers = review humaine, toujours** — une page embarquée (`embedUrl`), des appels sortants (`http.fetch:`) ou une app sans code hébergé mais avec des contributions ne passent JAMAIS par la validation automatique, même quand elle est active : l'équipe lit ce qui part vers l'extérieur. - **La description honnête** — la baseline `i18n`, la tagline et la description de la fiche marketplace doivent correspondre à ce que l'app fait réellement. Une promesse non tenue (ex. « synchronisation en temps réel » pour un traitement en réalité manuel) est un motif de refus. - **La catégorie correcte** — cohérente avec la fonction principale de l'app, pas choisie pour la visibilité. - **Les permissions et capabilities** — au minimum nécessaire (principe du moindre privilège). - **Le support** — un `support.email` valide et surveillé. - **La sécurité et la qualité générale du code** — le build automatisé a déjà écarté les secrets en dur, les motifs interdits et les dépendances vulnérables ; la review lit ce que le build ne peut pas juger (usage des données, comportement). --- ## Délais et validation automatique Il n'y a pas de délai contractuel affiché à ce stade : les versions soumises sont traitées **dans l'ordre d'arrivée** par l'équipe Capibara. Suivez le statut de votre version (`REVIEW`, `APPROVED`, `REJECTED`) directement depuis la page de votre app sur le portail — aucune action de votre part n'est nécessaire pendant l'attente. Chaque décision (approbation, refus motivé) vous est envoyée par e-mail. **Validation automatique.** L'instance peut activer une option (réglage de la plateforme, désactivée par défaut) qui approuve une version **sans lecture humaine** quand tout est réuni : build réussi, rapport propre (aucun contrôle en échec ni en attente), version encore en `REVIEW`, et **aucun backend tiers** — une page embarquée (`embedUrl`), un appel sortant (`http.fetch:`), un `backend: { url }` ou une app hybride avec des contributions restent toujours lus par un humain. Vous recevez le même e-mail d'approbation ; la publication reste votre geste. --- ## Motifs de refus courants - Manifeste invalide ou champs incohérents entre eux (ex. `capabilities` déclarant `ui.widget` sans widget correspondant dans `contributes`). - Permissions ou capabilities disproportionnées par rapport à la fonctionnalité décrite. - Description ou tagline trompeuse, ou qui promet une fonctionnalité non implémentée. - Absence de `support.email`, ou adresse manifestement non surveillée. - Comportement suspect détecté à la lecture (appel réseau vers un domaine non déclaré dans `capabilities`, tentative de contournement des permissions). - Contenu ou comportement contraire aux CGV Marketplace (logiciel malveillant, tracker non déclaré, violation de droits de tiers). Un refus est toujours accompagné de notes explicites. Corrigez et resoumettez — une version `REJECTED` redevient un brouillon modifiable. --- ## Publier une version approuvée Une fois `APPROVED`, la publication est **une action volontaire** : rien ne se publie automatiquement. Au premier `publish` d'un projet, la fiche marketplace est créée automatiquement, avec : - l'**accroche** reprise de votre baseline `i18n.fr` (modifiable ensuite) ; - la **catégorie** du projet ; - un **statut** `LISTED` (visible et installable). Les publications suivantes du même projet mettent à jour la version publiée sur la fiche existante. ### Retrait de fiche (`DELISTED`) Distinct du kill switch : l'équipe Capibara peut **retirer votre fiche du marketplace** (motif obligatoire, envoyé par e-mail). La fiche n'apparaît plus au catalogue et ne peut plus être installée ; les organisations qui l'ont déjà installée **continuent de l'utiliser** (sauf incident distinct). La remise en ligne est notifiée de la même façon. Une fiche `DELISTED` garde ses versions : corriger et republier ne la remet pas en ligne tout seul — répondez au motif via l'espace support de votre app. --- ## Mettre à jour (nouvelle version) Il n'y a pas de mise à jour « en place » : vous incrémentez le `version` (semver) dans le manifeste, enregistrez un nouveau brouillon (portail ou `capibara deploy --version x.y.z`), et refaites le cycle `submit` → review → `publish`. Chaque version garde son propre historique (`DRAFT`/`REVIEW`/`APPROVED`/`PUBLISHED`/`REJECTED`) — vous pouvez avoir plusieurs versions dans des états différents en parallèle (par exemple une `PUBLISHED` en production pendant qu'une prochaine est en `REVIEW`). Côté tenant, les mises à jour **ne sont jamais appliquées automatiquement** : un administrateur doit ouvrir la fiche de son app installée et re-consentir explicitement aux permissions de la nouvelle version pour l'appliquer. Prévoyez que certains de vos utilisateurs restent sur une version antérieure un moment. --- ## Le kill switch (incident global ou par tenant) En cas d'incident (faille de sécurité découverte, comportement abusif, signalement fondé), l'équipe Capibara peut **désactiver une version** immédiatement : - **Globalement** — la version est isolée pour tous les tenants qui l'ont installée. - **Pour un seul tenant** — si le problème n'affecte qu'un espace précis (ex. donnée corrompue chez ce client), sans braquer le reste de votre base installée. Chaque désactivation est enregistrée avec un motif et **vous est notifiée par e-mail** (version, portée globale ou organisation, motif) ; elle peut être levée dès que le problème est résolu. Pendant l'incident, toute invocation de la version répond `killed` (cf. [Capabilities, bornes et erreurs](/dev/docs/capabilities)) et l'API publique refuse les façades de ses installations (423). Traitez-le en priorité : c'est le mécanisme qui protège vos utilisateurs (et votre réputation de développeur) en attendant un correctif — en général, une nouvelle version soumise en review. --- ## La fiche marketplace Éditable depuis la page de votre app sur le portail, une fois une première version publiée : | Champ | Contrainte | |---|---| | Accroche (`tagline`) | ≤ 140 caractères. | | Description (`descriptionMd`) | ≤ 20 000 caractères, en Markdown. | | Captures d'écran | jusqu'à 8, chacune une URL d'image que vous hébergez (pas d'upload dédié pour la fiche — utilisez votre propre hébergement d'images). | | Catégorie | reprise du projet, modifiable. | | Icône | image carrée, ≤ 1 Mo, uploadée depuis l'en-tête de votre app sur le portail — affichée sur le portail **et** la fiche marketplace. | Une fiche soignée (accroche claire, captures réelles de l'app en fonctionnement, description qui explique le bénéfice concret) reste le meilleur levier d'installation — la review juge la conformité, pas l'attractivité, mais les deux vont mieux ensemble. --- ## Revenus et rev-share ## Le modèle de prix Le prix d'une app est déclaré dans le manifeste (`pricing`, cf. [Référence du manifeste](/dev/docs/manifeste#pricing)) : | `model` | Ce que paie le tenant | |---|---| | `free` | rien. | | `one_time` | un montant fixe (`amountEur`), une seule fois, à l'installation. | | `subscription` | `amountEur` par mois, avec un essai gratuit optionnel (`trialDays`, 0 à 30 jours). | Le prix est saisi en euros ; Stripe gère la conversion selon le pays du payeur au moment du paiement. --- ## Inscription Stripe Connect Express Pour toucher le moindre euro, vous devez compléter l'inscription **Stripe Connect Express** depuis **Revenus** (`/dev/payouts`) — réservée au propriétaire du compte développeur : 1. Le portail crée votre compte Connect Express (associé à votre compte développeur) au premier clic sur « Configurer mes paiements ». 2. Vous êtes redirigé vers un formulaire Stripe hébergé (KYC : identité, coordonnées bancaires). Vous pouvez le quitter et y revenir plus tard (« Reprendre l'inscription »). 3. Une fois le KYC complet (`payouts_enabled` **et** `charges_enabled` côté Stripe), votre compte passe « vérifié » et les paiements deviennent possibles. > Si Stripe Connect n'est pas encore activé sur l'instance que vous utilisez > (environnement de test, par exemple), la page l'indique clairement : les > paiements développeurs seront disponibles à la bascule en production. --- ## Les 3 paliers de partage (sur le net après frais Stripe) | Palier | Part développeur | Condition | |---|---|---| | **Standard** | 60 % | par défaut, toujours actif. | | **Boost lancement** | 80 % | pendant les **90 jours** qui suivent votre toute première publication, toutes apps confondues. | | **Capibara Partner** | 70 % | statut accordé par l'équipe Capibara. | Si plusieurs paliers s'appliquent en même temps, **le plus favorable pour vous** est retenu automatiquement — pas besoin de le demander. ### Exemple chiffré — vente à 10 € 1. Le tenant paie **10,00 €**. 2. Les frais Stripe sont estimés à **1,5 % + 0,25 €** (cartes européennes), soit ici **0,40 €**. 3. Le **net** disponible au partage est donc **9,60 €**. 4. Votre part dépend du palier actif : | Palier | Part dev | Vous touchez | Part plateforme | |---|---|---|---| | Standard (60 %) | 60 % | **5,76 €** | 3,84 € | | Boost lancement (80 %) | 80 % | **7,68 €** | 1,92 € | | Capibara Partner (70 %) | 70 % | **6,72 €** | 2,88 € | > Le taux de frais Stripe ci-dessus est une **estimation**, utilisée pour > fixer la retenue au moment du paiement. Le montant net réel dépend du type > de carte et du pays de l'acheteur ; il est réconcilié après coup depuis > Stripe et c'est cette valeur réconciliée qui apparaît dans votre récapitulatif > de revenus (`/dev/payouts`). --- ## Quand et comment c'est versé Les ventes sont encaissées par **transfert de destination** (« destination charges ») : votre part est transférée **automatiquement vers votre compte Stripe Connect à chaque vente**, sans action de votre part. La page **Revenus** récapitule, par app : nombre de ventes, chiffre d'affaires brut, votre part cumulée. Le rythme effectif de mise à disposition des fonds sur votre compte bancaire (quotidien, hebdomadaire…) suit ensuite le calendrier de virement standard de votre compte Stripe Connect. ### Relevés mensuels Le 1ᵉʳ de chaque mois, un **relevé** du mois écoulé est généré dès que vous avez eu des ventes : brut, frais Stripe réconciliés, reprises éventuelles, net. C'est le document de référence pour votre comptabilité ; il ne déclenche pas de virement (la part a déjà été transférée à chaque vente). ### Remboursements et reprises Politique par défaut ([CGV marketplace](/legal/cgv-marketplace) §7) : **14 jours satisfait ou remboursé** sur les achats ponctuels, **au prorata** sur les abonnements (le mois entamé reste dû). Un remboursement est décidé et exécuté par l'équipe Capibara ; votre part est alors **reprise** (transfert inverse Stripe) et apparaît en « reprise » sur le relevé du mois — un relevé peut être négatif si un remboursement dépasse vos ventes de la période. Les frais Stripe non récupérables restent à la charge de la plateforme, jamais déduits une seconde fois de votre part. --- ## La TVA et votre fiscalité Sur le marketplace, **Capibara est le marchand de référence** de la vente à l'organisation ([CGV marketplace](/legal/cgv-marketplace)) : c'est la plateforme qui facture l'acheteur et traite la TVA de cette transaction ; le prix du manifeste est le prix payé par l'organisation, et le partage se calcule sur le **net** après frais Stripe. Cela ne vous dispense pas de vos **propres obligations fiscales** : vous restez seul responsable de déclarer, dans votre pays, les revenus perçus via la plateforme (vos relevés mensuels en sont la pièce). Capibara n'est ni votre comptable ni votre conseiller fiscal — en cas de doute, consultez un professionnel. --- ## Suivre vos revenus **Revenus** (`/dev/payouts`) affiche : - l'état de votre compte Stripe Connect ; - votre palier de rev-share actuel et le nombre de jours restants du Boost lancement, le cas échéant ; - vos ventes, votre chiffre d'affaires brut et votre part nette cumulée ; - vos relevés mensuels, avec les reprises éventuelles.