Desarrolladores
API de Wislab
Conecta tu academia con tus sistemas: sincroniza personas desde tu RRHH o CRM, lee cursos, progreso, certificados, inscripciones y pagos, y lleva leads a tu CRM.
- URL base
https://wislab.app/api/v1- Versión
v1 · 1.0.0
La API viene en los planes Cohortes y Empresa.
Introducción
La API de Wislab es REST: URLs por recurso, JSON en las peticiones y en las respuestas, y códigos HTTP normales.
Cada petición actúa sobre una sola academia: la de la API key que uses. La academia nunca va en la URL.
El contrato completo está en OpenAPI 3.0. Impórtalo en Postman, Insomnia o tu generador de clientes.
https://wislab.app/api/v1Autenticación
- 1En el panel de tu academia, entra a Ajustes > Integraciones > Claves de API. Solo el dueño de la academia o un admin pueden crearla.
- 2Elige los scopes que necesita tu integración. La key se muestra una sola vez: guárdala en tu gestor de secretos.
- 3Envía la key en el header
Authorization: Bearerde cada petición.
Tu key es un secreto
Úsala solo desde tu servidor. Nunca la pongas en el navegador, en una app móvil ni en un repositorio. Si se filtra, revócala en el mismo panel y crea otra.
curl https://wislab.app/api/v1/academy \
-H "Authorization: Bearer $WISLAB_API_KEY"Scopes
Cada key trae solo los scopes que le diste. Usa una key por integración: así puedes revocar una sin tocar las demás.
| Scope | Qué permite |
|---|---|
users:read | Leer las personas de la academia y su perfil. |
users:sync | Dar de alta, actualizar y desactivar personas desde tu sistema. |
courses:read | Leer el catálogo de cursos. |
progress:read | Leer el avance de cada persona en sus cursos. |
completions:read | Leer quién terminó cada curso y cuándo. |
certificates:read | Leer los certificados emitidos. |
bootcamps:read | Leer los bootcamps: fechas, precios y cupos. |
enrollments:read | Leer quién está inscrito en cada bootcamp. |
payments:read | Leer compras de cursos y talleres, y recibos de pago. |
crm:read | Leer contactos y negocios del CRM. |
crm:write | Crear y actualizar contactos del CRM. |
fields:read | Leer campos personalizados y sus valores. |
fields:write | Escribir valores de campos personalizados. |
GET /academy no necesita scope: cualquier key válida lo lee.
{
"error": "FORBIDDEN",
"message": "API key lacks required scope: users:read."
}Paginación
Los listados reciben page (empieza en 0) y limit (20 por defecto, hasta 100).
La respuesta trae data con los resultados, total, page y pageCount. Sigue pidiendo páginas hasta que page llegue a pageCount - 1.
curl "https://wislab.app/api/v1/courses?page=1&limit=50" \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
"…"
],
"total": 132,
"page": 1,
"pageCount": 3
}Errores
Un error responde con un código HTTP y un JSON con error (un código estable que puedes usar en tu código), message y, a veces, details.
| Código | HTTP | Qué significa |
|---|---|---|
VALIDATION_ERROR | 400 | Un parámetro o el body no es válido. details dice cuál. |
UNKNOWN_FIELD | 400 | Escribiste un campo personalizado que no tiene definición. |
LIMIT_REACHED | 400 | La academia llegó a un límite de su plan. |
UNAUTHORIZED | 401 | Falta la API key, está mal formada o fue revocada. |
FORBIDDEN | 403 | La key no tiene el scope, o el plan no incluye la API. |
NAMESPACE_FORBIDDEN | 403 | Intentaste escribir campos de otro namespace. |
NOT_FOUND | 404 | El recurso no existe en esta academia. |
CONFLICT | 409 | Ya existe un recurso con esa clave. |
CRM_DISABLED | 409 | La academia tiene el CRM apagado. |
RATE_LIMITED | 429 | Pasaste el límite de uso. Espera Retry-After segundos. |
INTERNAL | 500 | Algo falló de nuestro lado. Reintenta en unos segundos. |
{
"error": "VALIDATION_ERROR",
"details": {
"errors": [],
"properties": {
"limit": {
"errors": [
"Too small: expected number to be >=1"
]
}
}
}
}Límites de uso
Cada key puede hacer 120 peticiones por minuto. Si te pasas, recibes 429 RATE_LIMITED con el header Retry-After: espera esos segundos y reintenta.
HTTP/1.1 429 Too Many Requests
Retry-After: 18
{ "error": "RATE_LIMITED", "message": "Rate limit exceeded." }Referencia
Academia
La academia detrás de la key o del token.
/v1/academyObtener la academia
No necesita scope: cualquier API key o token de instalación válido la lee. Nombre, slug, dominio, idiomas, moneda, plan y marca; nunca personas.
Scope:Sin scope
Respuestas
- 200La academia.
- 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/academy \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": {
"id": "clx8k2m0p0001",
"name": "Academia Ejemplo",
"slug": "fundamentos-de-fotografia",
"domain": "string",
"url": "https://academia.example.com",
"defaultLocale": "string",
"supportedLocales": [
"string"
],
"currency": "USD",
"package": "string",
"logoUrl": "https://academia.example.com",
"primaryColor": "string"
}
}Referencia
Usuarios
Las personas de la academia y la sincronización desde tus sistemas.
/v1/usersListar usuarios
Requiere el scope users:read.
Scope:users:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
rolestringopcionalFiltra por rol.
Uno de:
owner,admin,manager,teacher,moderator,studentsearchstringopcionalBusca en nombre, apellido y email.
Respuestas
- 200Una página de usuarios.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/users \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"email": "ana@example.com",
"firstName": "Ana",
"lastName": "García",
"username": "anagarcia",
"role": "owner",
"isBanned": false,
"createdAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}/v1/users/{id}Obtener un usuario
Requiere el scope users:read.
Scope:users:read
Parámetros de ruta
idstringobligatorioEl ID del usuario.
Respuestas
- 200El usuario.
- 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 404No hay un usuario con ese ID en esta academia.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/users/clx8k2m0p0001 \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": {
"id": "clx8k2m0p0001",
"email": "ana@example.com",
"firstName": "Ana",
"lastName": "García",
"username": "anagarcia",
"role": "owner",
"isBanned": false,
"createdAt": "2026-10-27T15:00:00.000Z"
}
}/v1/users/syncSincronizar usuarios
Da de alta, actualiza y desactiva estudiantes desde tu sistema de RRHH o CRM, hasta 500 por petición. Idempotente por email. status: inactive desactiva (se puede revertir). Solo maneja estudiantes: un email del equipo se reporta como omitido. Requiere el scope users:sync.
Scope:users:sync
Body
usersobject[]obligatorioemailstringobligatorioexternalIdstringopcionalEl ID en tu sistema de origen (número de empleado, RFC). Se guarda en los metadatos de la persona.
firstNamestringopcionallastNamestringopcionalrolestringopcionalUno de:
studentstatusstringopcionalinactivedesactiva a la persona (se puede revertir) y conserva su historial.Uno de:
active,inactive
optionsobjectopcionaldryRunbooleanopcionalValida y reporta sin escribir nada.
sendWelcomeEmailbooleanopcional
Respuestas
- 200El resultado de la sincronización.
- 400Body inválido (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl -X POST https://wislab.app/api/v1/users/sync \
-H "Authorization: Bearer $WISLAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"users": [
{
"email": "ana@example.com",
"externalId": "EMP-1042",
"firstName": "Ana",
"lastName": "García",
"role": "student",
"status": "active"
}
],
"options": {
"dryRun": false,
"sendWelcomeEmail": false
}
}'{
"data": {
"processed": 1,
"created": 1,
"updated": 1,
"deactivated": 1,
"skipped": 1,
"dryRun": false,
"errors": [
{
"index": 1,
"email": "ana@example.com",
"reason": "Invalid email."
}
],
"importLogId": "clx8k2m0p0002"
}
}Referencia
Cursos
El catálogo de cursos.
/v1/coursesListar cursos
Requiere el scope courses:read.
Scope:courses:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
isPublishedstringopcionalFiltra por estado de publicación.
Uno de:
true,false
Respuestas
- 200Una página de cursos.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/courses \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"title": "Fundamentos de fotografía",
"slug": "fundamentos-de-fotografia",
"description": null,
"courseType": "course",
"level": "basic",
"monetizationType": "free",
"priceInCents": 4900,
"currency": "USD",
"isPublished": true,
"totalCapsules": 1,
"createdAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}Referencia
Progreso
El progreso de cada estudiante.
/v1/users/{id}/progressObtener el progreso de un usuario
Progreso por curso. Requiere el scope progress:read.
Scope:progress:read
Parámetros de ruta
idstringobligatorioEl ID del usuario.
Respuestas
- 200El progreso del usuario por curso.
- 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 404No hay un usuario con ese ID en esta academia.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/users/clx8k2m0p0001/progress \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": {
"userId": "clx8k2m0p0002",
"lessonsCompletedTotal": 1,
"courses": [
{
"courseId": "clx8k2m0p0002",
"percentageProgress": 60,
"isEnrolled": true,
"updatedAt": "2026-10-27T15:00:00.000Z"
}
]
}
}Referencia
Cursos completados
Cursos completados.
/v1/completionsListar cursos completados
Cursos que un estudiante terminó al 100%. Requiere el scope completions:read.
Scope:completions:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
fromdatetimeopcionalFecha ISO 8601 inclusiva, contra la fecha de completado.
todatetimeopcionalFecha ISO 8601 inclusiva.
Respuestas
- 200Una página de cursos completados.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/completions \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"userId": "clx8k2m0p0002",
"courseId": "clx8k2m0p0002",
"completedAt": "2026-10-27T15:00:00.000Z",
"certificateId": "clx8k2m0p0002"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}Referencia
Certificados
Certificados emitidos.
/v1/certificatesListar certificados
Requiere el scope certificates:read.
Scope:certificates:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
statusstringopcionalFiltra por estado.
Uno de:
active,revokeduserIdstringopcionalFiltra por usuario.
Respuestas
- 200Una página de certificados.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/certificates \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"userId": "clx8k2m0p0002",
"courseId": "clx8k2m0p0002",
"pathId": "clx8k2m0p0002",
"bootcampId": "clx8k2m0p0002",
"programId": "clx8k2m0p0002",
"credentialCode": "WSL-7F3K-2Q9P",
"issuedAt": "2026-10-27T15:00:00.000Z",
"expiresAt": "2026-10-27T15:00:00.000Z",
"status": "active",
"certificateUrl": "https://academia.example.com/certificates/WSL-7F3K-2Q9P",
"recipientName": "Ana García"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}Referencia
Bootcamps
Los bootcamps de la academia.
/v1/bootcampsListar bootcamps
Requiere el scope bootcamps:read.
Scope:bootcamps:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
isListedstringopcionalFiltra por visibilidad en el catálogo.
Uno de:
true,falseisActivestringopcionalFiltra por estado activo.
Uno de:
true,false
Respuestas
- 200Una página de bootcamps.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/bootcamps \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"title": "Fundamentos de fotografía",
"slug": "fundamentos-de-fotografia",
"cohortStartDate": "2026-10-27T15:00:00.000Z",
"cohortEndDate": "2026-10-27T15:00:00.000Z",
"enrollmentDeadline": null,
"isFree": false,
"regularPrice": 1,
"earlyBirdPrice": 1,
"currency": "USD",
"maxStudents": 1,
"isActive": true,
"isEnrollmentOpen": false,
"isListed": true,
"createdAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}Referencia
Inscripciones
Inscripciones a bootcamps.
/v1/enrollmentsListar inscripciones a bootcamps
Requiere el scope enrollments:read.
Scope:enrollments:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
bootcampIdstringopcionalFiltra por bootcamp.
userIdstringopcionalFiltra por usuario.
statusstringopcionalFiltra por estado.
Uno de:
active,expired,completed,refunded,removed
Respuestas
- 200Una página de inscripciones.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/enrollments \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"userId": "clx8k2m0p0002",
"bootcampId": "clx8k2m0p0002",
"status": "active",
"enrollmentDate": "2026-10-27T15:00:00.000Z",
"amount": 490,
"currency": "USD",
"isManualAssignment": false,
"createdAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}Referencia
Pagos
Compras de cursos y talleres, y recibos de pago.
/v1/paymentsListar compras de cursos y talleres
Requiere el scope payments:read.
Scope:payments:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
kindstringopcionalFiltra por lo que se compró.
Uno de:
course,workshopuserIdstringopcionalFiltra por usuario.
statusstringopcionalFiltra por estado.
Respuestas
- 200Una página de compras.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/payments \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"kind": "course",
"itemId": "clx8k2m0p0002",
"userId": "clx8k2m0p0002",
"amount": 490,
"currency": "USD",
"status": "active",
"stripeSessionId": "cs_live_a1B2c3D4",
"refundedAt": "2026-10-27T15:00:00.000Z",
"createdAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}/v1/payments/receiptsListar recibos de pago
Requiere el scope payments:read.
Scope:payments:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
userIdstringopcionalFiltra por usuario.
enrollmentIdstringopcionalFiltra por inscripción.
paymentStatusstringopcionalFiltra por estado de pago.
Respuestas
- 200Una página de recibos.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/payments/receipts \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"userId": "clx8k2m0p0002",
"enrollmentId": "clx8k2m0p0002",
"programEnrollmentId": "clx8k2m0p0002",
"amount": 490,
"currency": "USD",
"paymentStatus": "paid",
"paymentMethod": "card",
"paidAt": "2026-10-27T15:00:00.000Z",
"description": null,
"isRefunded": false,
"isCancelled": false,
"createdAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}Referencia
CRM
Contactos y negocios del CRM.
/v1/crm/contactsListar contactos del CRM
Requiere el scope crm:read.
Scope:crm:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
lifecycleStagestringopcionalFiltra por etapa del embudo.
sourcestringopcionalFiltra por origen.
updatedAfterdatetimeopcionalSolo contactos modificados después de esta fecha ISO 8601.
Respuestas
- 200Una página de contactos.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/crm/contacts \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"email": "ana@example.com",
"phone": "+52 55 0000 0000",
"firstName": "Ana",
"lastName": "García",
"jobTitle": null,
"lifecycleStage": "SUBSCRIBER",
"source": "SIGNUP",
"sourceDetail": "Formulario del taller",
"score": 1,
"companyId": "clx8k2m0p0002",
"tenantUserId": "clx8k2m0p0002",
"lastContactedAt": "2026-10-27T15:00:00.000Z",
"createdAt": "2026-10-27T15:00:00.000Z",
"updatedAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}/v1/crm/contactsCrear o actualizar un contacto del CRM
Pasa por la misma entrada que los formularios de la academia: deduplica por email, la etapa del embudo solo avanza, abre un negocio si la academia los crea solos y emite lead.created cuando el contacto es nuevo. 201 si es nuevo, 200 si ya existía. 409 CRM_DISABLED si la academia tiene el CRM apagado. Requiere el scope crm:write.
Scope:crm:write
Body
emailstringobligatoriofirstNamestring | nullopcionallastNamestring | nullopcionalphonestring | nullopcionalsourcestringopcionalCómo llegó la persona. Se conserva el de la primera vez que se vio el contacto.
Uno de:
SIGNUP,NEWSLETTER,WAITLIST,CONTACT_FORM,DEMO_REQUEST,COURSE_ENROLLMENT,MANUAL,IMPORT,OTHERsourceDetailstring | nullopcionalTexto libre sobre el origen, por ejemplo el nombre del formulario o la campaña.
lifecycleStagestringopcionalUn contacto existente solo avanza en el embudo.
Uno de:
SUBSCRIBER,LEAD,MQL,SQL,OPPORTUNITY,CUSTOMER,EVANGELIST,OTHER
Respuestas
- 200El contacto ya existía y se actualizó.
- 201Contacto creado.
- 400Body inválido (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 409La academia tiene el CRM apagado.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl -X POST https://wislab.app/api/v1/crm/contacts \
-H "Authorization: Bearer $WISLAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "ana@example.com",
"firstName": "Ana",
"lastName": "García",
"phone": "+52 55 0000 0000",
"source": "OTHER",
"sourceDetail": "Formulario del taller",
"lifecycleStage": "LEAD"
}'{
"data": {
"id": "clx8k2m0p0001",
"email": "ana@example.com",
"phone": "+52 55 0000 0000",
"firstName": "Ana",
"lastName": "García",
"jobTitle": null,
"lifecycleStage": "SUBSCRIBER",
"source": "SIGNUP",
"sourceDetail": "Formulario del taller",
"score": 1,
"companyId": "clx8k2m0p0002",
"tenantUserId": "clx8k2m0p0002",
"lastContactedAt": "2026-10-27T15:00:00.000Z",
"createdAt": "2026-10-27T15:00:00.000Z",
"updatedAt": "2026-10-27T15:00:00.000Z"
}
}/v1/crm/dealsListar negocios del CRM
Requiere el scope crm:read.
Scope:crm:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
statusstringopcionalFiltra por estado.
Uno de:
OPEN,WON,LOSTpipelineIdstringopcionalFiltra por embudo.
contactIdstringopcionalFiltra por contacto.
Respuestas
- 200Una página de negocios.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/crm/deals \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"title": "Fundamentos de fotografía",
"pipelineId": "clx8k2m0p0002",
"stageId": "clx8k2m0p0003",
"status": "OPEN",
"valueCents": 4900,
"currency": "USD",
"contactId": "clx8k2m0p0002",
"companyId": "clx8k2m0p0002",
"expectedCloseDate": "2026-10-27T15:00:00.000Z",
"wonAt": "2026-10-27T15:00:00.000Z",
"lostAt": "2026-10-27T15:00:00.000Z",
"createdAt": "2026-10-27T15:00:00.000Z",
"updatedAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}Referencia
Campos personalizados
Campos personalizados de cursos, bootcamps y rutas, y sus valores.
/v1/fieldsListar definiciones de campos personalizados
Incluye los campos de la academia (academy) y los de cada app instalada (app--<handle>). Requiere el scope fields:read.
Scope:fields:read
Parámetros de consulta
pageintegeropcionalNúmero de página, empieza en 0.
limitintegeropcionalTamaño de página, hasta 100.
entitystringopcionalFiltra por entidad.
Uno de:
course,bootcamp,path
Respuestas
- 200Una página de definiciones.
- 400Parámetros de consulta inválidos (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/fields \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": [
{
"id": "clx8k2m0p0001",
"entity": "course",
"namespace": "academy",
"key": "level",
"fieldId": "academy:level",
"type": "text",
"label": {
"en": "Level",
"es": "Nivel"
},
"options": [
{
"value": "string",
"label": "string"
}
],
"order": 1,
"createdAt": "2026-10-27T15:00:00.000Z"
}
],
"total": 1,
"page": 0,
"pageCount": 1
}/v1/fieldsDeclarar un campo de la app
Solo con el token de instalación de una app externa: el campo nace en el namespace app--<handle> de esa app. Una API key de la academia recibe 403; la academia define sus campos en Admin > Campos personalizados. Requiere el scope fields:write.
Scope:fields:write
Body
entitystringobligatorioUno de:
course,bootcamp,pathkeystringobligatoriotypestringobligatorioUno de:
text,number,boolean,select,url,datelabelobjectobligatoriooptionsobject[]opcionalvaluestringobligatoriolabelstringobligatorio
orderintegeropcional
Respuestas
- 201La definición creada.
- 400Body inválido (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 409Ya existe un campo con esa clave para esa entidad.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl -X POST https://wislab.app/api/v1/fields \
-H "Authorization: Bearer $WISLAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity": "course",
"key": "level",
"type": "text",
"label": {
"en": "Level",
"es": "Nivel"
},
"options": [
{
"value": "string",
"label": "string"
}
],
"order": 1
}'{
"data": {
"id": "clx8k2m0p0001",
"entity": "course",
"namespace": "academy",
"key": "level",
"fieldId": "academy:level",
"type": "text",
"label": {
"en": "Level",
"es": "Nivel"
},
"options": [
{
"value": "string",
"label": "string"
}
],
"order": 1,
"createdAt": "2026-10-27T15:00:00.000Z"
}
}/v1/courses/{id}/fieldsValores de los campos personalizados de un curso
Devuelve fields con claves namespace:key. Requiere el scope fields:read.
Scope:fields:read
Parámetros de ruta
idstringobligatorioEl ID.
Respuestas
- 200Los valores.
- 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 404No hay un curso con ese ID en esta academia.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/courses/clx8k2m0p0001/fields \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": {
"id": "clx8k2m0p0001",
"entity": "course",
"fields": {
"academy:level": "intermediate"
}
}
}/v1/courses/{id}/fieldsEscribir los campos personalizados de un curso
Una API key de la academia escribe solo el namespace academy; el token de instalación de una app escribe solo su app--<handle> (si no, 403 NAMESPACE_FORBIDDEN). null borra el valor; un campo sin definición responde 400 UNKNOWN_FIELD. Requiere el scope fields:write.
Scope:fields:write
Parámetros de ruta
idstringobligatorioEl ID.
Body
fieldsobjectobligatorio
Respuestas
- 200Los valores después del cambio.
- 400Body inválido, campo desconocido o valor de otro tipo (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 404No hay un curso con ese ID en esta academia.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl -X PATCH https://wislab.app/api/v1/courses/clx8k2m0p0001/fields \
-H "Authorization: Bearer $WISLAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"academy:level": "intermediate"
}
}'{
"data": {
"id": "clx8k2m0p0001",
"entity": "course",
"fields": {
"academy:level": "intermediate"
}
}
}/v1/bootcamps/{id}/fieldsValores de los campos personalizados de un bootcamp
Devuelve fields con claves namespace:key. Requiere el scope fields:read.
Scope:fields:read
Parámetros de ruta
idstringobligatorioEl ID.
Respuestas
- 200Los valores.
- 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 404No hay un bootcamp con ese ID en esta academia.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/bootcamps/clx8k2m0p0001/fields \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": {
"id": "clx8k2m0p0001",
"entity": "course",
"fields": {
"academy:level": "intermediate"
}
}
}/v1/bootcamps/{id}/fieldsEscribir los campos personalizados de un bootcamp
Una API key de la academia escribe solo el namespace academy; el token de instalación de una app escribe solo su app--<handle> (si no, 403 NAMESPACE_FORBIDDEN). null borra el valor; un campo sin definición responde 400 UNKNOWN_FIELD. Requiere el scope fields:write.
Scope:fields:write
Parámetros de ruta
idstringobligatorioEl ID.
Body
fieldsobjectobligatorio
Respuestas
- 200Los valores después del cambio.
- 400Body inválido, campo desconocido o valor de otro tipo (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 404No hay un bootcamp con ese ID en esta academia.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl -X PATCH https://wislab.app/api/v1/bootcamps/clx8k2m0p0001/fields \
-H "Authorization: Bearer $WISLAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"academy:level": "intermediate"
}
}'{
"data": {
"id": "clx8k2m0p0001",
"entity": "course",
"fields": {
"academy:level": "intermediate"
}
}
}/v1/paths/{id}/fieldsValores de los campos personalizados de una ruta
Devuelve fields con claves namespace:key. Requiere el scope fields:read.
Scope:fields:read
Parámetros de ruta
idstringobligatorioEl ID.
Respuestas
- 200Los valores.
- 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 404No hay una ruta con ese ID en esta academia.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl https://wislab.app/api/v1/paths/clx8k2m0p0001/fields \
-H "Authorization: Bearer $WISLAB_API_KEY"{
"data": {
"id": "clx8k2m0p0001",
"entity": "course",
"fields": {
"academy:level": "intermediate"
}
}
}/v1/paths/{id}/fieldsEscribir los campos personalizados de una ruta
Una API key de la academia escribe solo el namespace academy; el token de instalación de una app escribe solo su app--<handle> (si no, 403 NAMESPACE_FORBIDDEN). null borra el valor; un campo sin definición responde 400 UNKNOWN_FIELD. Requiere el scope fields:write.
Scope:fields:write
Parámetros de ruta
idstringobligatorioEl ID.
Body
fieldsobjectobligatorio
Respuestas
- 200Los valores después del cambio.
- 400Body inválido, campo desconocido o valor de otro tipo (ver
details). - 401API key ausente, mal formada o revocada.
- 403La key no tiene el scope necesario o el plan de la academia no incluye la API.
- 404No hay una ruta con ese ID en esta academia.
- 429Límite de uso excedido. Espera los segundos de
Retry-After.
curl -X PATCH https://wislab.app/api/v1/paths/clx8k2m0p0001/fields \
-H "Authorization: Bearer $WISLAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"academy:level": "intermediate"
}
}'{
"data": {
"id": "clx8k2m0p0001",
"entity": "course",
"fields": {
"academy:level": "intermediate"
}
}
}¿Te falta un endpoint?
Cuéntanos qué quieres integrar y lo vemos contigo.