Volt LogoVolt
Extension Development

Exemples d'extensions

Implémentations concrètes d'extensions et cas d'usage

Exemples d'extensions

Apprenez avec des exemples concrets

Ces implémentations d'extensions prêtes pour la production démontrent les bonnes pratiques et les patterns courants avec VoltAPI.

Générateur de mot de passe

Un générateur de mots de passe sécurisés avec plusieurs modes :

// Extension Password Generator
// Déclencheurs : "pass", "password", "pwd"

interface Plugin {
id: string;
name: string;
description: string;
enabled: boolean;
canHandle(context: PluginContext): boolean;
match(context: PluginContext): PluginResult[];
execute(result: PluginResult): Promise<void>;
}

interface PluginContext {
query: string;
settings?: Record<string, unknown>;
}

interface PluginResult {
id: string;
type: any;
title: string;
subtitle?: string;
icon?: string;
score: number;
data?: Record<string, unknown>;
}

const TRIGGERS = ['pass', 'password', 'pwd'];
const CHARSET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\*';

function generatePassword(length: number): string {
const array = new Uint32Array(length);
crypto.getRandomValues(array);
return Array.from(array, (num) => CHARSET[num % CHARSET.length]).join('');
}

function calculateStrength(length: number): string {
if (length >= 20) return 'Très fort';
if (length >= 16) return 'Fort';
if (length >= 12) return 'Bon';
return 'Faible';
}

class PasswordGeneratorPlugin implements Plugin {
id = 'password-generator';
name = 'Password Generator';
description = 'Générer des mots de passe cryptographiquement sûrs';
enabled = true;

canHandle(context: PluginContext): boolean {
const query = context.query.toLowerCase().trim();
return TRIGGERS.some(trigger => query.startsWith(trigger));
}

match(context: PluginContext): PluginResult[] {
const { PluginResultType } = window.VoltAPI.types;
const query = context.query.toLowerCase().trim();

    // Extraire la longueur de la requête (ex. "pass 20")
    const parts = query.split(/\s+/);
    const lengthArg = parts.find(p => /^\d+$/.test(p));
    const length = lengthArg ? Math.min(128, Math.max(8, parseInt(lengthArg))) : 16;

    const password = generatePassword(length);
    const strength = calculateStrength(length);

    return [{
      id: 'password',
      type: PluginResultType.Password,
      title: password,
      subtitle: `${length} car. • ${strength} • Entrée pour copier`,
      icon: '🔐',
      score: 100,
      data: { password, length }
    }];

}

async execute(result: PluginResult): Promise<void> {
const password = result.data?.password as string;
const success = await window.VoltAPI.utils.copyToClipboard(password);

    if (success) {
      window.VoltAPI.notify('Mot de passe copié !', 'success');
    } else {
      window.VoltAPI.notify('Échec de la copie', 'error');
    }

}
}

export default PasswordGeneratorPlugin;
{
  "id": "password-generator",
  "name": "Password Generator",
  "version": "1.0.0",
  "description": "Générer des mots de passe cryptographiquement sûrs",
  "author": { "name": "Volt Community" },
  "main": "index.ts",
  "category": "utilities",
  "keywords": ["password", "security", "generator"],
  "minVoltVersion": "0.4.0",
  "permissions": ["clipboard"]
}

Utilisation :

  • pass → mot de passe de 16 caractères
  • pass 24 → mot de passe de 24 caractères
  • password 32 → mot de passe de 32 caractères

Recherche web

Chercher sur plusieurs moteurs de recherche :

// Extension Web Search
// Déclencheurs : "?", "search ", "web "

interface Plugin {
id: string;
name: string;
description: string;
enabled: boolean;
canHandle(context: PluginContext): boolean;
match(context: PluginContext): PluginResult[];
execute(result: PluginResult): Promise<void>;
}

interface PluginContext {
query: string;
}

interface PluginResult {
id: string;
type: any;
title: string;
subtitle?: string;
icon?: string;
score: number;
data?: Record<string, unknown>;
}

const TRIGGERS = ['?', 'search ', 'web ', 'google ', 'bing '];

const SEARCH_ENGINES = [
{ id: 'google', name: 'Google', url: 'https://google.com/search?q=', icon: '🔍' },
{ id: 'duckduckgo', name: 'DuckDuckGo', url: 'https://duckduckgo.com/?q=', icon: '🦆' },
{ id: 'bing', name: 'Bing', url: 'https://bing.com/search?q=', icon: '🅱️' },
];

class WebSearchPlugin implements Plugin {
id = 'web-search';
name = 'Web Search';
description = 'Chercher sur le web avec différents moteurs';
enabled = true;

canHandle(context: PluginContext): boolean {
const query = context.query.toLowerCase();
return TRIGGERS.some(t => query.startsWith(t));
}

match(context: PluginContext): PluginResult[] {
const { PluginResultType } = window.VoltAPI.types;

    // Extraire la requête de recherche
    let searchQuery = context.query;
    for (const trigger of TRIGGERS) {
      if (searchQuery.toLowerCase().startsWith(trigger)) {
        searchQuery = searchQuery.slice(trigger.length).trim();
        break;
      }
    }

    if (!searchQuery) {
      return [{
        id: 'hint',
        type: PluginResultType.Info,
        title: 'Tapez votre requête',
        subtitle: 'Exemple : ? what is volt launcher',
        icon: '💡',
        score: 50
      }];
    }

    return SEARCH_ENGINES.map((engine, i) => ({
      id: engine.id,
      type: PluginResultType.WebSearch,
      title: `Chercher « ${searchQuery} »`,
      subtitle: `Ouvrir dans ${engine.name}`,
      icon: engine.icon,
      score: 100 - i,
      data: {
        url: engine.url + encodeURIComponent(searchQuery),
        engine: engine.name
      }
    }));

}

async execute(result: PluginResult): Promise<void> {
const url = result.data?.url as string;
if (url) {
await window.VoltAPI.utils.openUrl(url);
}
}
}

export default WebSearchPlugin;
{
  "id": "web-search",
  "name": "Web Search",
  "version": "1.0.0",
  "description": "Chercher sur le web avec différents moteurs",
  "author": { "name": "Volt Community" },
  "main": "index.ts",
  "category": "utilities",
  "keywords": ["search", "web", "google", "bing"],
  "minVoltVersion": "0.4.0",
  "permissions": ["network"]
}

Utilisation :

  • ?what is typescript → Chercher sur tous les moteurs
  • search météo → Chercher météo
  • google react docs → Chercher sur Google

Calculatrice

Évaluer des expressions mathématiques :

// Extension Calculator
// Déclencheur : expressions mathématiques

interface Plugin {
id: string;
name: string;
description: string;
enabled: boolean;
canHandle(context: PluginContext): boolean;
match(context: PluginContext): PluginResult[];
execute(result: PluginResult): Promise<void>;
}

interface PluginContext {
query: string;
}

interface PluginResult {
id: string;
type: any;
title: string;
subtitle?: string;
icon?: string;
score: number;
data?: Record<string, unknown>;
}

// Regex d'expression math simple
const MATH_REGEX = /^[\d\s+\-*/().,%^]+$/;

function evaluate(expression: string): number {
// Retirer les espaces et remplacer les symboles courants
const cleaned = expression
.replace(/\s/g, '')
.replace(/,/g, '')
.replace(/%/g, '/100')
.replace(/\^/g, '\*\*');

// Utiliser le constructeur Function pour une évaluation sûre
// Permet uniquement les opérations mathématiques
const fn = new Function(`return (${cleaned})`);
return fn();
}

function formatResult(num: number): string {
if (Number.isInteger(num)) {
return num.toLocaleString();
}
// Arrondir à 10 décimales pour éviter les erreurs de virgule flottante
return parseFloat(num.toFixed(10)).toLocaleString(undefined, {
maximumFractionDigits: 10
});
}

class CalculatorPlugin implements Plugin {
id = 'calculator';
name = 'Calculator';
description = 'Évaluer des expressions mathématiques';
enabled = true;

canHandle(context: PluginContext): boolean {
const query = context.query.trim();
// Doit contenir au moins un chiffre et un opérateur
return MATH_REGEX.test(query) &&
/\d/.test(query) &&
/[+\-*/.^%]/.test(query);
}

match(context: PluginContext): PluginResult[] {
const { PluginResultType } = window.VoltAPI.types;
const query = context.query.trim();

    try {
      const result = evaluate(query);

      if (!isFinite(result)) {
        return [{
          id: 'error',
          type: PluginResultType.Calculator,
          title: 'Calcul invalide',
          subtitle: 'Division par zéro ou expression invalide',
          icon: '⚠️',
          score: 50
        }];
      }

      const formatted = formatResult(result);

      return [{
        id: 'result',
        type: PluginResultType.Calculator,
        title: formatted,
        subtitle: `${query} = ${formatted} • Entrée pour copier`,
        icon: '🔢',
        score: 100,
        data: { result: formatted, expression: query }
      }];
    } catch (error) {
      return [];
    }

}

async execute(result: PluginResult): Promise<void> {
const value = result.data?.result as string;
if (value) {
const success = await window.VoltAPI.utils.copyToClipboard(value);
if (success) {
window.VoltAPI.notify('Résultat copié !', 'success');
}
}
}
}

export default CalculatorPlugin;
{
  "id": "calculator",
  "name": "Calculator",
  "version": "1.0.0",
  "description": "Évaluer des expressions mathématiques",
  "author": { "name": "Volt Community" },
  "main": "index.ts",
  "category": "utilities",
  "keywords": ["calculator", "math", "compute"],
  "minVoltVersion": "0.4.0",
  "permissions": ["clipboard"]
}

Utilisation :

  • 2 + 2 → 4
  • 100 * 1.15 → 115
  • (50 + 25) / 3 → 25
  • 2^10 → 1 024

Minuteur

Créer des minuteurs avec notifications :

// Extension Timer
// Déclencheurs : "timer", "remind"

interface Plugin {
id: string;
name: string;
description: string;
enabled: boolean;
canHandle(context: PluginContext): boolean;
match(context: PluginContext): PluginResult[];
execute(result: PluginResult): Promise<void>;
}

interface PluginContext {
query: string;
}

interface PluginResult {
id: string;
type: any;
title: string;
subtitle?: string;
icon?: string;
score: number;
data?: Record<string, unknown>;
}

const TIME_REGEX = /^(?:timer|remind)\s+(\d+)\s\*(s|sec|seconds?|m|min|minutes?|h|hours?)?$/i;

function parseTime(amount: number, unit: string): number {
const u = (unit || 's').toLowerCase();
if (u.startsWith('h')) return amount _ 3600;
if (u.startsWith('m')) return amount _ 60;
return amount;
}

function formatDuration(seconds: number): string {
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;

const parts = [];
if (h > 0) parts.push(`${h}h`);
if (m > 0) parts.push(`${m}m`);
if (s > 0 || parts.length === 0) parts.push(`${s}s`);

return parts.join(' ');
}

class TimerPlugin implements Plugin {
id = 'timer';
name = 'Timer';
description = 'Créer des minuteurs et des rappels';
enabled = true;

canHandle(context: PluginContext): boolean {
const query = context.query.toLowerCase().trim();
return query.startsWith('timer') || query.startsWith('remind');
}

match(context: PluginContext): PluginResult[] {
const { PluginResultType } = window.VoltAPI.types;
const query = context.query.trim();

    const match = TIME_REGEX.exec(query);
    if (!match) {
      return [{
        id: 'hint',
        type: PluginResultType.Timer,
        title: 'Définir un minuteur',
        subtitle: 'Exemple : timer 5m, timer 30s, timer 1h',
        icon: '⏱️',
        score: 50
      }];
    }

    const [, amountStr, unit] = match;
    const amount = parseInt(amountStr);
    const seconds = parseTime(amount, unit);
    const formatted = formatDuration(seconds);

    return [{
      id: 'timer',
      type: PluginResultType.Timer,
      title: `Minuteur de ${formatted}`,
      subtitle: 'Appuyez sur Entrée pour démarrer',
      icon: '⏱️',
      score: 100,
      data: { seconds, display: formatted }
    }];

}

async execute(result: PluginResult): Promise<void> {
const seconds = result.data?.seconds as number;
const display = result.data?.display as string;

    if (!seconds) return;

    window.VoltAPI.notify(`Minuteur de ${display} démarré`, 'success');

    // Démarrer le minuteur
    setTimeout(() => {
      // Notification à la fin
      if ('Notification' in window && Notification.permission === 'granted') {
        new Notification('Minuteur terminé !', {
          body: `Votre minuteur de ${display} est terminé`,
          icon: '⏱️'
        });
      }
      window.VoltAPI.notify(`Minuteur terminé ! (${display})`, 'info');
    }, seconds * 1000);

}
}

export default TimerPlugin;
{
  "id": "timer",
  "name": "Timer",
  "version": "1.0.0",
  "description": "Créer des minuteurs et des rappels",
  "author": { "name": "Volt Community" },
  "main": "index.ts",
  "category": "utilities",
  "keywords": ["timer", "reminder", "countdown"],
  "minVoltVersion": "0.4.0",
  "permissions": ["notifications"]
}

Utilisation :

  • timer 30s → minuteur de 30 secondes
  • timer 5m → minuteur de 5 minutes
  • timer 1h → minuteur d'1 heure

Générateur d'UUID

Générer des identifiants uniques :

// Extension UUID Generator
// Déclencheurs : "uuid", "guid"

interface Plugin {
id: string;
name: string;
description: string;
enabled: boolean;
canHandle(context: PluginContext): boolean;
match(context: PluginContext): PluginResult[];
execute(result: PluginResult): Promise<void>;
}

interface PluginContext {
query: string;
}

interface PluginResult {
id: string;
type: any;
title: string;
subtitle?: string;
icon?: string;
score: number;
data?: Record<string, unknown>;
}

function generateUUID(): string {
// Utiliser crypto.randomUUID si disponible (navigateurs modernes)
if (typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}

// Implémentation de repli
const array = new Uint8Array(16);
crypto.getRandomValues(array);

// Définir version (4) et variant (10xx)
array[6] = (array[6] & 0x0f) | 0x40;
array[8] = (array[8] & 0x3f) | 0x80;

const hex = Array.from(array, b => b.toString(16).padStart(2, '0')).join('');
return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`;
}

class UUIDPlugin implements Plugin {
id = 'uuid-generator';
name = 'UUID Generator';
description = 'Générer des identifiants uniques';
enabled = true;

canHandle(context: PluginContext): boolean {
const query = context.query.toLowerCase().trim();
return query === 'uuid' || query === 'guid' || query.startsWith('uuid ');
}

match(context: PluginContext): PluginResult[] {
const { PluginResultType } = window.VoltAPI.types;
const query = context.query.toLowerCase().trim();

    // L'utilisateur demande-t-il plusieurs UUIDs ?
    const countMatch = query.match(/^uuid\s+(\d+)$/);
    const count = countMatch ? Math.min(10, parseInt(countMatch[1])) : 1;

    const results: PluginResult[] = [];

    for (let i = 0; i < count; i++) {
      const uuid = generateUUID();
      results.push({
        id: `uuid-${i}`,
        type: PluginResultType.Info,
        title: uuid,
        subtitle: 'Appuyez sur Entrée pour copier',
        icon: '🔑',
        score: 100 - i,
        data: { uuid }
      });
    }

    return results;

}

async execute(result: PluginResult): Promise<void> {
const uuid = result.data?.uuid as string;
if (uuid) {
const success = await window.VoltAPI.utils.copyToClipboard(uuid);
if (success) {
window.VoltAPI.notify('UUID copié !', 'success');
}
}
}
}

export default UUIDPlugin;
{
  "id": "uuid-generator",
  "name": "UUID Generator",
  "version": "1.0.0",
  "description": "Générer des identifiants uniques",
  "author": { "name": "Volt Community" },
  "main": "index.ts",
  "category": "development",
  "keywords": ["uuid", "guid", "unique", "id"],
  "minVoltVersion": "0.4.0",
  "permissions": ["clipboard"]
}

Utilisation :

  • uuid → générer un UUID
  • uuid 5 → générer 5 UUIDs

Exemple de plugin backend (Rust)

Pour les intégrations système, utilisez des plugins backend en Rust :

use serde::{Deserialize, Serialize};
use std::path::PathBuf;

#[derive(Debug, Serialize, Deserialize)]
pub struct GameInfo {
    pub id: String,
    pub name: String,
    pub path: PathBuf,
    pub icon: Option<String>,
}

pub struct SteamPlugin {
    steam_path: PathBuf,
}

impl SteamPlugin {
    pub fn new() -> Self {
        let steam_path = Self::find_steam_path();
        Self { steam_path }
    }

    fn find_steam_path() -> PathBuf {
        #[cfg(target_os = "windows")]
        { PathBuf::from("C:\\Program Files (x86)\\Steam") }
        #[cfg(target_os = "macos")]
        { PathBuf::from("/Users/Shared/Steam") }
        #[cfg(target_os = "linux")]
        { PathBuf::from("~/.steam/steam") }
    }

    pub fn scan_games(&self) -> Vec<GameInfo> {
        let library_path = self.steam_path.join("steamapps");
        let mut games = Vec::new();

        if let Ok(entries) = std::fs::read_dir(&library_path) {
            for entry in entries.flatten() {
                if let Some(name) = entry.file_name().to_str() {
                    if name.starts_with("appmanifest_") && name.ends_with(".acf") {
                        if let Ok(game) = self.parse_manifest(&entry.path()) {
                            games.push(game);
                        }
                    }
                }
            }
        }

        games
    }

    fn parse_manifest(&self, path: &PathBuf) -> Result<GameInfo, Box<dyn std::error::Error>> {
        let content = std::fs::read_to_string(path)?;

        let id = Self::extract_value(&content, "appid")?;
        let name = Self::extract_value(&content, "name")?;
        let install_dir = Self::extract_value(&content, "installdir")?;

        Ok(GameInfo {
            id,
            name,
            path: self.steam_path.join("steamapps/common").join(&install_dir),
            icon: None,
        })
    }

    fn extract_value(content: &str, key: &str) -> Result<String, Box<dyn std::error::Error>> {
        let pattern = format!("\"{}\"\\s+\"([^\"]+)\"", key);
        let re = regex::Regex::new(&pattern)?;

        re.captures(content)
            .and_then(|c| c.get(1))
            .map(|m| m.as_str().to_string())
            .ok_or_else(|| "Clé introuvable".into())
    }
}

// Commande Tauri à exposer au frontend
#[tauri::command]
pub async fn scan_steam_games() -> VoltResult<Vec<GameInfo>> {
    let plugin = SteamPlugin::new();
    Ok(plugin.scan_games())
}

Plugin GitHub

Recherchez dépôts, issues, PRs et gists GitHub directement depuis Volt. Disponible dans la Boutique d'extensions.

// Plugin GitHub — Rechercher repos, issues, PRs, gists
// Déclencheurs : "gh:" ou "gh "

const GITHUB_API = 'https://api.github.com';

class GitHubPlugin implements Plugin {
  id = 'github';
  name = 'GitHub';
  description = 'Rechercher dépôts, issues et pull requests GitHub';
  enabled = true;

  private headers: Record<string, string> = {
    'Accept': 'application/vnd.github.v3+json',
  };

  canHandle(context: PluginContext): boolean {
    const q = context.query.toLowerCase().trim();
    return q.startsWith('gh:') || q.startsWith('gh ');
  }

  async match(context: PluginContext): Promise<PluginResult[]> {
    const { PluginResultType } = window.VoltAPI.types;
    const query = context.query.replace(/^gh[:\s]/, '').trim();

    if (!query) {
      return [{
        id: 'hint',
        type: PluginResultType.Info,
        title: 'Rechercher sur GitHub',
        subtitle: 'gh:react, gh:user/repo, gh:issues react',
        icon: '🐙',
        score: 50
      }];
    }

    try {
      const response = await fetch(
        `${GITHUB_API}/search/repositories?q=${encodeURIComponent(query)}&per_page=5`,
        { headers: this.headers }
      );
      const data = await response.json();

      return data.items.map((repo: any, i: number) => ({
        id: `repo-${repo.id}`,
        type: PluginResultType.Info,
        title: repo.full_name,
        subtitle: `⭐ ${repo.stargazers_count} • ${repo.description || 'Aucune description'}`,
        icon: '📦',
        score: 100 - i,
        data: { url: repo.html_url }
      }));
    } catch {
      return [];
    }
  }

  async execute(result: PluginResult): Promise<void> {
    const url = result.data?.url as string;
    if (url) await window.VoltAPI.utils.openUrl(url);
  }
}

export default GitHubPlugin;
{
  "id": "github",
  "name": "GitHub",
  "version": "1.0.0",
  "description": "Rechercher dépôts, issues, pull requests et gists GitHub",
  "author": {
    "name": "VoltLaunchr Community",
    "github": "VoltLaunchr"
  },
  "main": "src/index.ts",
  "prefix": "gh",
  "category": "productivity",
  "keywords": ["github", "search", "repositories", "issues", "pull-requests"],
  "repository": "https://github.com/VoltLaunchr/volt-extensions",
  "license": "MIT",
  "minVoltVersion": "0.4.0",
  "permissions": ["network"]
}

Rechercher des dépôts :

  • gh:react — Chercher des repos correspondant à « react »
  • gh:language:rust stars:>1000 — Filtrer par langage et étoiles

Rechercher issues & PRs :

  • gh:issues react — Chercher des issues ouvertes
  • gh:prs typescript — Chercher des pull requests

Parcourir des repos utilisateur :

  • gh:user/repo — Voir un dépôt spécifique

Tendances :

  • gh:trending — Afficher les repos tendance

Authentification (optionnelle) : Définissez la variable d'env GITHUB_TOKEN pour 5 000 req/heure (contre 60 non authentifié).


Plugin Notion

Recherchez dans votre espace Notion — pages, bases de données et blocs. Disponible dans la Boutique d'extensions.

// Plugin Notion — Rechercher dans l'espace Notion
// Déclencheurs : "notion:" ou "n:"

const NOTION_API = 'https://api.notion.com/v1';

class NotionPlugin implements Plugin {
  id = 'notion';
  name = 'Notion';
  description = 'Rechercher dans votre espace Notion';
  enabled = true;

  canHandle(context: PluginContext): boolean {
    const q = context.query.toLowerCase().trim();
    return q.startsWith('notion:') || q.startsWith('n:');
  }

  async match(context: PluginContext): Promise<PluginResult[]> {
    const { PluginResultType } = window.VoltAPI.types;
    const query = context.query.replace(/^(notion|n):/, '').trim();

    if (!query) {
      return [{
        id: 'hint',
        type: PluginResultType.Info,
        title: 'Rechercher dans Notion',
        subtitle: 'n:notes réunion, notion:databases, n:recent',
        icon: '📝',
        score: 50
      }];
    }

    try {
      const apiKey = await window.VoltAPI.invoke('get_secure_value', {
        key: 'NOTION_API_KEY'
      });

      const response = await fetch(`${NOTION_API}/search`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Notion-Version': '2024-02-15',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          query,
          page_size: 5,
        }),
      });

      const data = await response.json();

      return data.results.map((page: any, i: number) => ({
        id: `notion-${page.id}`,
        type: PluginResultType.Info,
        title: page.properties?.title?.title?.[0]?.plain_text || 'Sans titre',
        subtitle: `${page.object} • Modifié le ${new Date(page.last_edited_time).toLocaleDateString()}`,
        icon: page.icon?.emoji || '📄',
        score: 100 - i,
        data: { url: page.url }
      }));
    } catch {
      return [];
    }
  }

  async execute(result: PluginResult): Promise<void> {
    const url = result.data?.url as string;
    if (url) await window.VoltAPI.utils.openUrl(url);
  }
}

export default NotionPlugin;
{
  "id": "notion",
  "name": "Notion",
  "version": "1.0.0",
  "description": "Rechercher dans votre espace Notion — pages, bases de données et blocs",
  "author": {
    "name": "VoltLaunchr Community",
    "github": "VoltLaunchr"
  },
  "main": "src/index.ts",
  "prefix": "notion",
  "category": "productivity",
  "keywords": ["notion", "notes", "workspace", "search", "databases"],
  "repository": "https://github.com/VoltLaunchr/volt-extensions",
  "license": "MIT",
  "minVoltVersion": "0.4.0",
  "permissions": ["network"]
}

Recherche texte intégral :

  • notion:notes de réunion — Chercher dans l'espace
  • n:feuille de route projet — Préfixe court

Lister les bases :

  • notion:databases — Afficher toutes les bases

Pages récentes :

  • n:recent — Voir les pages récemment modifiées

Authentification (requise) : Définissez NOTION_API_KEY dans Paramètres → Intégrations. Créez une intégration sur notion.so/my-integrations.

Rate limits : 3 req/sec (plan gratuit), best effort (payant).


Plus d'exemples

On this page