1. Aperçu

L'API 1filaire vous donne accès à la dernière version enregistrée des projets de votre compte. Chaque jeton API appartient à un seul compte et donne accès à tous les projets de ce compte, quel que soit l'utilisateur qui les a créés.

URL de base

Tous les endpoints de cette documentation se trouvent sous :

https://app.1filaire.be/api/v1

L'API est aussi disponible sur les domaines néerlandophone et anglophone (app.1draad.be et app.1wire.be). Le domaine n'a aucune influence sur les données renvoyées.

Ce que la v1 ne fait pas

  • Les modifications pas encore enregistrées, ou conservées hors ligne dans le navigateur, ne figurent pas dans l'API.
  • Il n'est pas possible de créer, modifier ou supprimer des projets : l'API est en lecture seule.
  • Les jetons se gèrent dans l'application, pas via l'API.

Spécification OpenAPI

Le contrat complet, lisible par machine, se trouve sur app.1filaire.be/api/v1/openapi.yaml. Vous pouvez l'importer dans Postman, Insomnia ou un générateur de code pour créer un client.

MCP pour assistants IA

Vous pouvez aussi ouvrir les mêmes données à un assistant IA via MCP. Il vous suffit de vous connecter avec votre compte ; aucun jeton API n'est nécessaire.

2. Authentification

Créer un jeton API

  1. Connectez-vous sur app.1filaire.be.
  2. Ouvrez le menu utilisateur en haut à droite, choisissez Intégrations (sous Utilisateurs) et ouvrez l'onglet API REST.
  3. Donnez au jeton un nom reconnaissable, par exemple le nom de votre liaison ERP, et cliquez sur Créer un jeton.
  4. Copiez le jeton immédiatement. Le jeton complet n'est affiché qu'une seule fois.
Conservez le jeton comme un mot de passe. Chaque jeton donne un accès complet à l'API pour tous les projets du compte ; il n'y a pas de droits limités par jeton. Placez-le dans les paramètres secrets de votre intégration, jamais dans le code source ni dans une URL.

Un jeton appartient au compte, pas à l'utilisateur qui l'a créé. Il reste valable jusqu'à ce que quelqu'un le révoque ou que le compte soit supprimé, même si l'utilisateur qui l'a créé quitte le compte. Chaque utilisateur du compte peut voir, créer et révoquer tous les jetons. Sur la même page, vous voyez quand chaque jeton a été utilisé pour la dernière fois.

Envoyer le jeton

Envoyez le jeton à chaque requête dans l'en-tête Authorization :

Shell
curl https://app.1filaire.be/api/v1/projects \
  -H "Authorization: Bearer $DENDRAAD_API_TOKEN"
  • Un jeton passé en paramètre de requête n'est pas accepté, et une session de navigateur connectée ne donne pas accès à l'API.
  • Si le jeton est absent, invalide ou révoqué, vous recevez 401 avec un en-tête WWW-Authenticate: Bearer realm="1draad API".
  • Toutes les réponses portent Cache-Control: no-store.

3. Lister les projets

GET/projects

Renvoie tous les projets non supprimés du compte, de tous les utilisateurs, du plus récent au plus ancien (created_at décroissant, puis id décroissant).

Paramètres de requête

ParamètreDéfautSignification
page1Numéro de page, entier positif.
per_page50Nombre de projets par page, de 1 à 100.
queryvideRecherche, sans tenir compte des majuscules, dans le nom du projet, la référence, les données du client, l'adresse de l'installation et l'EAN. Tronqué après 200 caractères.
updated_sinceaucunHorodatage ISO 8601, par exemple 2026-10-23T09:00:00Z. Ne renvoie que les projets modifiés à ce moment ou après.
Requête
curl "https://app.1filaire.be/api/v1/projects?per_page=100&query=ERP-101" \
  -H "Authorization: Bearer $DENDRAAD_API_TOKEN"
Réponse · 200
{
  "data": [
    {
      "id": 123,
      "name": "Installation batterie domestique",
      "reference": "ERP-101",
      "client_name": "Marie Dubois",
      "installation_ean": "541234567890123456",
      "created_at": "2026-10-23T09:00:00.000000Z",
      "updated_at": "2026-10-23T10:00:00.000000Z",
      "app_url": "https://app.1filaire.be/projects/123/edit",
      "share_url": null
    }
  ],
  "pagination": { "page": 1, "per_page": 100, "total_count": 1, "total_pages": 1 }
}

Champs d'un projet

ChampTypeSignification
idintegerIdentifiant fixe du projet. Utilisez-le pour relier les projets à vos propres enregistrements.
namestringNom du projet.
referencestring | nullVotre propre référence, par exemple un numéro de dossier ou de commande de votre ERP.
client_namestring | nullNom du client.
installation_eanstring | nullCode EAN de l'installation.
created_at, updated_atdate-timeISO 8601 en UTC, avec microsecondes. updated_at change à chaque modification enregistrée, y compris celles du schéma.
app_urluriLien pour ouvrir le projet dans l'éditeur. Ne fonctionne que pour un utilisateur connecté ayant accès au compte.
share_urluri | nullLien de partage public, uniquement si le partage est déjà activé. Une requête API n'active jamais le partage.

Les liens utilisent le domaine de la langue d'export du projet : app.1draad.be, app.1filaire.be ou app.1wire.be.

Pagination

La liste fonctionne avec des pages numérotées. Si des projets sont ajoutés ou supprimés pendant le parcours, un projet peut glisser vers une autre page et apparaître deux fois ou pas du tout. Dédoublonnez donc toujours sur id, et consultez Synchroniser pour une approche robuste.

4. Données du projet

GET/projects/{id}

Renvoie tous les champs de la liste, complétés par les données administratives du projet et quatre fiches de contact.

ChampTypeSignification
account_idintegerCompte auquel appartient le projet.
owned_by_idinteger | nullUtilisateur propriétaire du projet.
client_languagestring | nullLangue du client : nl, fr ou en.
installation_kindstringdomestic (domestique) ou non_domestic (non domestique).
installation_same_as_clientbooleanL'adresse de l'installation est la même que celle du client.
current_typestring | nullType de courant tel que saisi, texte libre, par exemple 3 x 400V + N ~ 50Hz.
clientContactClient.
installation_locationContactLieu de l'installation.
installerContactInstallateur.
controllerContactOrganisme de contrôle.

Chaque fiche de contact contient les mêmes champs : name, street, postal_code, city, country, company_number, fixed_phone, mobile_phone et email. Ce qui n'est pas rempli reste null ou vide.

Adresse de l'installation : si installation_same_as_client vaut true, utilisez les données de client comme adresse de l'installation. installation_location ne contient alors que ce qui a été enregistré séparément, et peut être vide ou obsolète.
Réponse · 200 (abrégée)
{
  "data": {
    "id": 123,
    "name": "Installation batterie domestique",
    "reference": "ERP-101",
    "client_name": "Marie Dubois",
    "installation_ean": "541234567890123456",
    "created_at": "2026-10-23T09:00:00.000000Z",
    "updated_at": "2026-10-23T10:00:00.000000Z",
    "app_url": "https://app.1filaire.be/projects/123/edit",
    "share_url": null,
    "account_id": 7,
    "owned_by_id": 15,
    "client_language": "fr",
    "installation_kind": "domestic",
    "installation_same_as_client": true,
    "current_type": "3 x 400V + N ~ 50Hz",
    "client": {
      "name": "Marie Dubois",
      "street": "Rue de Fer 12",
      "postal_code": "5000",
      "city": "Namur",
      "country": "Belgique",
      "company_number": null,
      "fixed_phone": null,
      "mobile_phone": "0470 12 34 56",
      "email": "marie.dubois@example.com"
    },
    "installation_location": { "name": null, "street": null, ... },
    "installer": { ... },
    "controller": { ... }
  }
}

5. Lire le schéma unifilaire

GET/projects/{id}/schematic

Renvoie une représentation lisible des schémas enregistrés : tous les composants avec leurs réglages, le circuit auquel ils appartiennent et les notes. La réponse provient d'une seule version enregistrée du projet et ne modifie rien au projet.

Réponse · 200 (abrégée)
{
  "data": {
    "project_id": 123,
    "updated_at": "2026-10-23T10:00:00.000000Z",
    "property_units": { "amperage": "A", "delta_current": "mA", "cross_section": "mm²", "length": "m" },
    "schematics": [
      {
        "id": "schema-1",
        "name": "Schema 1",
        "root_component_ids": ["board-789"],
        "components": [ ... ],
        "annotations": [
          { "id": "note-1", "anchor_component_id": "battery-123", "text": "Installée dans le garage" }
        ],
        "backup_connections": [
          { "id": "backup-1", "converter_component_id": "converter-456", "switchboard_component_id": "board-789" }
        ]
      }
    ]
  }
}

Schémas

Un projet peut contenir plusieurs schémas. Chaque schéma de schematics contient :

ChampSignification
id, nameIdentifiant et nom du schéma.
root_component_idsLes composants au sommet de l'arborescence, dans l'ordre.
componentsTous les composants du schéma (voir ci-dessous).
annotationsNotes avec id, anchor_component_id et text. Un texte libre a anchor_component_id: null ; un texte placé par hasard près d'un composant n'est pas considéré comme lié.
backup_connectionsLiaisons de secours entre un onduleur (converter_component_id) et un tableau de secours (switchboard_component_id).

Composants

Exemple de composant
{
  "id": "battery-123",
  "type": "battery",
  "label": "Battery",
  "description": "Marque : Exemple\nS/N : BAT-001",
  "properties": { "quantity": 1, "label": "B1" },
  "parent_id": "converter-456",
  "child_ids": [],
  "connection": {},
  "switchboard_id": "board-789",
  "circuit_id": "breaker-234",
  "circuit_label": "B",
  "circuit_name": "Circuit batterie domestique",
  "phase": "L1",
  "subcircuit_id": "battery-123",
  "subcircuit_label": 1,
  "subcircuit_name": null
}
ChampSignification
idIdentifiant du composant au sein du projet.
typeType de composant fixe de l'éditeur, par exemple battery ou switchboard. Utilisez ce champ dans votre code.
labelNom lisible du type, en anglais. Destiné à l'affichage, pas au filtrage.
descriptionLa description exactement telle que saisie, ou null.
propertiesRéglages enregistrés avec des clés en snake_case : variantes, valeurs électriques, quantité, … Un composant texte conserve son texte dans properties.content.
parent_id, child_idsPosition dans l'arborescence du schéma. L'ordre de child_ids est l'ordre des dérivations.
connectionPorts enregistrés des onduleurs et des commandes, et côté et position des dérivations et des tableaux de secours. Un objet vide signifie que rien n'est enregistré.
switchboard_idLe tableau de distribution parent le plus proche.
circuit_id, circuit_label, circuit_nameLe circuit : référence au composant qui définit le circuit, la lettre sur le dessin et le nom du circuit.
phaseLa phase du circuit, par exemple L1.
subcircuit_id, subcircuit_label, subcircuit_nameLe sous-circuit, de la même manière. Le label est généralement un nombre.
Aucune interprétation. L'API ne renvoie que ce qui est enregistré. Les marques, numéros de série ou capacités ne sont pas extraits de la description, aucune valeur par défaut de l'éditeur n'est ajoutée et rien n'est relié aux articles de votre ERP. Dans les projets plus anciens, les champs de circuit peuvent manquer ; ils valent alors null.

Unités

property_units indique l'unité des réglages connus :

RéglageUnité
amperageA
delta_currentmA (courant différentiel)
cross_sectionmm² (section du câble)
lengthm

Identité et cohérence

Un composant est unique au sein de la combinaison (project_id, schematic_id, component_id). Si vous récupérez les données du projet et le schéma dans des requêtes séparées, comparez updated_at pour vous assurer qu'ils correspondent à la même version enregistrée.

6. Synchroniser

Pour mettre à jour votre propre système, demandez régulièrement les projets modifiés depuis la dernière fois :

  1. Notez l'heure avant de commencer.
  2. Parcourez toutes les pages de GET /projects?updated_since=… avec l'heure de l'exécution précédente, et dédoublonnez sur id.
  3. Pour chaque projet modifié, récupérez les données ou le schéma si vous en avez besoin.
  4. Conservez l'heure de l'étape 1 comme point de départ de l'exécution suivante. Comme updated_since est inclusif, vous ne manquez rien ; un projet reçu deux fois est simplement écrasé.
JavaScript (Node.js 18+)
const BASE_URL = "https://app.1filaire.be/api/v1";
const headers = { Authorization: `Bearer ${process.env.DENDRAAD_API_TOKEN}` };

// Tous les projets modifiés à partir de `since`, dédoublonnés sur id.
async function changedProjects(since) {
  const projects = new Map();
  for (let page = 1; ; page++) {
    const url = new URL(`${BASE_URL}/projects`);
    url.search = new URLSearchParams({ page, per_page: 100, updated_since: since });
    const response = await fetch(url, { headers });
    const body = await response.json();
    if (!response.ok) throw new Error(`${body.error.code}: ${body.error.message}`);

    body.data.forEach((project) => projects.set(project.id, project));
    if (page >= body.pagination.total_pages) return [...projects.values()];
  }
}
Projets supprimés : updated_since ne renvoie pas les projets supprimés. Pour suivre les suppressions, comparez de temps en temps la liste complète (sans updated_since) avec vos propres données. Un projet supprimé renvoie aussi 404 sur GET /projects/{id}.

7. MCP pour assistants IA

POST/mcp

Les mêmes données sont aussi disponibles sous forme de serveur MCP (Model Context Protocol). Un assistant IA compatible MCP, comme Claude ou ChatGPT, peut alors rechercher lui-même vos projets et lire vos schémas, par exemple pour établir une liste de matériel ou répondre à une question sur une installation.

https://app.1filaire.be/mcp

Le serveur utilise le transport Streamable HTTP et est aussi disponible sur app.1draad.be et app.1wire.be. Vous vous connectez de deux façons : avec votre compte 1filaire (recommandé) ou avec un jeton API.

Se connecter avec votre compte (recommandé)

Aucun jeton n'est nécessaire. Vous vous connectez et autorisez vous-même chaque client IA.

  1. Ajoutez l'URL ci-dessus comme serveur MCP distant (Streamable HTTP) dans votre client IA. Choisissez OAuth si le client demande comment se connecter.
  2. Connectez-vous avec votre compte 1filaire existant lorsque le client le demande.
  3. Vérifiez le compte et l'adresse de retour, puis cliquez sur Autoriser l'accès en lecture seule. Le client apparaît ensuite sous Intégrations → Assistants IA (MCP) → Clients IA connectés.
Claude Code
claude mcp add --transport http 1filaire https://app.1filaire.be/mcp
# Ensuite dans Claude Code : /mcp, choisissez 1filaire et connectez-vous.
Codex (OpenAI)
codex mcp add 1filaire --url https://app.1filaire.be/mcp
codex mcp login 1filaire
# Ouvre votre navigateur pour vous connecter.

ChatGPT : dans les paramètres, sous Apps → Advanced settings, activez le Developer mode. Choisissez ensuite Apps → Create, saisissez l'URL MCP, choisissez OAuth comme authentification et connectez-vous. La disponibilité et l'emplacement de cette option dépendent de votre abonnement ChatGPT ; dans un espace de travail, un administrateur doit parfois l'autoriser d'abord.

  • Le client peut lire tous les projets enregistrés, les coordonnées et les schémas du compte. Il ne peut ni modifier les projets ni activer le partage.
  • Vous devez autoriser chaque connexion vous-même, même si le même client s'est déjà connecté auparavant. Le nom du client est fourni par le client lui-même et n'est pas vérifié : n'autorisez que les connexions que vous avez initiées.
  • Chaque utilisateur du compte peut révoquer une connexion avec Déconnecter. Le client perd alors immédiatement l'accès ; les autres connexions et jetons API restent actifs.
  • Une connexion appartient à l'utilisateur qui l'a autorisée. Si cet utilisateur quitte le compte, la connexion expire aussi. Après 90 jours, elle expire dans tous les cas et vous vous reconnectez.
  • La connexion vaut pour un domaine : une connexion via app.1filaire.be ne fonctionne pas sur app.1draad.be ou app.1wire.be, et ne donne pas accès à l'API REST.

Se connecter avec un jeton API

Votre client ne peut pas se connecter mais prend en charge un en-tête Authorization personnalisé ? Envoyez alors un jeton API comme jeton Bearer, comme pour l'API REST (voir Authentification).

mcp.json (par exemple Cursor)
{
  "mcpServers": {
    "1filaire": {
      "url": "https://app.1filaire.be/mcp",
      "headers": { "Authorization": "Bearer VOTRE_JETON_API" }
    }
  }
}
Astuce : créez un jeton distinct pour votre assistant IA, par exemple nommé « Assistant IA ». Si vous le révoquez, l'assistant perd immédiatement l'accès, sans interrompre vos autres liaisons.

Outils

Tous les outils sont en lecture seule et renvoient la même réponse JSON que l'endpoint REST correspondant.

OutilArgumentsCorrespond à
list_projectsFacultatifs : page, per_page, query, updated_since, avec la même signification que dans l'API REST.GET /projects
get_projectObligatoire : project_id (entier).GET /projects/{id}
get_project_schematicObligatoire : project_id (entier).GET /projects/{id}/schematic

Le résultat figure à la fois dans structuredContent et sous forme de texte JSON dans content, afin que les clients qui ne gèrent pas les résultats structurés puissent aussi le lire. Les descriptions et notes d'un projet sont des données de l'utilisateur ; le serveur demande aux clients IA de ne pas les traiter comme des instructions.

Erreurs

  • Un projet inconnu, supprimé ou d'un autre compte, ou un argument invalide, donne un résultat d'outil avec isError: true et le même objet error que l'API REST (not_found ou invalid_parameters).
  • Un outil ou une méthode inconnus donnent une erreur de protocole JSON-RPC.
  • Sans jeton API ou jeton d'accès OAuth valide, vous recevez HTTP 401, avec un en-tête WWW-Authenticate qui renvoie aux métadonnées OAuth du serveur.

Détails techniques

Utile uniquement si vous développez vous-même un client MCP.

Transport

  • Prend en charge la version 2025-11-25 du protocole MCP et les versions antérieures du SDK Ruby MCP officiel. Envoyez d'abord initialize, puis notifications/initialized, et transmettez ensuite la version négociée dans l'en-tête MCP-Protocol-Version. Une version non prise en charge donne HTTP 400.
  • Chaque POST porte Content-Type: application/json et Accept: application/json, text/event-stream. Les réponses sont en JSON ; une notification reçoit une réponse vide avec HTTP 202.
  • Le serveur est sans état : pas d'ID de session, pas de flux SSE persistant. GET et DELETE donnent HTTP 405.
  • Les clients natifs sans en-tête Origin sont acceptés. Avec un en-tête Origin, seuls les trois domaines de l'application sont acceptés ; les autres donnent HTTP 403. Un appel direct depuis une page web d'un autre domaine (CORS) ne fonctionne donc pas.

OAuth

EndpointRôle
GET /.well-known/oauth-protected-resource/mcpDonnées de la ressource MCP et du serveur d'autorisation.
GET /.well-known/oauth-authorization-serverMétadonnées du serveur d'autorisation.
POST /oauth/registerEnregistrement dynamique du client (RFC 7591).
GET /oauth/authorizeConnexion et autorisation.
POST /oauth/tokenÉchange du code et renouvellement des jetons.
POST /oauth/revokeRévocation de la connexion.
  • Uniquement le flux authorization code avec PKCE (S256), obligatoire pour chaque client. Le seul scope est mcp:read.
  • Enregistrez votre client avec client_name, des redirect_uris exactes et token_endpoint_auth_method (none, client_secret_basic ou client_secret_post). Les adresses de retour doivent utiliser HTTPS, sauf HTTP sur une adresse de loopback pour les clients natifs. Les Client ID Metadata Documents ne sont pas encore pris en charge.
  • Transmettez l'URL MCP comme paramètre resource, par exemple https://app.1filaire.be/mcp. Les requêtes de jeton utilisent application/x-www-form-urlencoded.
  • Un jeton d'accès est valable une heure. À chaque renouvellement, vous recevez un nouveau jeton d'accès et un nouveau jeton de renouvellement ; conservez les deux et ne renouvelez jamais deux fois en même temps. Réutiliser un ancien jeton de renouvellement révoque toute la connexion.
Appeler un outil avec curl
curl https://app.1filaire.be/mcp \
  -H "Authorization: Bearer $DENDRAAD_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  --data '{"jsonrpc":"2.0","id":2,"method":"tools/call",
           "params":{"name":"list_projects","arguments":{"query":"ERP-101","per_page":10}}}'

8. Erreurs

En cas d'erreur, vous recevez un objet JSON avec un code fixe et un message en anglais. Basez votre logique sur le code, pas sur le texte.

Réponse · 404
{ "error": { "code": "not_found", "message": "Project not found." } }
StatutCodeQuand
400invalid_parameterspage ou per_page invalide, ou updated_since qui n'est pas un horodatage ISO 8601.
401unauthorizedJeton absent, invalide ou révoqué.
404not_foundLe projet n'existe pas, a été supprimé ou appartient à un autre compte. Pour des raisons de sécurité, l'API ne précise pas lequel des trois.

9. Versions et compatibilité

Les changements susceptibles de casser des intégrations existantes arriveront dans un nouvel espace de noms (/api/v2). Au sein de la v1, des éléments peuvent toutefois s'ajouter. Écrivez votre intégration de façon à tolérer :

  • de nouveaux champs dans une réponse,
  • de nouveaux types de composants dans type,
  • de nouveaux réglages dans properties et connection.

Des questions sur l'API, ou une donnée qui vous manque pour votre liaison ? Faites-le-nous savoir via le formulaire de contact.