SlateCore API

API REST de lectura para tu slate, equipo, festivales, calendario y finanzas. Pensada para que tu web pública (o la de tus coproductoras) lea datos en tiempo real desde SlateCore — sin tener que duplicarlos en un CMS aparte. También exponemos webhooks salientes para que tu sitio se invalide en cuanto cambies algo aquí adentro.

Base URL

https://slatecore.app/api/v1

Genera tu API key desde Configuración → API & Webhooks dentro de la app. Disponible para tier Studio y Label.

Autenticación

Cada request requiere el header X-API-Key con tu key. Las keys se hashean con SHA-256 al guardarse — la versión en claro solo se ve una vez al crearla, así que guárdala bien (manager de secretos / variable de entorno). Si la pierdes, revoca y genera una nueva.

bash
curl -H "X-API-Key: sk_live_..." \
  https://slatecore.app/api/v1/ping

Cada key trae un set de scopes (projects:read, team:read, etc.). Un endpoint que requiere un scope que tu key no tiene devuelve 403 insufficient_scope.

Rate limits

Límites por minuto y por día configurables por key (defaults: 60/min, 10 000/día). Cuando excedes, el endpoint devuelve 429 rate_limit_exceeded con el header Retry-After. Las respuestas se cachean en el edge con s-maxage=30, stale-while-revalidate=60 — usa la cache para no churnar requests por cada visitante de tu web.

Errores

Todos los errores siguen el shape { error, message }:

400bad_requestQuery inválida (ej: limit > 100).
401invalid_api_keyHeader X-API-Key ausente o key revocada.
403insufficient_scopeLa key no tiene el scope que requiere este endpoint.
404not_foundEl recurso no existe o no es accesible para tu tenant.
429rate_limit_exceededExcediste el límite por minuto o por día.
500internal_errorError de nuestro lado. Reintenta con backoff exponencial.

Endpoints

Visibilidad: privado por default

Esta API solo devuelve los proyectos que marcaste como públicos. Por default un proyecto es privado y no aparece aquí ni en los sitios web que consumen la API. Elige qué exponer en Configuración → API & Webhooks → Visibilidad pública en la API: tus proyectos quedan agrupados por slate (Slate confirmado, En consideración, etc.) con un switch por proyecto y un botón para publicar el grupo entero de una. El control vive en la config de la API —no en el proyecto— a propósito: qué se hace público lo decide quien administra la API (permiso manageApiKeys), no cualquiera con acceso al proyecto. Si coproduces, cada productora publica el proyecto compartido en su propia API de forma independiente. El filtro aplica a /projects, /projects/:id, sus awards, y los /events, /milestones y /finanzas de cada proyecto.

Recomendado: publica tu slate confirmado y deja en privado lo que siga en consideración o descartado. Revisa esta lista antes de compartir tu API key o conectar tu sitio.

GET/pingno scope required

Health check. Returns 200 for any active key.

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  https://slatecore.app/api/v1/ping

Response

json
{ "ok": true, "tenant_id": "..." }
GET/brandingno scope required

Returns the caller tenant's public branding (name, logos, color).

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  https://slatecore.app/api/v1/branding

Response

json
{
  "data": {
    "name": "Mi Productora",
    "logo_url": "https://...",
    "favicon_url": "https://...",
    "apple_touch_icon_url": "https://...",
    "primary_color": "#2563eb"
  }
}
GET/projectsprojects:read

List of accessible projects (own + collab) you've published to the public API. Paginated. Only published projects appear — manage which in Settings → API & Webhooks → Public visibility.

Query params

pageintPage number, defaults to 1.
limitintPage size 1–100, defaults to 20.

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  "https://slatecore.app/api/v1/projects?page=1&limit=20"

Response

json
{
  "data": [
    {
      "id": "uuid",
      "nombre": "La Balada del Chupacabras",
      "logline": "...",
      "estatus": "Producción",
      "tipo_de_proyecto": "Largometraje",
      "genero": ["Coming of Age", "Comedia"],
      "poster_url": "https://...",
      "productoras_info": [
        { "nombre": "TM Cine", "logoUrl": "...", "website": "..." }
      ],
      "part_of_slate": "Yes",
      "trailer_url": "https://www.youtube.com/watch?v=…",
      "collaboration_role": null
    }
  ],
  "meta": { "total": 14, "page": 1, "limit": 20 }
}
GET/projects/:idprojects:detail

Full project detail including lead/authors/crew/comps. Returns 404 unless the project is published (public visibility on).

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  https://slatecore.app/api/v1/projects/<uuid>

Response

json
{
  "data": {
    "id": "uuid",
    "nombre": "...",
    "logline": "...",
    "sinopsis": "...",
    "autores": [{ "nombre": "...", "apellido": "..." }],
    "crew": [{ "rol": "Dirección", "nombre": "..." }],
    "comparables": [{ "titulo": "...", "año": 2023 }],
    "part_of_slate": "Yes",
    "trailer_url": "https://vimeo.com/123456789/abcdef"
  }
}
GET/projects/:id/awardsawards:read

Festival selections / awards for that project.

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  https://slatecore.app/api/v1/projects/<uuid>/awards

Response

json
{
  "data": [
    {
      "festival": "Sundance",
      "año": 2025,
      "estatus": "Selección oficial",
      "premio": null
    }
  ]
}
GET/teamteam:read

Public team directory of the caller's tenant.

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  https://slatecore.app/api/v1/team

Response

json
{
  "data": [
    {
      "id": "uuid",
      "nombre": "Sebastián Sariñana",
      "rol": "Dirección",
      "foto_url": "https://...",
      "imdb_url": "https://www.imdb.com/name/..."
    }
  ]
}
GET/eventsevents:read

Calendar events visible to the caller (own + collab projects).

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  https://slatecore.app/api/v1/events

Response

json
{
  "data": [
    {
      "id": "uuid",
      "titulo": "Pitch a Netflix",
      "fecha": "2026-06-12T15:00:00Z",
      "proyecto_id": "uuid"
    }
  ]
}
GET/milestonesmilestones:read

Milestones visible to the caller (own + collab projects).

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  https://slatecore.app/api/v1/milestones

Response

json
{
  "data": [
    {
      "id": "uuid",
      "titulo": "Primer corte",
      "fecha_objetivo": "2026-09-01",
      "completado": false,
      "proyecto_id": "uuid"
    }
  ]
}
GET/finanzasfinanzas:read

Per-project P&L summaries, grouped by currency. Aggregates only — never row-level data. Sensitive scope: opt-in per key.

Request

bash
curl -H "X-API-Key: $SLATE_API_KEY" \
  https://slatecore.app/api/v1/finanzas

Response

json
{
  "data": [
    {
      "proyecto_id": "uuid",
      "totals": {
        "MXN": { "ingresos": 12000000, "gastos": 8500000 },
        "USD": { "ingresos": 50000, "gastos": 12000 }
      }
    }
  ]
}

Webhooks

Recibe un POST en tu URL cada vez que cambia un dato en SlateCore — útil para revalidar tu Next.js, invalidar cache de Webflow, o disparar deploys. Registra el webhook desde Configuración → API & Webhooks en la app: eliges los eventos que te interesan y nosotros generamos un secret HMAC para que verifiques el origen. Reintentamos hasta 3 veces con backoff (1 min, 5 min, 15 min) si tu endpoint responde con 5xx o no responde a tiempo.

Eventos

project.created · project.updated · project.deleted

INSERT/UPDATE/DELETE on projects, plus any change to a row in project_collaborators (alta/baja/slate change). Fans out to every active collab tenant.

award.created · award.updated · award.deleted

INSERT/UPDATE/DELETE on festivales. Fans out to collabs.

team.created · team.updated · team.deleted

INSERT/UPDATE/DELETE on crew_cast. Fans out to collabs.

milestone.created · milestone.updated · milestone.deleted

INSERT/UPDATE/DELETE on milestones. Fans out to collabs.

event.created · event.updated · event.deleted

INSERT/UPDATE/DELETE on eventos. Fans out when the event is project-scoped; tenant-only events stay owner-only.

Payload

Todo evento llega con la misma forma. tenant_id siempre apunta al tenant receptor — para coproducciones llega un evento por cada tenant que colabora. owner_tenant_id identifica al dueño del recurso cuando cae por fan-out.

json
{
  "event": "project.updated",
  "id": "uuid-del-recurso",
  "tenant_id": "uuid-del-receptor",
  "proyecto_id": "uuid-o-null",
  "owner_tenant_id": "uuid-o-null",
  "reason": "collaboration_changed",
  "timestamp": "2026-05-05T16:30:00Z"
}

Headers que mandamos: X-Slate-Event, X-Slate-Signature, X-Slate-Delivery (id único — útil para deduplicar en tu lado).

Verifica la firma HMAC

Cada delivery trae X-Slate-Signature: sha256=<hmac>. Calcula el HMAC-SHA256 del cuerpo crudo (no re-stringifies el JSON, usa los bytes recibidos) con tu secret y compara antes de confiar.

javascript
const crypto = require('crypto')

app.post('/slate-webhook', (req, res) => {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.SLATE_WEBHOOK_SECRET)
    .update(req.rawBody)         // bytes crudos, no JSON.stringify
    .digest('hex')

  if (req.header('x-slate-signature') !== expected) {
    return res.status(401).end()
  }

  // Responde 2xx rápido — procesa async si es lento.
  res.status(200).end()
})

Cross-tenant fan-out

Cuando edites un proyecto compartido, los webhooks de cada tenant colaborador también se disparan con su propio tenant_id y owner_tenant_id apuntando al dueño. Cada consumidor refetchea con su API key y obtiene su propia vista (incluyendo su part_of_slate, que es per-tenant).

Cuando un colaborador cambia algo que solo le afecta a él (su propio part_of_slate en un proyecto compartido), se dispara project.updated con reason: "collaboration_changed" solo a ese tenant — el dueño no recibe el evento, evita spam.

Acceso por plan

La API y los webhooks están disponibles en Studio y Label. Los planes Indie y School no incluyen acceso a la API. Compara planes en slatecore.app. Para soporte: hola@slatecore.app.