Desarrolladores

Conecta Screenwell con las herramientas que ya usas

Webhooks para cada informe y cambio de etapa, una API REST para tus puestos y candidatos, y un servidor MCP para que Claude, ChatGPT y otros asistentes de IA trabajen con Screenwell por ti.

En todos los planes y en la prueba

Claves de API

Los webhooks, la API y el servidor MCP para scripts usan la clave de API de tu cuenta. La encuentras en la aplicación en Ajustes → API y webhooks. Los conectores de Claude y ChatGPT no necesitan una clave: en su lugar, inicias sesión con Screenwell.

  • Tienes una clave principal y una secundaria, así puedes cambiar a una clave nueva sin tiempo de inactividad.
  • Una clave actúa como tú: ve tus puestos y los de tu equipo, y nada más.
  • Guárdala en tu servidor. Nunca la pongas en una página web ni en una app móvil.

Zapier

Conecta Screenwell con tu ATS, Slack, Google Sheets y más de 7.000 apps, sin escribir código. Cada disparador se activa en el momento en que ocurre en Screenwell.

Configuración

  1. 1Copia tu clave API en la app: Ajustes → API y webhooks.
  2. 2Abre Screenwell en Zapier con el botón de abajo y acepta la invitación.
  3. 3Crea un Zap, elige Screenwell y pega tu clave API cuando Zapier la pida.
  4. 4Elige un disparador o una acción, pruébalo y activa el Zap.
Abrir Screenwell en Zapier

Disparadores

Interview Scored
Luna terminó una entrevista y la evaluación está lista: puntuación, recomendación, resumen y enlace.
Candidate Moved to Stage
Una persona candidata cambió de etapa. Opcionalmente solo para una etapa, como Preseleccionados.
New Candidate
Se añadió una candidatura, en la app, por la API o desde el enlace de la entrevista.
New Job
Se creó un empleo.
Interview Completed
Terminó una entrevista, antes de que la evaluación esté lista.

Acciones y búsquedas

Add Candidate to Job
Nombre, correo, teléfono y un CV opcional.
Send Interview Invite
Envía el enlace de la entrevista por correo. Busca a la persona por correo o la añade.
Schedule Meet/Teams Interview
Reserva a Luna para una entrevista en Google Meet o Microsoft Teams.
Update Candidate Stage
Mueve a Nuevo, Invitado, Entrevistado, Preseleccionado, Contratado o Descartado.
Create Job
Título, descripción, empresa e idioma de la entrevista.
Find Candidate
Por correo, opcionalmente dentro de un empleo.
Find Job
Por título.

Ideas

  • Nueva candidatura en Workable, Recruitee, Teamtailor o Greenhouse → Send Interview Invite
  • Interview Scored → una nota y la siguiente etapa en tu ATS
  • Interview Scored → un mensaje en el canal de selección de Slack
  • Interview Scored → una fila nueva en Google Sheets

Webhooks

Screenwell envía un POST firmado con un cuerpo JSON a tu URL cuando pasa algo. Apúntalo a tu ATS, a un catch hook de Zapier o a tu propio endpoint.

Configúralo

  1. 1En la aplicación, abre Ajustes → API y webhooks y añade tu URL de webhook. Debe ser una dirección https pública.
  2. 2Copia el secreto de firma que aparece tras el primer guardado. Lo necesitas para comprobar las firmas.
  3. 3Pulsa «Enviar evento de prueba» para recibir un interview.scored de ejemplo con test: true.

También puedes configurar la URL con la API: PUT /api/v1/settings/webhook {"webhookUrl": "https://…"}.

Eventos

interview.scored
Luna terminó una entrevista y el informe está listo: la puntuación sobre 100, su decisión y con cuánta seguridad, su razonamiento y un enlace al informe.
candidate.stage_changed
Un candidato cambió de etapa en el tablero, con el origen, el destino y quién lo movió: luna tras la entrevista, o recruiter cuando lo hizo alguien de tu equipo.

Las cuentas que usaban CV Parsing siguen recibiendo sus eventos anteriores (cv_parsed, candidate_created y otros).

Cómo es una entrega

Cada entrega tiene el mismo sobre: id, eventType, timestamp, userId y data. Los eventos de prueba también llevan test: true.

interview.scored
{
  "id": "evt_01J9ZK4T7Q2M8C6V",
  "eventType": "interview.scored",
  "timestamp": "2026-09-26T09:44:12.000Z",
  "userId": "usr_4f1c",
  "data": {
    "candidate": { "id": "cand_8f2c", "name": "Maya Kowalski", "email": "maya@example.com" },
    "job": { "id": "job_31a0", "title": "Senior Frontend Engineer" },
    "interview": { "id": "int_77b1", "finishedAt": "2026-09-26T09:43:50.000Z", "durationSeconds": 1920 },
    "score": 84,
    "decision": "hire",
    "confidence": 82,
    "summary": "Strong frontend engineer who led a design system migration.",
    "reasoning": "Explains her trade-offs clearly and meets 4 of 5 requirements.",
    "scorecardUrl": "https://<app-host>/interviews/int_77b1",
    "integrity": { "level": "none" }
  }
}
candidate.stage_changed
{
  "id": "evt_01J9ZK4VB1XK0D3R",
  "eventType": "candidate.stage_changed",
  "timestamp": "2026-09-26T09:44:13.000Z",
  "userId": "usr_4f1c",
  "data": {
    "candidate": { "id": "cand_8f2c", "name": "Maya Kowalski", "email": "maya@example.com" },
    "job": { "id": "job_31a0", "title": "Senior Frontend Engineer" },
    "from": "invited",
    "to": "shortlisted",
    "movedBy": "luna",
    "changedBy": "rule",
    "reason": "Moved by rule: score 84 ≥ 75",
    "at": "2026-09-26T09:44:13.000Z"
  }
}

Cabeceras

X-Screenwell-Event
El tipo de evento, p. ej. interview.scored.
X-Screenwell-Event-Id
El id del evento. Se mantiene igual en cada reintento, así que úsalo para saltarte eventos que ya has procesado.
X-Screenwell-Signature
t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">, firmado con tu secreto de firma.

Comprueba la firma

  1. 1Lee el cuerpo de la solicitud en bruto, antes de parsear el JSON.
  2. 2Calcula el HMAC-SHA256 de «<t>.<cuerpo bruto>» con tu secreto de firma, en hexadecimal.
  3. 3Compáralo con v1 en tiempo constante, y rechaza las solicitudes cuyo t tenga más de 5 minutos.
Node.js (Express)
import crypto from 'node:crypto'
import express from 'express'

const app = express()
const SECRET = process.env.SCREENWELL_WEBHOOK_SECRET // whsec_...

// Keep the raw body: the signature is over the exact bytes we sent.
app.post('/webhooks/screenwell', express.raw({ type: 'application/json' }), (req, res) => {
  const header = req.get('X-Screenwell-Signature') ?? ''
  const { t, v1 } = Object.fromEntries(header.split(',').map((part) => part.split('=')))
  const expected = crypto.createHmac('sha256', SECRET).update(`${t}.${req.body}`).digest('hex')

  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 5 * 60
  const valid = v1?.length === expected.length && crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))
  if (!fresh || !valid) return res.status(400).send('bad signature')

  const event = JSON.parse(req.body)
  // Skip events you have already handled: event.id stays the same on retries.
  console.log(event.eventType, event.data)
  res.sendStatus(200)
})

app.listen(3000)
Python (Flask)
import hashlib, hmac, json, os, time
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = os.environ["SCREENWELL_WEBHOOK_SECRET"].encode()  # whsec_...

@app.post("/webhooks/screenwell")
def screenwell():
    header = request.headers.get("X-Screenwell-Signature", "")
    parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p)
    t, v1 = parts.get("t", "0"), parts.get("v1", "")

    body = request.get_data()  # the raw bytes, before any JSON parsing
    expected = hmac.new(SECRET, f"{t}.".encode() + body, hashlib.sha256).hexdigest()

    if abs(time.time() - int(t)) > 300 or not hmac.compare_digest(v1, expected):
        abort(400)

    event = json.loads(body)
    # Skip events you have already handled: event["id"] stays the same on retries.
    print(event["eventType"], event["data"])
    return "", 200

Reintentos

Responde con cualquier estado 2xx en menos de 10 segundos. Si tu endpoint falla o no responde, Screenwell vuelve a intentarlo tras 1 minuto, 5 minutos, 30 minutos y 2 horas. Ajustes → API y webhooks muestra las últimas entregas con su estado y la respuesta de tu endpoint.

  1. 0
  2. +1m
  3. +5m
  4. +30m
  5. +2h

API REST

Una API JSON para los puestos, candidatos y entrevistas de tu cuenta. Envía tu clave en la cabecera X-API-KEY. Las respuestas tienen esta forma: {"status": "success", "data": …}.

URL base
https://api.screenwell.ai/api/v1
Autenticación
X-API-KEY: <API key>

Puestos

  • GET/jobsTus puestos y los de tu equipo.
  • GET/jobs/:idUn puesto con su descripción y habilidades.
  • POST/jobsCrea un puesto: título, empresa, ubicación, descripción y más.
  • PUT/jobs/:idCambia los datos de un puesto.

Candidatos

  • POST/jobs/:id/candidatesAñade un candidato a un puesto a partir de su CV: subiendo un archivo (file), con un enlace (fileUrl) o en base64.
  • POST/jobs/:id/candidates/batchAñade varios CV a un puesto a la vez (fileUrls o base64Files).
  • GET/candidates/:idUn candidato con los datos de su CV, su estado y el análisis de Luna.
  • PUT/candidates/:id/statusMueve a un candidato, p. ej. a selected (Preseleccionado), hired o rejected.
  • GET/candidates/:id/cvUn enlace al archivo de CV del candidato.

Entrevistas e informes

  • GET/meetingsEntrevistas y llamadas, las más recientes primero. Filtra con isInterview=true, limit y offset.
  • GET/meetings/:id/interview-insightsEl informe de una entrevista: puntuación, recomendación, puntos fuertes, dudas y evidencias.
  • GET/meetings/:id/transcriptLa transcripción de la entrevista.

Cuenta

  • GET/quotaCuántas entrevistas te quedan este mes.
  • GET · PUT/settings/webhookConsulta o configura tu URL de webhook.

Estados del candidato

Las etapas del tablero se corresponden con estos estados: Nuevo = applied, Invitado = interview_scheduled, Entrevistado = interviewed, Preseleccionado = selected, Contratado = hired, No encaja = rejected. Cambiar un estado nunca envía un correo al candidato.

Ejemplo: añadir un candidato a partir de un CV

curl
curl -X POST https://api.screenwell.ai/api/v1/jobs/job_31a0/candidates \
  -H "X-API-KEY: $SCREENWELL_API_KEY" \
  -F "file=@maya-kowalski-cv.pdf"

# or from a link
curl -X POST https://api.screenwell.ai/api/v1/jobs/job_31a0/candidates \
  -H "X-API-KEY: $SCREENWELL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fileUrl": "https://example.com/cv/maya.pdf"}'
curl
curl -X PUT https://api.screenwell.ai/api/v1/candidates/cand_8f2c/status \
  -H "X-API-KEY: $SCREENWELL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "selected"}'

Servidor MCP

Trabaja con Screenwell desde Claude, ChatGPT, Cursor o cualquier cliente MCP: «¿A quién preseleccionó Luna esta semana?», «Añade estos 5 CV al puesto de Backend», «Envíale a Tomás el enlace de entrevista». El asistente actúa como tú, con el mismo acceso que tienes en la aplicación.

Endpoint
POST https://api.screenwell.ai/mcp
Authorization
Bearer <token de inicio de sesión o clave de API>

Desde claude.ai o ChatGPT: inicia sesión con Screenwell

No hay clave que copiar. Añade Screenwell como conector con la URL del servidor, luego inicia sesión con tu cuenta de Screenwell y aprueba el acceso.

claude.ai (web, escritorio y móvil)

  1. 1Abre Settings → Connectors → Add custom connector. En los planes Team y Enterprise, un propietario tiene que añadirlo primero en Organization settings.
  2. 2Ponle el nombre Screenwell e introduce la URL del servidor. Deja vacíos el ID de cliente y el secreto de OAuth.
  3. 3Haz clic en Connect. Screenwell se abre: inicia sesión, revisa el acceso y haz clic en Allow. Luego activa Screenwell desde el menú de herramientas en un chat.

ChatGPT

  1. 1Abre Settings → Apps & Connectors → Advanced settings y activa Developer mode. Los espacios de trabajo Business, Enterprise y Edu necesitan que un administrador lo permita.
  2. 2Elige Create, ponle el nombre Screenwell, introduce la URL del servidor y selecciona OAuth como autenticación.
  3. 3Screenwell se abre: inicia sesión, revisa el acceso y haz clic en Allow. Luego elige el conector en un chat.
Endpointhttps://api.screenwell.ai/mcp

La página de Screenwell muestra qué app lo solicita, la dirección a la que volverás después, y el acceso que pide: solo lectura, o lectura y acción (añadir, mover y enviar correos a candidatos, siempre con tu confirmación antes).

Cada app conectada aparece en Ajustes → API y webhooks → Apps conectadas. Desconectar le corta el acceso en su siguiente solicitud.

Con una clave de API: Claude Code, Cursor y scripts

Las herramientas que te permiten configurar una cabecera pueden usar tu clave de API en su lugar. Claude Code también puede iniciar sesión: añade el servidor sin cabecera, luego ejecuta /mcp y elige Authenticate.

Claude Code
# sign in with Screenwell: add the server, then run /mcp and choose Authenticate
claude mcp add --transport http screenwell https://api.screenwell.ai/mcp

# or with an API key
claude mcp add --transport http screenwell https://api.screenwell.ai/mcp \
  --header "Authorization: Bearer <API key>"

# read-only
claude mcp add --transport http screenwell-read https://api.screenwell.ai/mcp \
  --header "Authorization: Bearer <API key>" \
  --header "X-Screenwell-Scope: read"
Claude Desktop · claude_desktop_config.json
{
  "mcpServers": {
    "screenwell": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.screenwell.ai/mcp", "--header", "Authorization: Bearer ${SCREENWELL_KEY}"],
      "env": { "SCREENWELL_KEY": "<API key>" }
    }
  }
}

Claude Desktop se conecta a través de mcp-remote, que añade la cabecera de la clave por ti.

Cursor, VS Code, el MCP Inspector y los scripts funcionan con la misma URL, usando una cabecera de clave de API o iniciando sesión.

Con una clave de API, añade la cabecera X-Screenwell-Scope: read para una conexión de solo lectura. El asistente podrá consultar información, pero no añadir, mover ni escribirle a nadie.

Herramientas

Consultar información

  • list_jobsTus puestos con los candidatos por etapa y si el enlace de entrevista está activado.
  • get_jobUn puesto con el plan de entrevista de Luna, el enlace de entrevista y el pipeline.
  • list_candidatesCandidatos por puesto, etapa o nombre, con su última puntuación y quién los movió por última vez.
  • get_candidateUn candidato: sus datos de contacto, el briefing de Luna, el resumen del CV, el informe y la respuesta del responsable de contratación.
  • get_scorecardEl informe completo: puntuación sobre 100, decisión, puntos fuertes, carencias y momentos clave.
  • ask_lunaHazle a Luna, tu asesora de contratación, una pregunta sobre tus candidatos.

Actuar

  • add_candidateAñade un candidato a partir de sus datos o de un CV (PDF o Word). Luna lee el CV primero.
  • move_candidateNecesita tu confirmaciónMueve a un candidato a otra etapa.
  • add_noteAñade una nota para tu equipo a un candidato.
  • send_interview_linkNecesita tu confirmaciónEnvía por correo el enlace de entrevista del puesto a hasta 50 candidatos.

Nada llega a un candidato sin tu confirmación

  • Enviar el enlace de entrevista, y mover a alguien a Contratado o No encaja, primero muestra una vista previa («Esto enviará un correo a 3 candidatos: …»). No pasa nada hasta que el asistente te lo pregunte y tú lo confirmes.
  • El asistente solo ve lo que tú ves en la aplicación: tus puestos y los de tu equipo. Funciona en cualquier plan y durante la prueba, igual que la API.
  • Hasta 60 llamadas a herramientas por minuto y por clave. Leer CVs y Preguntar a Luna tienen sus propios límites por hora.

¿Construyendo algo más grande?

Cuéntanos qué te gustaría conectar. Te ayudamos a configurarlo.

Habla con nosotros