Voltar à Documentação

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-key e x-user-key estã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=true para 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=true sem valor primeiro para verificar se a chave de tag existe

Parâmetro tags retorna erro

  • O parâmetro tags deve 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