Sutram REST API v1
Versão: 0.89.0 Data: 19/02/2026 Status: Em produção
Visão geral
A REST API do Sutram fornece endpoints JSON para consumo externo do conteúdo de projetos (pastas, arquivos, links). Ela utiliza a mesma autenticação de chave dupla do MCP Server (x-project-key + x-user-key), portanto qualquer projeto com Acesso Remoto habilitado fica automaticamente acessível pela REST API.
Casos de uso
- Integração com plataforma APM — Consumir conteúdo do Sutram (eventos, notícias, podcasts, webinars) como repositório central (SSOT)
- Dashboards personalizados — Criar páginas de listagem de conteúdo fora do Sutram
- Aplicativos móveis — Buscar arquivos e links com URLs de download pré-assinadas
- Automação — Descoberta e recuperação programática de conteúdo via scripts ou CI/CD
URL base
https://sutram.io/api/v1
Desenvolvimento:
http://localhost:4001/api/v1
Como funciona
External Client (app, script, dashboard)
|
| HTTPS + JSON
v
Sutram REST API
/api/v1/*
|
| Dual Key Authentication
v
Project Content (folders, files, links, tags)
Autenticação
Toda requisição deve incluir dois headers:
| Header | Valor | Descrição |
|---|---|---|
x-project-key |
sk_proj_... |
Identifica o projeto |
x-user-key |
sk_user_... |
Identifica o usuário |
Ambas as chaves são criadas pela interface web do Sutram. Consulte o Guia do Usuário do MCP Server para instruções passo a passo.
Exemplo
curl -H "x-project-key: sk_proj_ej8NWMisd2rJgMwAJ22T..." \
-H "x-user-key: sk_user_zQD0BjH56nQhOgX3uxni..." \
https://sutram.io/api/v1/project
Respostas de erro
Quando a autenticação falha, a API retorna 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" }
Permissões
| Papel | Acesso |
|---|---|
| Owner | Acesso total de leitura |
| Admin | Acesso total de leitura |
| Member | Acesso total de leitura |
| Viewer | Sem acesso (401) |
A REST API v1 é somente leitura. Operações de escrita (upload, exclusão, renomeação, movimentação) estão disponíveis pelo MCP Server.
Endpoints
GET /api/v1/project
Retorna informações sobre o projeto autenticado.
Exemplo de requisição:
curl -H "x-project-key: $PROJECT_KEY" \
-H "x-user-key: $USER_KEY" \
https://sutram.io/api/v1/project
Resposta:
{
"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
Lista as pastas do nível raiz do projeto.
Exemplo de requisição:
curl -H "x-project-key: $PROJECT_KEY" \
-H "x-user-key: $USER_KEY" \
https://sutram.io/api/v1/folders
Resposta:
{
"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
Retorna os detalhes de uma pasta, suas subpastas e seus itens de conteúdo.
Parâmetros de caminho:
| Parâmetro | Tipo | Descrição |
|---|---|---|
id |
UUID | ID da pasta |
Exemplo de requisição:
curl -H "x-project-key: $PROJECT_KEY" \
-H "x-user-key: $USER_KEY" \
https://sutram.io/api/v1/folders/f1a2b3c4-...
Resposta:
{
"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
}
}
Respostas de erro:
| Status | Corpo | Quando |
|---|---|---|
| 404 | {"error": "Folder not found"} |
A pasta não existe ou pertence a outro projeto |
GET /api/v1/content
Lista itens de conteúdo com filtragem, busca por tags, busca por texto e paginação.
Query parameters:
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
folder_id |
UUID | — | Filtrar por pasta. Sem este parâmetro, retorna apenas itens do nível raiz. |
all_folders |
boolean | false |
Se true, busca em todas as pastas (não apenas na raiz). Necessário para consultas de tag/busca em todo o projeto. |
type |
string | — | Filtrar por tipo de conteúdo: "file", "web_link", "video_link", "audio_link" |
tag |
string | — | Chave de tag única para filtrar (ex.: tag=category) |
tag_value |
string | — | Valor da tag para correspondência (usado com tag). Correspondência de substring, sem distinção de maiúsculas/minúsculas. |
tags |
JSON | — | Múltiplas condições AND como array JSON (ex.: tags=[{"key":"topic","value":"neuro"}]) |
search |
string | — | Buscar pelo nome do item (correspondência de substring, sem distinção de maiúsculas/minúsculas) |
page |
integer | 1 |
Número da página |
per_page |
integer | 50 |
Itens por página (máximo: 100) |
Comportamento da busca por tags:
- Correspondência de chave: Correspondência exata, sem distinção de maiúsculas/minúsculas (
"Category"corresponde a"category") - Correspondência de valor: Correspondência de substring, sem distinção de maiúsculas/minúsculas (
"neuro"corresponde a"Neurologia Avançada") - Múltiplas condições (parâmetro
tags): Todas as condições devem ser satisfeitas (lógica AND) - Sem valor: Quando
tag_valueé omitido, corresponde a qualquer item que possua a chave de tag, independentemente do valor
Exemplo — listar itens da raiz
curl -H "x-project-key: $PROJECT_KEY" \
-H "x-user-key: $USER_KEY" \
"https://sutram.io/api/v1/content"
Exemplo — listar itens em uma pasta
curl -H "x-project-key: $PROJECT_KEY" \
-H "x-user-key: $USER_KEY" \
"https://sutram.io/api/v1/content?folder_id=f1a2b3c4-..."
Exemplo — filtrar por tipo
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"
Exemplo — busca por tag única
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"
Exemplo — busca AND com múltiplas 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"
O parâmetro tags acima é a versão codificada em URL de:
[{"key": "patient", "value": "joão"}, {"key": "year", "value": "2024"}]
Exemplo — buscar por nome
curl -H "x-project-key: $PROJECT_KEY" \
-H "x-user-key: $USER_KEY" \
"https://sutram.io/api/v1/content?search=report&all_folders=true"
Exemplo — listagem paginada
curl -H "x-project-key: $PROJECT_KEY" \
-H "x-user-key: $USER_KEY" \
"https://sutram.io/api/v1/content?page=2&per_page=20"
Resposta:
{
"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
}
}
Campos do contentable por tipo:
O contentable é serializado sob uma chave correspondente ao tipo do item:
| Tipo | Chave | Campos |
|---|---|---|
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
Retorna os detalhes completos de um único item de conteúdo, incluindo URLs de download pré-assinadas para arquivos.
Parâmetros de caminho:
| Parâmetro | Tipo | Descrição |
|---|---|---|
id |
UUID | ID do item de conteúdo |
Exemplo de requisição:
curl -H "x-project-key: $PROJECT_KEY" \
-H "x-user-key: $USER_KEY" \
https://sutram.io/api/v1/content/d5e6f7a8-...
Resposta (arquivo):
{
"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-..."
}
}
}
Resposta (link de vídeo):
{
"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"
}
}
}
Resposta (link de áudio):
{
"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"
}
}
}
Resposta (link 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"
}
}
}
Diferenças entre resposta de detalhe e listagem:
O endpoint /content/:id retorna campos adicionais em comparação com o endpoint de listagem:
| Campo | Listagem (/content) |
Detalhe (/content/:id) |
|---|---|---|
folder_path |
Não | Sim |
file.version |
Não | Sim |
file.download_url |
Não | Sim (pré-assinada, temporária) |
web_link.fetched_description |
Não | Sim |
video_link.duration_seconds |
Não | Sim |
video_link.fetched_title |
Não | Sim |
audio_link.duration_seconds |
Não | Sim |
audio_link.fetched_title |
Não | Sim |
Respostas de erro:
| Status | Corpo | Quando |
|---|---|---|
| 404 | {"error": "Content item not found"} |
O item não existe ou pertence a outro projeto |
Tags de itens de conteúdo
Tags são pares de chave-valor em formato de texto livre, associados a itens de conteúdo e pastas. Elas permitem metadados estruturados e recursos avançados de busca.
Restrições de tags
| Restrição | Limite |
|---|---|
| Máximo de tags por item | 50 |
| Comprimento máximo da chave | 100 caracteres |
| Comprimento máximo do valor | 500 caracteres |
| Tipos de chave e valor | Apenas strings |
Gerenciamento de tags
As tags dos itens de conteúdo são gerenciadas pelas ferramentas do MCP Server:
| Ferramenta MCP | Descrição |
|---|---|
sutram_set_item_tags |
Definir/substituir todas as tags de um item de conteúdo |
sutram_search_items |
Buscar itens por tag (condição única ou AND com múltiplas condições) |
sutram_get_item_tag_keys |
Listar todas as chaves de tag distintas entre os itens |
Consulte o Guia do Usuário do MCP Server para detalhes sobre essas ferramentas.
Consultando tags pela REST API
Use os query parameters tag, tag_value e tags no GET /api/v1/content:
# Find all items tagged with "category"
curl ... "https://sutram.io/api/v1/content?tag=category&all_folders=true"
# Find items where category contains "report"
curl ... "https://sutram.io/api/v1/content?tag=category&tag_value=report&all_folders=true"
# Find items matching multiple conditions (AND)
curl ... "https://sutram.io/api/v1/content?tags=[{\"key\":\"patient\",\"value\":\"joão\"},{\"key\":\"year\",\"value\":\"2024\"}]&all_folders=true"
Comparação: REST API vs. MCP Server
| Funcionalidade | REST API (/api/v1) |
MCP Server (/mcp) |
|---|---|---|
| Protocolo | HTTP/JSON | JSON-RPC 2.0 (MCP) |
| Ler conteúdo | Sim | Sim |
| Buscar por tags | Sim | Sim |
| URLs de download | Sim (pré-assinadas) | Sim (pré-assinadas) |
| Upload de arquivos | Não | Sim |
| Criar links | Não | Sim |
| Criar pastas | Não | Sim |
| Definir tags | Não | Sim |
| Mover/renomear/excluir | Não | Sim |
| Autenticação | Mesma chave dupla | Mesma chave dupla |
| Ideal para | Aplicativos externos, dashboards, scripts | Assistentes de IA, automação |
Limites de requisições
Atualmente não há limites de requisições na REST API. Isso pode mudar em versões futuras. Por favor, seja razoável com a frequência de requisições.
Versionamento
A API é versionada pelo caminho da URL (/api/v1). Mudanças que quebram compatibilidade serão introduzidas em novas versões (/api/v2). Adições que não quebram compatibilidade (novos campos, novos parâmetros opcionais) podem ser adicionadas à versão atual sem aviso prévio.
Exemplos
Buscar todos os links de vídeo de um projeto
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"
Buscar conteúdo marcado com um tópico específico
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"
Navegar pela hierarquia de pastas
# 1. List root folders
curl ... "https://sutram.io/api/v1/folders"
# 2. Open a specific folder
curl ... "https://sutram.io/api/v1/folders/f1a2b3c4-..."
# 3. Get download URL for a file
curl ... "https://sutram.io/api/v1/content/d5e6f7a8-..."
Paginar por todo o conteúdo
# 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"
# Continue until page >= total_pages from meta
Integração com 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",
});
Integração com 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")
Solução de problemas
401 Unauthorized
- Verifique se ambos os headers
x-project-keyex-user-keyestão presentes - Confirme que as chaves não foram revogadas
- Certifique-se de que você é um membro ativo (não viewer) do projeto
404 Not Found
- Verifique se o ID da pasta/conteúdo pertence ao projeto autenticado
- Confirme que o item não foi excluído
Resultados vazios na busca por tags
- Adicione
all_folders=truepara buscar em todas as pastas (sem isso, apenas itens da raiz são retornados) - A busca por tags não diferencia maiúsculas de minúsculas — verifique erros de digitação nos nomes das chaves
- Use
GET /api/v1/content?tag=SUA_CHAVE&all_folders=truesem valor primeiro para verificar se a chave de tag existe
Parâmetro tags retorna erro
- O parâmetro
tagsdeve ser um array JSON válido:[{"key": "...", "value": "..."}] - Codifique a string JSON em URL ao passá-la como query parameter
- Cada condição deve ter um campo
key;valueé opcional