Aller au contenu principal
Vh
Espace créateurs
← Accueil

Publiez votre app.
Touchez les vôtres.

Distribuez votre outil pro auprès d'utilisateurs déjà installés. Profitez du SDK pour partager données et identité avec les autres apps de la suite.

§ 01 · Pourquoi VibeHub

Quatre raisons concrètes.

01
Audience captive

Vos apps sont visibles dans le hub d'utilisateurs déjà actifs sur la suite — pas besoin de les acquérir un par un.

02
Données partagées

Lisez et écrivez les contacts, entreprises et collections de l'utilisateur via le SDK. Plus besoin de leur faire ressaisir leurs données.

03
Confiance par défaut

L'auth est gérée par VibeHub, votre app tourne en iframe sandbox, l'utilisateur révoque les permissions en un clic.

04
Paiements intégrés

Configurez votre tarif (gratuit, achat unique, abonnement). Stripe encaisse pour vous, on vous reverse.

§ 02 · Tarification

Vous fixez le prix.

Quatre modèles disponibles à la soumission :

Gratuit Aucun paiement, juste de la distribution.
Freemium Gratuit avec des limites, payant pour débrider.
Achat unique Un paiement, accès à vie.
Abonnement Mensuel ou annuel, géré via Stripe.

Pendant la beta

100 % du revenu vous revient, sans commission VibeHub. Quand on activera une commission, elle sera annoncée 30 jours à l'avance et les apps déjà publiées garderont leurs conditions d'origine pendant 12 mois.

§ 03 · Pour commencer

Quatre étapes.

Une app VibeHub est un simple site web (HTML + JS + CSS) packagé dans un ZIP. VibeHub l'héberge et l'affiche dans une iframe à l'intérieur de la plateforme.

01
Créez votre app

Un dossier avec un index.html.

02
Utilisez le SDK

vibehub-sdk.js est injecté automatiquement.

03
Zippez et uploadez

Dans VibeLab > votre app > section Hébergement.

04
Review

Un admin valide votre bundle, et c'est en ligne.

Télécharger le Starter Kit ZIP · 3 KB · template fonctionnel

§ 04 · Référence SDK

Le SDK est déjà là.

Disponible via window.VibeHub, injecté automatiquement dans votre app.

Contacts contacts:read · contacts:write

const vh = new VibeHub();

// Lister les contacts
const data = await vh.contacts.list({ q: 'Marie', page: 1 });
// → { contacts: [...], total: 42, page: 1, pages: 3 }

// Créer un contact
const c = await vh.contacts.create({
    first_name: 'Marie',
    last_name: 'Dupont',
    email: 'marie@example.com',
    company_id: '...',  // optionnel
});

// Modifier · Supprimer
await vh.contacts.update(c.contact.id, { job_title: 'CEO' });
await vh.contacts.delete(c.contact.id);

Entreprises companies:read · companies:write

const companies = await vh.companies.list({ q: 'Acme' });
await vh.companies.create({ name: 'Acme Corp', industry: 'Tech' });
await vh.companies.update(id, { size: '50-200' });
await vh.companies.delete(id);

Storage (privé par app) aucun scope requis

// Enregistrer n'importe quelle donnée
await vh.storage.set('user-prefs', { theme: 'dark', lang: 'fr' });

// Lire · Lister · Supprimer
const prefs = await vh.storage.get('user-prefs');
const tasks = await vh.storage.list('task_');
await vh.storage.delete('task_001');

Teams

const teams = await vh.teams.list();
const team = await vh.teams.create('Mon équipe');
await vh.teams.invite(team.team.id, 'alice@example.com', 'member');

// Storage partagé par équipe
await vh.storage.set('config', { key: 'value' }, teamId);

Navigation & UI

vh.navigate('/vibecrm');
vh.toast('Contact sauvegardé !', 'success');
vh.setTitle('Mon dashboard');

console.log(vh.user);   // { id, name, email, avatar_url, role }
console.log(vh.theme);  // 'light' ou 'dark'

§ 05 · Apparaître dans les autres apps

Link providers.

Vos données peuvent s'afficher directement dans le panneau d'un contact CRM, d'une organisation, ou d'un projet. Pour ça, votre app déclare un link provider : une fonction qui répond à la question « qu'est-ce que tu as pour cet ID ? ».

Apps in-house (Python)

# app/votre_app/links.py
from app.core.links import register_link_provider
from app.votre_app.models import Note

@register_link_provider(
    "contact",
    kind="votre-app",
    label="Notes",
    icon="sticky-note",
)
def notes_for_contact(user_id, contact_id):
    notes = Note.query.filter_by(user_id=user_id, contact_id=contact_id).limit(20).all()
    return {
        "items": [n.to_dict() for n in notes],
        "totals": {"count": len(notes)},
        "actions": [{"label": "Nouvelle note", "url": f"/apps/votre-app/?contact_id={contact_id}"}],
    }

Importez ce module depuis app/__init__.py. Le hub agrège tous les providers automatiquement — aucune modification du CRM nécessaire.

Apps tierces (manifest)

Déclarez vos surfaces dans le manifest. Le hub appellera votre endpoint à chaque ouverture de fiche.

{
  "name": "Mon App",
  "link_surfaces": [
    {
      "entity": "contact",
      "label": "Notes",
      "icon": "sticky-note",
      "endpoint": "/api/links/contact",
      "scope": "contacts:read"
    }
  ]
}
Le hub appelle GET {endpoint}/{contact_id} avec un token signé. Réponse JSON identique au format Python ci-dessus. Les réponses sont cachées 60s côté hub pour ne pas spammer votre backend.

§ 06 · Scopes & permissions

Demandez ce dont vous avez besoin.

Votre app déclare ses scopes à l'upload. L'utilisateur les accepte à l'installation.

ScopeDescription
contacts:readLire les contacts de l'utilisateur
contacts:writeCréer et modifier des contacts
contacts:deleteSupprimer des contacts
companies:readLire les entreprises de l'utilisateur
companies:writeCréer et modifier des entreprises
companies:deleteSupprimer des entreprises

Le storage privé ne nécessite aucun scope — chaque app y a accès automatiquement.

§ 07 · Sécurité & règles

Le contrat utilisateur ↔ créateur.

Votre app tourne dans une iframe sandboxée — pas d'accès direct au DOM parent.
Vous n'avez jamais accès à la base de données — uniquement via le SDK.
Chaque accès aux données est loggé dans un audit trail.
L'utilisateur peut révoquer vos permissions à tout moment.
Votre bundle est reviewé par un admin avant d'être mis en ligne.
Interdit : tracking, cookies tiers, appels à des services externes sans consentement.
Créer un compte

Téléchargez le starter kit ci-dessus pour partir d'un template fonctionnel.