API REST

Endpoints

Los endpoints REST que puede llamar una clave de API del espacio de trabajo, agrupados por aquello sobre lo que trabajan, con los parámetros principales de cada uno.

Convenciones

Todas las rutas son relativas a https://teddit.io/api. Envía la clave como se describe en Autenticación.

  • Acceso es el rol mínimo de clave que puede llamar al endpoint: viewer (una clave de Lectura), member (Lectura + edición) o admin (Lectura + análisis). Un rol superior siempre puede llamarlo también.
  • :orgId es el id del espacio de trabajo de GET /whoami. :id es un id de sitio de GET /orgs/:orgId/projects.
  • Parámetros de periodo. Los endpoints de informes toman period (day, week, month o quarter; por defecto week) y start (cualquier fecha dentro del periodo que quieras, YYYY-MM-DD; por defecto el último periodo). Sus respuestas repiten period y start y listan cada periodo con datos en periods.
  • En las respuestas, “nombrado” es mentioned, “enlazado” es ownCited, tu posición es brandRank, visibility es la puntuación de visibilidad, y un asistente es un provider con la clave openai, anthropic, perplexity, gemini, google_aio o google_ai_mode.

Las herramientas MCP devuelven los mismos datos, así que la descripción de una herramienta describe también el endpoint correspondiente.

Espacio de trabajo

MétodoRutaAccesoFinalidad
GET/whoamiviewerEl espacio de trabajo, el rol y el nombre de la clave.
GET/orgs/:orgIdviewerEl espacio de trabajo: su nombre y el rol de quien llama.
GET/orgs/:orgId/dashboardviewerCada sitio con sus números actuales, los asistentes conectados, y los límites del espacio de trabajo con los análisis usados este mes.
GET/orgs/:orgId/projectsviewerLos sitios del espacio de trabajo.
GET/orgs/:orgId/usageviewerEl saldo, las recargas, y lo que han costado los análisis: este mes en total y por sitio con el tope de cada uno, los últimos seis meses, y el precio por respuesta del modelo por defecto de cada asistente.
POST/orgs/:orgId/projectsadminAñadir un sitio.
GET/orgs/:orgId/providersviewerLos asistentes, el modelo con el que responde cada uno, y si cada uno está conectado.
GET/orgs/:orgId/membersviewerMiembros, invitaciones pendientes y el límite de miembros del espacio de trabajo.
POST/orgs/:orgId/invitationsadminInvitar a una persona por correo.
DELETE/orgs/:orgId/invitations/:invitationIdadminCancelar una invitación pendiente.
PATCH/orgs/:orgId/members/:userIdadminCambiar el rol de un miembro.
DELETE/orgs/:orgId/members/:userIdadminQuitar a un miembro.

Añadir un sitio toma name y url (ambos obligatorios), y opcionalmente industry, brandTerms (otros nombres, hasta 50), competitors (objetos con name y domain, hasta 50), language (por defecto English) y location (por defecto United States).

Invitar toma email y role (viewer, member o admin; por defecto member). Cambiar un rol toma role. Lo que un admin puede y no puede hacer con otros miembros está en la página Roles.

No disponible para claves: todo lo que hay bajo /auth y /account, crear, eliminar y abandonar espacios de trabajo, renombrar un espacio de trabajo (PATCH /orgs/:orgId, solo Owner), recargar y facturas (solo Owner) y gestionar claves (/orgs/:orgId/tokens).

Sitios

MétodoRutaAccesoFinalidad
GET/projects/:idviewerEl sitio, el rol de quien llama y el número de respuestas guardadas.
PATCH/projects/:idmemberCambiar los ajustes del sitio. El tope, los ajustes de análisis y allowedProviders (los asistentes a los que puede preguntar el sitio, null para todos) necesitan un admin.
PATCH/projects/:id/scheduleadminActivar o desactivar los análisis programados.
POST/projects/:id/reanalysememberVolver a leer cada respuesta guardada con los nombres y competidores actuales. No llama a ningún asistente.

Cambiar ajustes toma cualquiera de estos campos:

  • name, brandTerms: el nombre de la marca y sus otros nombres. Cambiar cualquiera de los dos vuelve a leer todas las respuestas guardadas; la respuesta lleva entonces un resumen reanalysis.
  • industry, language, location (el país).
  • scanFrequencyDays (de 1 a 365): el intervalo entre análisis programados.
  • monthlyCapUsd: el tope mensual del sitio en dólares estadounidenses. null o 0 lo quita.
  • scanSettings: los ajustes de análisis guardados, sustituidos en bloque. Un objeto con providers (claves de asistente; omitido significa todos los conectados), models (clave de asistente a modelo), category, budgetUsd (lo máximo que puede costar un análisis; 0 significa el doble de su estimación) y skipAtCap (false deja que los análisis empiecen aunque el tope mensual esté gastado).

Calendario toma enabled (true o false). Activar el calendario fija el primer análisis para la noche siguiente (UTC); las respuestas de un análisis programado llegan en unas horas.

Eliminar un sitio, con sus prompts, análisis y respuestas, es para un Owner con sesión iniciada y no está disponible para claves.

Buyer personas

GET /projects/:id/personas lista los personas de un sitio con cuántos prompts pregunta cada uno; POST (member) añade uno con name (hasta 80 caracteres) y context (hasta 600): quién pregunta, con sus palabras. PATCH /projects/:id/personas/:personaId cambia cualquiera de los dos; DELETE quita uno, y sus prompts se preguntan sin persona desde el siguiente análisis. Los prompts toman personaId al crear, editar y editar en bloque (null lo quita). Cada respuesta conserva las palabras con que se hizo como context.

Informes

Todos estos son GET, necesitan viewer y toman los parámetros de periodo.

RutaDevuelve
/projects/:id/reportEl Panel: report con los recuentos de ahora y de antes, la cuota de voz, el ranking de marcas, filas por asistente, qué cambió, las fuentes más citadas, las series del gráfico y scope: sobre qué se midieron los números (asistentes, respuestas por pregunta, lugar, idioma, de dónde se leyeron las respuestas de cada asistente). report es null antes del primer análisis.
/projects/:id/sharesEnlaces compartidos del informe del sitio (admin). POST con un label opcional crea uno y devuelve su url; DELETE /projects/:id/shares/:shareId lo revoca para siempre. Un enlace abre /share/:token sin iniciar sesión, para cualquier periodo, firmado con el nombre y logotipo de informe del espacio de trabajo (PATCH /orgs/:id con reportName y reportLogo, Owner).
/projects/:id/trendsDiez periodos: las proporciones del sitio por periodo, cada prompt activo con sus veredictos por periodo, prompts ganados y perdidos, proporciones por categoría, y las listas held, volatile y lost.
/projects/:id/sentimentTono por asistente entre las respuestas que te nombran. Añade answers=1 para obtener esas respuestas una a una, cada una con su tono y la frase citada.
/projects/:id/sourcesCada dominio que citaron los asistentes, qué tipo de sitio es y si las respuestas que lo citan te nombran; y tus propias páginas con los prompts y asistentes que enlazan a cada una.
/projects/:id/competitorsLos competidores seguidos, con qué frecuencia se nombra cada marca en total y por asistente, recuentos cara a cara, y sugerencias de nombres no seguidos.
/projects/:id/competitors/:competitorIdUn competidor frente a ti: números emparejados, por asistente, por categoría, los prompts divididos en tres grupos, y sus páginas citadas.
curl "https://teddit.io/api/projects/12/report?period=month&start=2026-09-15" \
  -H "Authorization: Bearer tdt_…"

Cómo se calculan los números de estas respuestas: Métricas y estados.

Prompts y categorías

MétodoRutaAccesoFinalidad
GET/projects/:id/promptsviewerLa lista de prompts con el último veredicto de cada asistente y los cuadros del historial.
GET/projects/:id/prompts/export.csvviewerLa misma lista como archivo CSV.
POST/projects/:id/promptsmemberAñadir un prompt.
PATCH/projects/:id/prompts/:promptIdmemberEditar un prompt.
POST/projects/:id/prompts/bulkmemberFijar un estado o una categoría en muchos prompts, o eliminarlos.
POST/projects/:id/prompts/importmemberImportar prompts desde texto CSV.
POST/projects/:id/prompts/rewriteadminReescribir consultas de búsqueda importadas como preguntas completas. No se cobra; necesita un saldo mayor que cero. Hasta 10 llamadas por hora.
GET/projects/:id/prompts/rewrite/pendingviewerCuántos prompts importados siguen siendo consultas en bruto.
GET/projects/:id/prompts/:promptIdviewerUn prompt: el último veredicto por asistente, cada respuesta a lo largo del tiempo, el historial semana a semana.
GET/projects/:id/prompts/:promptId/answerviewerUna respuesta palabra por palabra, con las marcas nombradas, las fuentes y las búsquedas web.
GET/projects/:id/categoriesviewerLas categorías con sus recuentos de prompts.
POST/projects/:id/categoriesmemberAñadir una categoría vacía.
POST/projects/:id/categories/mergememberRenombrar, combinar o eliminar categorías.

La lista y la exportación toman los mismos parámetros de consulta: q (búsqueda de texto), category, status (draft, active, paused), intent, verdict (named, lost, cited, missing, failed), competitor (el nombre de un competidor seguido), stability (held, volatile, lost) y scanned (yes, never). La lista toma además sort (created, text, category, rank, scanned), dir (asc, desc), page, perPage (de 5 a 200, por defecto 20) y los parámetros de periodo, que fijan lo que representa un cuadro del historial.

Añadir toma text (de 3 a 500 caracteres, obligatorio), category o categories (una lista de hasta 8), intent (por defecto informational), funnel (por defecto awareness) y status (por defecto active). Un texto que ya se sigue responde 409. Editar toma los mismos campos, todos opcionales; categories sustituye toda la lista.

En bloque toma ids (de 1 a 5000) y status, category o delete: true. Eliminar un prompt elimina sus respuestas.

Importar toma contents (el texto del archivo, hasta 2.000.000 de caracteres), status (por defecto draft) y dryRun. Devuelve rows, created, updated, skipped y categories. El formato del archivo está en la página Importar prompts.

Una respuesta toma engine (una clave de asistente; por defecto el primer asistente que respondió) o r (el id de una respuesta pasada, tomado de los results del prompt).

Combinar categorías toma names (las categorías que fusionar) e into (el nombre en el que se convierten). Un nombre es un cambio de nombre, varios son una combinación, y un into vacío quita las categorías de sus prompts.

Competidores y páginas

MétodoRutaAccesoFinalidad
POST/projects/:id/competitorsmemberSeguir a un competidor.
PATCH/projects/:id/competitors/:competitorIdmemberCambiar un competidor. Solo cambian los campos enviados.
DELETE/projects/:id/competitors/:competitorIdmemberDejar de seguir a un competidor. Las respuestas guardadas se conservan.
GET/projects/:id/pagesviewerTus páginas del sitemap con sus títulos, y si una respuesta actual enlaza a cada una.
GET/projects/:id/crawlersviewerLo que robots.txt deja leer a cada rastreador de IA, la línea decisiva, llms.txt, y el historial de comprobaciones.
POST/projects/:id/crawlers/checkmemberVolver a leer robots.txt y llms.txt ahora; devuelve lo mismo que el GET.
GET/projects/:id/searchesviewerLas búsquedas web que realizaron los asistentes para los prompts activos, las más comunes primero.
GET/projects/:id/pages/:pageId/promptsviewerLos prompts cuyas respuestas actuales enlazan a una página.
POST/projects/:id/pages/import-sitemapmemberVolver a leer el sitemap del sitio ahora y añadir las páginas aún no listadas. Hasta 10 llamadas por hora.

Seguir toma name (obligatorio), domain, aliases (otros nombres, hasta 30), color y logo. Cambiar toma los mismos campos, todos opcionales: solo cambia lo que envías, aliases sustituye toda la lista, y domain: null quita el dominio. Los tres endpoints de competidores vuelven a leer las respuestas guardadas cuando cambian los nombres y devuelven el resultado como reanalysis.

Páginas toma q, section (la primera parte de la ruta), shown (yes o no), page y perPage (de 5 a 200, por defecto 50).

Análisis

MétodoRutaAccesoFinalidad
GET/projects/:id/scan-optionsviewerLos asistentes conectados, sus modelos con un coste por respuesta, prompts activos por categoría, análisis usados este mes y el gasto del sitio este mes.
POST/projects/:id/scans/estimateviewerEl coste previsto de un análisis tal como está configurado.
POST/projects/:id/scansadminIniciar un análisis.
GET/projects/:id/scans/liveviewerEl análisis en curso, si lo hay, con el ritmo y el tiempo restante.
POST/projects/:id/scans/:scanId/canceladminDetener un análisis en curso.
GET/projects/:id/scansviewerLos últimos 30 análisis.
GET/projects/:id/scans/:scanIdviewerUn análisis y las respuestas que recogió, 25 por página.

Estimar e iniciar toman el mismo cuerpo. Todos los campos son opcionales:

  • providers: claves de asistente. Vacío significa todos los asistentes conectados.
  • promptIds: un conjunto elegido de prompts. Vacío significa todos los prompts activos. Los prompts que no están activos se omiten.
  • category: analizar una categoría.
  • sample: analizar este número de prompts, elegidos al azar.
  • models: clave de asistente a modelo, de las opciones de scan-options. chatgpt-app y gemini-app (rápidos: responden al momento) y chatgpt-app-queue y gemini-app-queue (lentos y más baratos: unos minutos) toman la respuesta tal como la muestra la aplicación.
  • saved: true toma los asistentes, modelos y categoría de los ajustes de análisis guardados del sitio en lugar de esta petición. Al iniciar toma también el límite por análisis guardado.
  • Solo al iniciar: budgetUsd (detener cuando el análisis haya costado esta cantidad; omitido, el doble de su estimación) y label.

Estimar devuelve prompts, answers, cost y formatted. Iniciar devuelve el análisis, responde 402 cuando el saldo no cubre el análisis, y 400 con el motivo para cualquier otra cosa que le impida empezar. Los motivos, y cómo se cuenta el coste, están en la página Saldo y límites de gasto.

Un análisis toma tab (all, notNamed, competitorsOnly, errors), engine (una clave de asistente) y page. Los estados de un análisis son queued, running, cancelling, cancelled, done y failed.

Un ejemplo completo

Encontrar el sitio, añadir un prompt, poner precio a un análisis de una categoría, ejecutarlo y leer el resultado. Iniciar el análisis necesita una clave de Lectura + análisis.

KEY="tdt_…"
API="https://teddit.io/api"

# 1. Which workspace is this key for?
curl "$API/whoami" -H "Authorization: Bearer $KEY"
#    → "org": { "id": 3, … }

# 2. The sites of the workspace
curl "$API/orgs/3/projects" -H "Authorization: Bearer $KEY"
#    → "projects": [{ "id": 12, "domain": "brightloop.example", … }]

# 3. Add a prompt
curl -X POST "$API/projects/12/prompts" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"text": "What does email automation cost for 10,000 contacts?", "category": "pricing", "intent": "commercial"}'

# 4. What would a scan of that category cost?
curl -X POST "$API/projects/12/scans/estimate" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"category": "pricing"}'
#    → { "prompts": …, "answers": …, "cost": …, "formatted": "$…" }

# 5. Run it, and stop at 2 dollars
curl -X POST "$API/projects/12/scans" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"category": "pricing", "budgetUsd": 2}'

# 6. Follow it until "run" is null
curl "$API/projects/12/scans/live" -H "Authorization: Bearer $KEY"

# 7. Read this week's report
curl "$API/projects/12/report" -H "Authorization: Bearer $KEY"