Retour à la Documentation

Sutram REST API v1

Version : 0.89.0 Date : 2026-02-19 Statut : En production


Apercu general

L'API REST Sutram fournit des points de terminaison JSON pour la consommation externe du contenu de projet (dossiers, fichiers, liens). Elle utilise la meme authentification a double cle que le serveur MCP (x-project-key + x-user-key), de sorte que tout projet avec l'acces a distance active est automatiquement accessible via l'API REST.

Cas d'utilisation

  • Integration de plateforme APM — Consommer le contenu Sutram (evenements, actualites, podcasts, webinaires) en tant que depot central (SSOT)
  • Tableaux de bord personnalises — Construire des pages de listing de contenu en dehors de Sutram
  • Applications mobiles — Recuperer des fichiers et des liens avec des URL de telechargement pre-signees
  • Automatisation — Decouverte et recuperation programmatique de contenu via des scripts ou CI/CD

URL de base

https://sutram.io/api/v1

Developpement :

http://localhost:4001/api/v1

Fonctionnement

External Client (app, script, dashboard)
        |
        | HTTPS + JSON
        v
  Sutram REST API
    /api/v1/*
        |
        | Dual Key Authentication
        v
  Project Content (folders, files, links, tags)

Authentification

Chaque requete doit inclure deux en-tetes :

En-tete Valeur Description
x-project-key sk_proj_... Identifie le projet
x-user-key sk_user_... Identifie l'utilisateur

Les deux cles sont creees via l'interface web Sutram. Consultez le Guide utilisateur du serveur MCP pour les instructions detaillees.

Exemple

curl -H "x-project-key: sk_proj_ej8NWMisd2rJgMwAJ22T..." \
     -H "x-user-key: sk_user_zQD0BjH56nQhOgX3uxni..." \
     https://sutram.io/api/v1/project

Reponses d'erreur

Lorsque l'authentification echoue, l'API renvoie HTTP 401 :

{ "error": "Missing x-project-key header" }
{ "error": "Invalid project key" }
{ "error": "Invalid user key" }
{ "error": "Viewers cannot access this API" }
{ "error": "Not a member of this project" }

Permissions

Role Acces
Owner Acces en lecture complet
Admin Acces en lecture complet
Member Acces en lecture complet
Viewer Pas d'acces (401)

L'API REST v1 est en lecture seule. Les operations d'ecriture (telechargement, suppression, renommage, deplacement) sont disponibles via le serveur MCP.


Points de terminaison

GET /api/v1/project

Renvoie les informations sur le projet authentifie.

Exemple de requete :

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     https://sutram.io/api/v1/project

Reponse :

{
  "project": {
    "id": "a1b2c3d4-...",
    "name": "Construction Site Alpha",
    "description": "Main project documentation",
    "your_role": "owner",
    "created_at": "2026-01-15T10:00:00Z",
    "updated_at": "2026-02-19T14:30:00Z"
  }
}

GET /api/v1/folders

Liste les dossiers de niveau racine du projet.

Exemple de requete :

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     https://sutram.io/api/v1/folders

Reponse :

{
  "folders": [
    {
      "id": "f1a2b3c4-...",
      "name": "Reports",
      "parent_id": null,
      "tags": {"category": "monthly"},
      "created_at": "2026-01-20T10:00:00Z"
    },
    {
      "id": "f5e6d7c8-...",
      "name": "Photos",
      "parent_id": null,
      "tags": {},
      "created_at": "2026-01-22T08:00:00Z"
    }
  ],
  "meta": {
    "total_count": 2
  }
}

GET /api/v1/folders/:id

Renvoie les details d'un dossier, ses sous-dossiers et ses elements de contenu.

Parametres de chemin :

Parametre Type Description
id UUID ID du dossier

Exemple de requete :

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     https://sutram.io/api/v1/folders/f1a2b3c4-...

Reponse :

{
  "folder": {
    "id": "f1a2b3c4-...",
    "name": "Reports",
    "parent_id": null,
    "path": "/Reports",
    "tags": {"category": "monthly"},
    "created_at": "2026-01-20T10:00:00Z"
  },
  "subfolders": [
    {
      "id": "a1b2c3d4-...",
      "name": "2024",
      "parent_id": "f1a2b3c4-...",
      "tags": {"year": "2024"},
      "created_at": "2026-01-25T12:00:00Z"
    }
  ],
  "items": [
    {
      "id": "d5e6f7a8-...",
      "type": "file",
      "name": "summary",
      "description": null,
      "tags": {"status": "final"},
      "folder_id": "f1a2b3c4-...",
      "created_at": "2026-02-01T10:00:00Z",
      "file": {
        "filename": "summary.pdf",
        "content_type": "application/pdf",
        "file_size": 245000
      }
    }
  ],
  "meta": {
    "subfolder_count": 1,
    "item_count": 1
  }
}

Reponses d'erreur :

Statut Corps Quand
404 {"error": "Folder not found"} Le dossier n'existe pas ou appartient a un autre projet

GET /api/v1/content

Liste les elements de contenu avec filtrage, recherche par tags, recherche textuelle et pagination.

Parametres de requete :

Parametre Type Par defaut Description
folder_id UUID Filtrer par dossier. Sans ce parametre, renvoie uniquement les elements de niveau racine.
all_folders boolean false Si true, recherche dans tous les dossiers (pas seulement la racine). Requis pour les requetes par tags/recherche sur l'ensemble du projet.
type string Filtrer par type de contenu : "file", "web_link", "video_link", "audio_link"
tag string Cle de tag unique pour filtrer (par ex., tag=category)
tag_value string Valeur de tag a faire correspondre (utilise avec tag). Correspondance insensible a la casse par sous-chaine.
tags JSON Conditions AND multiples en tant que tableau JSON (par ex., tags=[{"key":"topic","value":"neuro"}])
search string Recherche par nom d'element (correspondance insensible a la casse par sous-chaine)
page integer 1 Numero de page
per_page integer 50 Elements par page (max : 100)

Comportement de la recherche par tags :

  • Correspondance de cle : Correspondance exacte insensible a la casse ("Category" correspond a "category")
  • Correspondance de valeur : Correspondance par sous-chaine insensible a la casse ("neuro" correspond a "Neurologia Avancada")
  • Conditions multiples (parametre tags) : Toutes les conditions doivent correspondre (logique AND)
  • Sans valeur : Lorsque tag_value est omis, correspond a tout element qui possede la cle de tag quelle que soit la valeur

Exemple — lister les elements racine

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content"

Exemple — lister les elements dans un dossier

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content?folder_id=f1a2b3c4-..."

Exemple — filtrer par type

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content?type=video_link&all_folders=true"

Exemple — recherche par tag unique

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content?tag=category&tag_value=cientifico&all_folders=true"

Exemple — recherche AND multi-tags

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content?tags=%5B%7B%22key%22%3A%22patient%22%2C%22value%22%3A%22jo%C3%A3o%22%7D%2C%7B%22key%22%3A%22year%22%2C%22value%22%3A%222024%22%7D%5D&all_folders=true"

Le parametre tags ci-dessus est la version encodee en URL de :

[{"key": "patient", "value": "joão"}, {"key": "year", "value": "2024"}]

Exemple — recherche par nom

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content?search=report&all_folders=true"

Exemple — listing pagine

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content?page=2&per_page=20"

Reponse :

{
  "items": [
    {
      "id": "d5e6f7a8-...",
      "type": "file",
      "name": "site-plan",
      "description": null,
      "tags": {"category": "planta", "year": "2024"},
      "folder_id": "f1a2b3c4-...",
      "created_at": "2026-02-19T10:00:00Z",
      "file": {
        "filename": "site-plan.pdf",
        "content_type": "application/pdf",
        "file_size": 2450000
      }
    },
    {
      "id": "e5f6a7b8-...",
      "type": "video_link",
      "name": "Site walkthrough",
      "description": null,
      "tags": {"topic": "neurologia"},
      "folder_id": null,
      "created_at": "2026-02-18T14:00:00Z",
      "video_link": {
        "url": "https://youtube.com/watch?v=abc",
        "platform": "youtube",
        "video_id": "abc",
        "thumbnail_url": "https://img.youtube.com/vi/abc/hqdefault.jpg"
      }
    },
    {
      "id": "a1b2c3d4-...",
      "type": "web_link",
      "name": "Documentation",
      "description": "Project reference docs",
      "tags": {},
      "folder_id": null,
      "created_at": "2026-02-17T09:00:00Z",
      "web_link": {
        "url": "https://docs.example.com",
        "fetched_title": "Documentation Hub",
        "favicon_url": "https://docs.example.com/favicon.ico"
      }
    },
    {
      "id": "c9d0e1f2-...",
      "type": "audio_link",
      "name": "Weekly recap",
      "description": null,
      "tags": {"series": "weekly"},
      "folder_id": null,
      "created_at": "2026-02-16T16:00:00Z",
      "audio_link": {
        "url": "https://open.spotify.com/episode/xyz",
        "platform": "spotify",
        "artist_or_author": "Team Alpha",
        "thumbnail_url": "https://i.scdn.co/image/abc"
      }
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 50,
    "total_count": 4,
    "total_pages": 1
  }
}

Champs contentable par type :

Le contentable est serialise sous une cle correspondant au type de l'element :

Type Cle Champs
file file filename, content_type, file_size
web_link web_link url, fetched_title, favicon_url
video_link video_link url, platform, video_id, thumbnail_url
audio_link audio_link url, platform, artist_or_author, thumbnail_url

GET /api/v1/content/:id

Renvoie les details complets d'un element de contenu unique, y compris les URL de telechargement pre-signees pour les fichiers.

Parametres de chemin :

Parametre Type Description
id UUID ID de l'element de contenu

Exemple de requete :

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     https://sutram.io/api/v1/content/d5e6f7a8-...

Reponse (fichier) :

{
  "item": {
    "id": "d5e6f7a8-...",
    "type": "file",
    "name": "site-plan",
    "description": null,
    "tags": {"category": "planta", "year": "2024"},
    "folder_id": "f1a2b3c4-...",
    "folder_path": "/Reports/2024",
    "created_at": "2026-02-19T10:00:00Z",
    "file": {
      "filename": "site-plan.pdf",
      "content_type": "application/pdf",
      "file_size": 2450000,
      "version": 1,
      "download_url": "https://storage.example.com/projects/.../site-plan.pdf?X-Amz-..."
    }
  }
}

Reponse (lien video) :

{
  "item": {
    "id": "e5f6a7b8-...",
    "type": "video_link",
    "name": "Site walkthrough",
    "description": null,
    "tags": {"topic": "neurologia"},
    "folder_id": null,
    "folder_path": "/",
    "created_at": "2026-02-18T14:00:00Z",
    "video_link": {
      "url": "https://youtube.com/watch?v=abc",
      "platform": "youtube",
      "video_id": "abc",
      "thumbnail_url": "https://img.youtube.com/vi/abc/hqdefault.jpg",
      "duration_seconds": null,
      "fetched_title": "Construction Site Alpha - Full Tour"
    }
  }
}

Reponse (lien audio) :

{
  "item": {
    "id": "c9d0e1f2-...",
    "type": "audio_link",
    "name": "Weekly recap",
    "description": null,
    "tags": {"series": "weekly"},
    "folder_id": null,
    "folder_path": "/",
    "created_at": "2026-02-16T16:00:00Z",
    "audio_link": {
      "url": "https://open.spotify.com/episode/xyz",
      "platform": "spotify",
      "artist_or_author": "Team Alpha",
      "thumbnail_url": "https://i.scdn.co/image/abc",
      "duration_seconds": 1800,
      "fetched_title": "Weekly Standup Recap - Feb 16"
    }
  }
}

Reponse (lien web) :

{
  "item": {
    "id": "a1b2c3d4-...",
    "type": "web_link",
    "name": "Documentation",
    "description": "Project reference docs",
    "tags": {},
    "folder_id": null,
    "folder_path": "/",
    "created_at": "2026-02-17T09:00:00Z",
    "web_link": {
      "url": "https://docs.example.com",
      "fetched_title": "Documentation Hub",
      "fetched_description": "Complete project documentation",
      "favicon_url": "https://docs.example.com/favicon.ico"
    }
  }
}

Differences entre la reponse detail et la reponse liste :

Le point de terminaison /content/:id renvoie des champs supplementaires par rapport au point de terminaison liste :

Champ Liste (/content) Detail (/content/:id)
folder_path Non Oui
file.version Non Oui
file.download_url Non Oui (pre-signee, temporaire)
web_link.fetched_description Non Oui
video_link.duration_seconds Non Oui
video_link.fetched_title Non Oui
audio_link.duration_seconds Non Oui
audio_link.fetched_title Non Oui

Reponses d'erreur :

Statut Corps Quand
404 {"error": "Content item not found"} L'element n'existe pas ou appartient a un autre projet

Tags des elements de contenu

Les tags sont des paires cle-valeur libres de type chaine attachees aux elements de contenu et aux dossiers. Ils permettent des metadonnees structurees et des capacites de recherche puissantes.

Contraintes des tags

Contrainte Limite
Nombre maximum de tags par element 50
Longueur maximale de la cle 100 caracteres
Longueur maximale de la valeur 500 caracteres
Types de cle et de valeur Chaines uniquement

Gestion des tags

Les tags sur les elements de contenu sont geres via les outils du serveur MCP :

Outil MCP Description
sutram_set_item_tags Definir/remplacer tous les tags d'un element de contenu
sutram_search_items Rechercher des elements par tag (condition unique ou AND multiple)
sutram_get_item_tag_keys Lister toutes les cles de tag distinctes utilisees sur les elements

Consultez le Guide utilisateur du serveur MCP pour plus de details sur ces outils.

Interrogation des tags via l'API REST

Utilisez les parametres de requete tag, tag_value et tags sur GET /api/v1/content :

# Trouver tous les elements tagges avec "category"
curl ... "https://sutram.io/api/v1/content?tag=category&all_folders=true"

# Trouver les elements ou category contient "report"
curl ... "https://sutram.io/api/v1/content?tag=category&tag_value=report&all_folders=true"

# Trouver les elements correspondant a plusieurs conditions (AND)
curl ... "https://sutram.io/api/v1/content?tags=[{\"key\":\"patient\",\"value\":\"joão\"},{\"key\":\"year\",\"value\":\"2024\"}]&all_folders=true"

Comparaison : API REST vs. serveur MCP

Capacite API REST (/api/v1) Serveur MCP (/mcp)
Protocole HTTP/JSON JSON-RPC 2.0 (MCP)
Lire le contenu Oui Oui
Recherche par tags Oui Oui
URL de telechargement Oui (pre-signees) Oui (pre-signees)
Telecharger des fichiers Non Oui
Creer des liens Non Oui
Creer des dossiers Non Oui
Definir des tags Non Oui
Deplacer/renommer/supprimer Non Oui
Authentification Meme double cle Meme double cle
Ideal pour Applications externes, tableaux de bord, scripts Assistants IA, automatisation

Limites de debit

Il n'y a actuellement aucune limite de debit sur l'API REST. Cela peut changer dans les versions futures. Veuillez etre raisonnable avec la frequence des requetes.


Versionnage

L'API est versionnee via le chemin de l'URL (/api/v1). Les changements incompatibles seront introduits dans de nouvelles versions (/api/v2). Les ajouts non incompatibles (nouveaux champs, nouveaux parametres optionnels) peuvent etre ajoutes a la version actuelle sans preavis.


Exemples

Recuperer tous les liens video d'un projet

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content?type=video_link&all_folders=true"

Recuperer le contenu tagge pour un sujet specifique

curl -H "x-project-key: $PROJECT_KEY" \
     -H "x-user-key: $USER_KEY" \
     "https://sutram.io/api/v1/content?tag=topic&tag_value=neurologia&all_folders=true"

Parcourir une hierarchie de dossiers

# 1. Lister les dossiers racine
curl ... "https://sutram.io/api/v1/folders"

# 2. Ouvrir un dossier specifique
curl ... "https://sutram.io/api/v1/folders/f1a2b3c4-..."

# 3. Obtenir l'URL de telechargement d'un fichier
curl ... "https://sutram.io/api/v1/content/d5e6f7a8-..."

Paginer a travers tout le contenu

# Page 1
curl ... "https://sutram.io/api/v1/content?page=1&per_page=20&all_folders=true"

# Page 2
curl ... "https://sutram.io/api/v1/content?page=2&per_page=20&all_folders=true"

# Continuer jusqu'a ce que page >= total_pages dans meta

Integration avec JavaScript (fetch)

const PROJECT_KEY = "sk_proj_...";
const USER_KEY = "sk_user_...";
const BASE_URL = "https://sutram.io/api/v1";

async function fetchContent(params = {}) {
  const query = new URLSearchParams(params).toString();
  const url = `${BASE_URL}/content${query ? "?" + query : ""}`;

  const response = await fetch(url, {
    headers: {
      "x-project-key": PROJECT_KEY,
      "x-user-key": USER_KEY,
    },
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error);
  }

  return response.json();
}

// List all video links
const videos = await fetchContent({ type: "video_link", all_folders: "true" });
console.log(`Found ${videos.meta.total_count} videos`);

// Search by tag
const tagged = await fetchContent({
  tag: "topic",
  tag_value: "neurologia",
  all_folders: "true",
});

Integration avec Python (requests)

import requests

PROJECT_KEY = "sk_proj_..."
USER_KEY = "sk_user_..."
BASE_URL = "https://sutram.io/api/v1"

headers = {
    "x-project-key": PROJECT_KEY,
    "x-user-key": USER_KEY,
}

# List root folders
folders = requests.get(f"{BASE_URL}/folders", headers=headers).json()

# Get content in a folder
folder_id = folders["folders"][0]["id"]
content = requests.get(
    f"{BASE_URL}/content",
    headers=headers,
    params={"folder_id": folder_id},
).json()

# Search by multiple tags
import json
tags = json.dumps([
    {"key": "patient", "value": "joão"},
    {"key": "year", "value": "2024"},
])
results = requests.get(
    f"{BASE_URL}/content",
    headers=headers,
    params={"tags": tags, "all_folders": "true"},
).json()

print(f"Found {results['meta']['total_count']} items")

Depannage

401 Non autorise

  • Verifiez que les deux en-tetes x-project-key et x-user-key sont presents
  • Verifiez que les cles n'ont pas ete revoquees
  • Assurez-vous d'etre un membre actif (pas un viewer) du projet

404 Non trouve

  • Verifiez que l'ID du dossier/contenu appartient au projet authentifie
  • Verifiez que l'element n'a pas ete supprime

Resultats vides avec recherche par tags

  • Ajoutez all_folders=true pour rechercher dans tous les dossiers (sans cela, seuls les elements racine sont renvoyes)
  • La recherche par tags est insensible a la casse — verifiez les fautes de frappe dans les noms de cles
  • Utilisez d'abord GET /api/v1/content?tag=VOTRE_CLE&all_folders=true sans valeur pour verifier que la cle de tag existe

Le parametre tags renvoie une erreur

  • Le parametre tags doit etre un tableau JSON valide : [{"key": "...", "value": "..."}]
  • Encodez la chaine JSON en URL lorsque vous la passez en parametre de requete
  • Chaque condition doit avoir un champ key ; value est optionnel