testivora/API
API · v1

API de Testivora

Lee y administra tus testimonios, espacios y muros por código. Para agencias y clientes que quieren integrar Testivora en sus propios flujos y herramientas.

llms.txt Referencia interactiva OpenAPI
Disponible en los planes Growth y Agency
Empieza en 2 minutos
1) Crea una API key en tu panel → Ajustes → API. 2) Mándala en el header Authorization. 3) Pega el botón “Copiar para LLMs” en ChatGPT o Claude y pídele que te arme la integración.
Lo básico

Autenticación

Cada request lleva una API key tipo Bearer, que creas en Ajustes → API. La llave es de tu cuenta: solo ve los datos de tu cuenta. Guardamos solo el hash de la llave — la verás completa una sola vez.

bash
curl https://api.testivora.com/v1/account \
  -H "Authorization: Bearer tv_live_xxxxxxxxxxxxxxxxxxxx"
Reemplaza el token con tu llave real (empieza con tv_live_).

Las llaves tienen permisos: lectura (GET) y/o escritura (POST/PATCH). Una llave de solo lectura no puede crear ni modificar.

Errores

Todos los errores usan el mismo formato { error: { type, message } } con el código HTTP correcto:

  • 401 — falta el header o la llave es inválida/revocada
  • 402 quota_exceeded — alcanzaste el límite mensual de tu plan (incluye limit, used, tier)
  • 403 — tu plan no incluye API, o la llave no tiene permiso de escritura
  • 404 — el recurso no existe en tu cuenta
  • 422 — error de validación (texto vacío, rating fuera de 1-5, etc.)
  • 429 rate_limited — demasiadas solicitudes (respeta el header Retry-After)

Rate limits

Por llave de API, independiente de tus quotas mensuales:

  • Lecturas: 120/min
  • Escrituras: 30/min

Son distintos de las quotas mensuales del tier (cuántos testimonios puedes crear al mes).

Paginación

Las listas usan cursor: la respuesta trae { object:"list", data, has_more, next_cursor }. Pasa ?cursor=<next_cursor>&limit=50 para la siguiente página. limit por default 25, máximo 100.

URLs de media

Las URLs de video, miniatura y foto son firmadas y expiran (~1 hora). Vuelve a pedir el recurso para refrescarlas; no las guardes a largo plazo. Las URLs externas que tú nos diste se devuelven tal cual.

Endpoints

Account

Tu cuenta: tier, acceso a la API, y uso vs. límites del plan.

GET/v1/account

Devuelve el objeto de la cuenta con uso del periodo actual y límites (null = ilimitado).

bash
curl https://api.testivora.com/v1/account \
  -H "Authorization: Bearer tv_live_xxxxxxxxxxxxxxxxxxxx"
json
{
  "object": "account",
  "tier": "growth",
  "api_access": true,
  "period": "2026-06",
  "usage": { "total_testimonials": 240, "testimonials_this_period": 12 },
  "limits": { "testimonials_per_month": 500, "ai_credits_per_month": 3000 }
}
Respuesta de ejemplo.

Spaces

Tus espacios (cada espacio es una colección de testimonios para un producto o servicio).

GET/v1/spaces

Lista todos tus espacios, del más reciente al más antiguo.

bash
curl https://api.testivora.com/v1/spaces \
  -H "Authorization: Bearer tv_live_..."
json
{
  "object": "list",
  "data": [
    {
      "id": "k57...",
      "object": "space",
      "name": "Mi curso",
      "slug": "mi-curso",
      "primary_color": "#a8412c",
      "logo_url": "https://...signed...",
      "testimonial_count": 240,
      "approved_count": 180,
      "public_wall_url": "https://testivora.com/wall/mi-curso"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
Respuesta de ejemplo.
GET/v1/spaces/{id}

Devuelve un espacio por su id.

Testimonials

El núcleo de la API: leer, importar y administrar testimonios.

GET/v1/testimonials

Lista testimonios dentro de un espacio (paginado por cursor). Filtros:

  • space_id — requerido. el espacio del que quieres listar.
  • status — pending | approved | archived. Omítelo para traer todos.
  • limit — default 25, máximo 100.
  • cursor — el next_cursor de la página anterior.
bash
curl "https://api.testivora.com/v1/testimonials?space_id=SPACE_ID&status=approved&limit=50" \
  -H "Authorization: Bearer tv_live_..."
json
{
  "id": "j97...",
  "object": "testimonial",
  "space_id": "k57...",
  "status": "approved",
  "type": "text",
  "text": "Cerré 3 clientes en una semana. Brutal.",
  "rating": 5,
  "featured": true,
  "tags": ["caso-b2b"],
  "author": { "name": "Ana López", "title": "Coach", "company": "Acme", "photo_url": null },
  "video": null,
  "images": [],
  "created_at": "2026-06-03T01:00:00.000Z",
  "published_at": "2026-06-03T01:00:00.000Z"
}
Cada elemento de data tiene esta forma.
GET/v1/testimonials/{id}

Devuelve un testimonio por su id.

POST/v1/testimonials

Crea un testimonio de TEXTO (importa uno que recolectaste por fuera). Cuenta contra tu quota mensual. Solo space_id y text son obligatorios.

bash
curl -X POST https://api.testivora.com/v1/testimonials \
  -H "Authorization: Bearer tv_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "space_id": "SPACE_ID",
    "text": "Cerré 3 clientes en una semana. Brutal.",
    "rating": 5,
    "status": "approved",
    "tags": ["caso-b2b"],
    "author": { "name": "Ana López", "title": "Coach", "company": "Acme" }
  }'
Devuelve 201 con el testimonio creado.
Solo texto en v1
Los testimonios en video no se crean por API en v1 (necesitan un flujo de subida). Para video usa el recolector.
PATCH/v1/testimonials/{id}

Actualiza el status (pending/approved/archived), el flag featured y/o los tags.

bash
curl -X PATCH https://api.testivora.com/v1/testimonials/TESTIMONIAL_ID \
  -H "Authorization: Bearer tv_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "status": "approved", "featured": true }'

Walls

Tus muros (walls). Un muro completo trae su configuración (template, theme, copy, blocks) MÁS sus testimonios aprobados ya filtrados y ordenados igual que el muro público — listos para renderizar donde quieras.

GET/v1/walls

Lista los resúmenes de todos tus muros.

GET/v1/walls/{id} · /v1/walls?space_slug=

Devuelve un muro completo por id, o el muro publicado de un espacio con ?space_slug=.

bash
curl "https://api.testivora.com/v1/walls?space_slug=mi-curso" \
  -H "Authorization: Bearer tv_live_..."
Eventos en tiempo real

Webhooks

Registra una URL en Ajustes → Webhooks y te mandamos un POST firmado cada vez que pasa algo. Perfecto para etiquetar en tu CRM, avisar en Slack o disparar un Zap/n8n.

  • testimonial.created — se recibió un testimonio nuevo (cualquier estado).
  • testimonial.approved — un testimonio pasó a aprobado.
  • testimonial.deleted — se eliminó un testimonio.

Cada entrega trae este sobre (el id es estable entre reintentos, úsalo para deduplicar):

json
{
  "id": "evt_3hF2bQ...",
  "object": "event",
  "event": "testimonial.approved",
  "version": "1.0",
  "created": "2026-06-03T01:00:00.000Z",
  "attempt": 1,
  "data": { /* the testimonial object (same shape as the API) */ }
}

Verifica que vino de nosotros: recalcula el HMAC-SHA256 del header Testivora-Signature con tu secret y compáralo en tiempo constante.

javascript
import crypto from "node:crypto";

// header = req.headers["testivora-signature"]  ->  "t=1717,v1=abc123…"
function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(",").map((p) => p.split("=")),
  );
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(parts.v1),
    Buffer.from(expected),
  );
}
Responde 2xx rápido; procesa async.
Reintentos y entregas
Si tu endpoint no responde 2xx, reintentamos con backoff exponencial (hasta 6 intentos: 1m, 5m, 30m, 2h, 6h) y luego lo marcamos como fallido. Ve el log de entregas en Ajustes → Webhooks. Tras muchos fallos seguidos pausamos el endpoint automáticamente.
¿Listo para integrar?

Crea tu primera API key desde tu panel y empieza a jalar tus testimonios. Disponible en Growth y Agency.

Crear mi API key →
© 2026 Testivora.
AutomatizacionesGuías de embedInicio