Logo StartupKit
ES
Integrations

Referencia de la API

Autentícate y consulta la API de Hiring para ofertas de empleo, candidatos y candidaturas.

Por qué es importante

La API de Hiring da a los sistemas externos acceso de lectura a tus datos de contratación: los portales de empleo obtienen las ofertas publicadas, los sistemas HRIS sincronizan los registros de candidatos, los dashboards rastrean las métricas del pipeline. Los scopes de los tokens garantizan que cada integración solo vea lo que necesita.

URL base

Todos los endpoints de la API son accesibles a través de:

https://startupkit.app/api/v1

Reemplaza startupkit.app con tu dominio real de Kit.

Autenticación

Cada solicitud requiere un token de API en el encabezado Authorization:

Authorization: Bearer YOUR_TOKEN

Formato alternativo (ambos funcionan):

Authorization: token YOUR_TOKEN

Crea tokens en Settings > API. Cada token debe tener scopes explícitos para acceder a los endpoints de contratación.

Scope Acceso
job_postings:read Ofertas de empleo y etapas
candidates:read Datos personales del candidato (nombre, email, teléfono), descarga de CV
applications:read Candidaturas, historial de etapas, descarga de CV

Los tokens sin ningún scope no pueden acceder a los endpoints de contratación.

Formato y ciclo de vida del token

  • Formato: Cadena hexadecimal de 32 caracteres (p. ej., a1b2c3d4e5f6...)
  • Rastreo de último uso: Cada solicitud exitosa actualiza last_used_at
  • Expiración: Se puede definir un expires_at opcional al crear el token
  • Alertas de inactividad: Los tokens sin usar durante más de 30 días activan notificaciones de administrador
  • Revocación automática: Los tokens se revocan automáticamente cuando un usuario es eliminado de la cuenta

Buena práctica: Crea tokens separados por integración con los scopes mínimos necesarios.

Alcance por cuenta

Cada token de API está vinculado a una cuenta específica. La cuenta se determina automáticamente a partir del token; no se necesita ningún parámetro account_id.

Cuando un miembro del equipo es eliminado de una cuenta, sus tokens para esa cuenta se revocan automáticamente.

Respuestas de error

Estado Significado Causas comunes
400 Solicitud incorrecta Contexto de cuenta ausente (caso límite en autenticación por sesión)
401 No autorizado Token ausente, inválido o expirado
403 Prohibido El token no tiene el scope requerido para este endpoint
404 No encontrado El recurso no existe o no pertenece a tu cuenta
422 Entidad no procesable Errores de validación (principalmente para endpoints fuera de contratación)

Paginación

Los endpoints de lista devuelven resultados paginados:

{
  "data": [...],
  "pagination": {
    "current_page": 1,
    "total_pages": 3,
    "total_count": 42,
    "per_page": 20
  }
}

Pasa ?page=2 para obtener las páginas siguientes.


Ofertas de empleo

Scope requerido: job_postings:read

Listar ofertas de empleo

GET /api/v1/job_postings

Ejemplo:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://startupkit.app/api/v1/job_postings?status=published

Parámetros:

Parámetro Tipo Descripción
status string Filtrar por draft, published o closed
page integer Número de página

Respuesta:

{
  "data": [
    {
      "id": "job_abc123",
      "title": "Senior Rails Developer",
      "status": "published",
      "department": "Engineering",
      "location": "New York, NY",
      "employment_type": "full_time",
      "remote": true,
      "salary_min": "120000.0",
      "salary_max": "180000.0",
      "salary_currency": "USD",
      "salary_period": "year",
      "published_at": "2026-01-15T10:00:00Z",
      "closed_at": null,
      "created_at": "2026-01-10T08:30:00Z",
      "updated_at": "2026-02-01T14:20:00Z",
      "stages": [
        {
          "id": "stg_def456",
          "name": "Screening",
          "stage_type": "default",
          "position": 0
        }
      ],
      "counts": {
        "total_applications": 24,
        "active_applications": 18,
        "rejected": 6
      }
    }
  ],
  "pagination": { ... }
}

Obtener una oferta de empleo

GET /api/v1/job_postings/:id

Devuelve la misma estructura que un elemento de la respuesta de lista.

Listar etapas

GET /api/v1/job_postings/:job_posting_id/stages

Respuesta:

{
  "data": [
    {
      "id": "stg_def456",
      "name": "Screening",
      "stage_type": "default",
      "position": 0
    }
  ]
}

Las etapas están ordenadas por posición. Sin paginación.


Candidatos

Scope requerido: candidates:read

Listar candidatos

GET /api/v1/candidates

Ejemplo:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://startupkit.app/api/v1/[email protected]

Parámetros:

Parámetro Tipo Descripción
search string Buscar por nombre o email
page integer Número de página

Respuesta:

{
  "data": [
    {
      "id": "cand_ghi789",
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "phone": "+1-555-0100",
      "status": "active",
      "github_username": "johndoe",
      "created_at": "2026-01-20T09:15:00Z",
      "applications": [
        {
          "id": "app_jkl012",
          "job_posting_id": "job_abc123",
          "job_posting_title": "Senior Rails Developer",
          "current_stage_name": "Interview",
          "status": "active",
          "submitted_at": "2026-01-20T09:15:00Z"
        }
      ]
    }
  ],
  "pagination": { ... }
}

Obtener un candidato

GET /api/v1/candidates/:id

Devuelve la misma estructura que un elemento de la respuesta de lista.


Candidaturas

Scope requerido: applications:read

Listar candidaturas

GET /api/v1/applications

Ejemplo:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://startupkit.app/api/v1/applications?job_posting_id=job_abc123&status=active

Parámetros:

Parámetro Tipo Descripción
job_posting_id string Filtrar por ID con prefijo de la oferta de empleo
status string Filtrar por active o rejected
page integer Número de página

Respuesta:

{
  "data": [
    {
      "id": "app_jkl012",
      "job_posting_id": "job_abc123",
      "candidate_id": "cand_ghi789",
      "current_stage_name": "Interview",
      "status": "active",
      "submitted_at": "2026-01-20T09:15:00Z",
      "created_at": "2026-01-20T09:15:00Z",
      "updated_at": "2026-02-10T11:30:00Z",
      "candidate": {
        "id": "cand_ghi789",
        "first_name": "John",
        "last_name": "Doe",
        "email": "[email protected]"
      },
      "stage_history": [
        {
          "id": "sp_mno345",
          "stage_name": "Screening",
          "stage_type": "default",
          "status": "completed",
          "started_at": "2026-01-20T09:15:00Z",
          "completed_at": "2026-01-25T16:00:00Z"
        },
        {
          "id": "sp_pqr678",
          "stage_name": "Interview",
          "stage_type": "interview",
          "status": "in_progress",
          "started_at": "2026-01-25T16:00:00Z",
          "completed_at": null
        }
      ]
    }
  ],
  "pagination": { ... }
}

Obtener una candidatura

GET /api/v1/applications/:id

Devuelve la misma estructura que un elemento de la respuesta de lista. Cuando el token tiene el scope candidates:read y la candidatura tiene un CV adjunto, la respuesta incluye metadatos del CV:

{
  "id": "app_jkl012",
  "resume_filename": "john_doe_resume.pdf",
  "resume_content_type": "application/pdf",
  "resume_byte_size": 245760,
  ...
}

Estos campos se omiten cuando no hay CV adjunto o cuando falta el scope candidates:read.

Descargar CV

Scopes requeridos: applications:read + candidates:read

GET /api/v1/applications/:application_id/resume

Descarga el CV del candidato para la candidatura indicada. Devuelve una redirección 302 a una URL firmada con tiempo limitado (válida durante 30 minutos).

Ejemplo:

curl -L -H "Authorization: Bearer YOUR_TOKEN" \
  -o resume.pdf \
  https://startupkit.app/api/v1/applications/app_jkl012/resume

Respuesta:

  • 302 Found – Redirección a la URL de descarga firmada. Usa -L (seguir redirecciones) con curl.
  • 403 Forbidden – El token no tiene el scope applications:read o candidates:read.
  • 404 Not Found – Candidatura no encontrada, o sin CV adjunto.

Notas:

  • Las URL firmadas expiran a los 30 minutos. Si expira, solicita una nueva.
  • El encabezado Content-Disposition está configurado como attachment (inicia la descarga en el navegador).
  • Tipos de archivo de CV: PDF, DOC, DOCX (según lo subido por el candidato).

Ocultamiento de datos personales del candidato

Cuando un token tiene applications:read pero no candidates:read, los datos del candidato en las respuestas de candidaturas se ocultan y solo muestran el ID:

{
  "candidate": {
    "id": "cand_ghi789"
  }
}

Los campos first_name, last_name y email no se incluyen. Esto permite que las integraciones de portales de empleo rastreen el estado de las candidaturas sin exponer la información de contacto de los candidatos.


Diagnóstico de problemas

Problemas de autenticación

401 Unauthorized

Si recibes una respuesta 401, verifica:

  1. Formato del token: Asegúrate de que el token sea exactamente el que se muestra en Settings > API (cadena hexadecimal de 32 caracteres)
  2. Encabezado Authorization: Debe ser Authorization: Bearer TOKEN o Authorization: token TOKEN
  3. Expiración del token: Comprueba si expires_at ha pasado en Settings > API
  4. Membresía en la cuenta: Confirma que el propietario del token sigue siendo miembro de la cuenta

403 Forbidden

Cuando recibes un 403, el token es válido pero no tiene el scope requerido:

  1. Verifica los scopes requeridos: Cada endpoint documenta su scope requerido (p. ej., job_postings:read)
  2. Añade los scopes faltantes: Edita el token en Settings > API y añade el scope necesario
  3. Formato del scope: Debe coincidir exactamente: job_postings:read, no job_postings ni read

Problemas de acceso a datos

Array data vacío en las respuestas

Si la API devuelve {"data": [], "pagination": {...}} pero esperas resultados:

  1. Aislamiento por cuenta: Los tokens de API solo ven datos de la cuenta a la que están vinculados
  2. Verifica la cuenta: Comprueba a qué cuenta pertenece el token en Settings > API
  3. Acceso entre cuentas: Los tokens no pueden acceder a datos de otras cuentas, incluso si el usuario es miembro de ellas

Los datos personales del candidato están ocultos

Si solo ves {"candidate": {"id": "cand_..."}} sin nombre ni email:

  1. Comportamiento esperado: Esto ocurre cuando el token tiene applications:read pero no candidates:read
  2. Añade el scope: Para ver los detalles completos del candidato, añade el scope candidates:read a tu token
  3. Privacidad por diseño: Esto permite que las integraciones rastreen candidaturas sin exponer información de contacto

Problemas de consultas y filtros

404 al buscar recursos específicos

  1. Usa IDs con prefijo: Las ofertas de empleo usan el formato job_abc123, no IDs de base de datos como 42
  2. Sensibilidad a mayúsculas: Los IDs con prefijo distinguen entre mayúsculas y minúsculas
  3. Alcance de la cuenta: El recurso debe pertenecer a la cuenta del token

Los parámetros de filtro no funcionan

  1. Valores de estado válidos:
    • Ofertas de empleo: draft, published, closed (distingue mayúsculas)
    • Candidaturas: active, rejected (distingue mayúsculas)
  2. Formato de parámetros: Usa ?status=published, no ?status=Published ni ?filter[status]=published

Preguntas frecuentes

¿Cómo funciona la paginación?

Todos los endpoints de lista devuelven 20 elementos por página (fijo). Usa ?page=2 para la siguiente página. El objeto pagination muestra total_pages y total_count.

¿Los tokens expiran automáticamente?

Solo si defines expires_at al crear el token. De lo contrario, los tokens permanecen válidos hasta que:

  • Se revoquen manualmente en Settings > API
  • El usuario sea eliminado de la cuenta
  • La cuenta sea eliminada

¿Debo usar un solo token para múltiples integraciones?

No. La buena práctica es un token por integración con los scopes mínimos. Esto facilita:

  • Auditar qué integración está haciendo solicitudes (a través de last_used_at)
  • Revocar el acceso a una integración específica sin afectar a las demás
  • Otorgar permisos diferentes a distintos sistemas

¿Cuál es la relación entre los webhooks y la API?

Los webhooks te notifican de eventos (nueva candidatura, cambio de etapa). La API te permite consultar el estado actual. Usa los webhooks para activar tu sistema y luego usa la API para obtener los detalles completos.

¿Puedo obtener más de 20 elementos por página?

No. El tamaño de página está fijado en 20 elementos para garantizar un rendimiento consistente. Usa el parámetro page para iterar sobre todos los resultados.

Lista de verificación rápida

  • Crea un token de API en Settings > API – cada token está vinculado a esa cuenta
  • Asigna solo los scopes que tu integración necesita (buena práctica: un token por integración con los scopes mínimos)
  • Comprueba expires_at en Settings > API para ver cuándo expira el token (si se definió)
  • Incluye Authorization: Bearer TOKEN en cada solicitud
  • Usa IDs con prefijo (p. ej., job_abc123) en las URLs, no IDs de base de datos
  • Maneja las respuestas 400 y 422 para errores de validación
  • Maneja las respuestas 401 – tu token puede haber expirado o sido revocado
  • Maneja las respuestas 403 – a tu token puede faltarle un scope requerido
  • Usa el parámetro page para paginar grandes conjuntos de resultados (20 elementos por página)

Escriba para buscar...