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_valueest 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-keyetx-user-keysont 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=truepour 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=truesans valeur pour verifier que la cle de tag existe
Le parametre tags renvoie une erreur
- Le parametre
tagsdoit 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;valueest optionnel