Auto Scheduler
PreciosZona de pruebaFlujoBlogPreguntas FrecuentesDocumentación API
Iniciar sesión

Auto Scheduler

Servicio en la nube para optimizar turnos y planificar cuadrantes con reglas y restricciones operativas.

Términos de servicio|Política de privacidad|Divulgaciones legales

Solver (operador)

En esta página

Descripción generalAlcanceSuscripción y facturaciónAutenticaciónCopiar para LLMEndpointUso (inicio rápido)MCP (agentes)API de lectura (GET)API de escritura (PATCH / POST / PUT / DELETE)Webhooks de finalizaciónCabecerasLímites y valores por defectoClaves raíz permitidasCuerpo de la solicitud (resumen)Tabla de referencia rápidaReferencia de campos (valores permitidos)apiVersiontimeZonescheduleStartDate / scheduleEndDatetimeRangeStart / timeRangeEndslotGranularityMinutesrequirementsByCellrequiredRolesByCellstaffavailableCellsstaff[].schedulingRoleIds / Soft prefer-avoidLegislación laboral y flags de pago (valores del servidor)SanitizaciónRespuesta correctaCódigos de error (lista completa)Ejemplo JSONMás información

Auto Scheduler

API de pago · Suscripción

Referencia de API para desarrolladores

Integre la API de producción para enviar cuadrantes con una clave API vinculada a su suscripción de pago. Los valores predeterminados del inquilino se guardan con PATCH /v1/schedule-defaults; los deseos semanales por empleado se leen o sustituyen con GET/PUT /v1/staff/{staffId}/weekly-shift-wish. La facturación sigue su plan y contrato (no por llamada API medida). Esta página documenta límites, validaciones y códigos de error — use la barra lateral para ir a cada campo.

Alcance de esta documentación

Esta página documenta la API REST de producto para integraciones externas.

Los webhooks de finalizacion de resultados son notificaciones HTTPS salientes configuradas en la gestion de API (no CRUD REST). Consulte Completion webhooks en esta pagina.

Las rutas internas del navegador (p. ej. callbacks de pago o analitica) no sustituyen esta API de producto. Para sistemas externos, use /v1/* y los webhooks de finalizacion.

Suscripción y acceso

Esta API HTTP forma parte del producto de pago: el acceso requiere un acuerdo comercial activo y las claves se emiten a su organización tras el onboarding.

La facturación se basa en la suscripción y el contrato. En planes de pago, los cargos suelen seguir la página de precios (p. ej. por miembro de plantilla y mes).

Los límites del playground o del nivel gratuito no aplican a las claves de API de pago. Los límites efectivos (días, personal, granularidad de 15 minutos) los fijan sus derechos de pago. Consulte Límites y valores por defecto en esta página.

Autenticación

Las solicitudes deben incluir una clave API válida emitida con su suscripción de pago. Cree, rote y revoque claves desde el área de cuenta tras iniciar sesión.

Envíe la clave en la cabecera x-api-key. Las claves están ligadas a su organización para la resolución del inquilino y los límites de acceso del plan contratado. Las operaciones fuera de los scopes devuelven 403 (API_KEY_SCOPE_DENIED). Las claves sin atributo scopes siguen permitiendo todas las operaciones.

Gestionar claves: Gestión de API

Copiar para LLM

Pegue el bloque siguiente en un asistente de chat cuando quiera ayuda para llamar a esta API del producto sin configurar MCP.

Resume URL base, autenticación, operaciones principales y precauciones de escritura. Nunca incluye una clave API real.

Para llamadas API reales desde un agente, configure MCP (agentes) en lugar de confiar solo en este texto.

Contexto para pegar

Auto Scheduler — Public API context for LLM assistants

Use this when helping a developer call the Auto Scheduler paid product REST API (/v1/*). Prefer configuring Tools MCP when available; this paste is for chat without MCP.

Base URL
- https://api.autoschedulers.com
- Paths are under /v1/*. Do not confuse this with the marketing website origin.

Authentication
- Every request needs header: x-api-key: <API_KEY>
- Never paste a real API key into chat logs or this prompt; ask the user to supply it via environment or a secret store.
- Keys are created in the product under Account → API management.
- JSON writes: Content-Type: application/json

Read endpoints
- GET /v1/schedule-results?limit=10
- GET /v1/schedule-results/{conditionId}
- GET /v1/schedule-conditions
- GET /v1/staff
- GET /v1/staff/{staffId}
- GET /v1/schedule-defaults
- GET /v1/schedule-results/{conditionId}/emergency-shift-context

Write endpoints (confirm with the user before calling)
- POST /v1/schedule — starts a job; may incur charges; max 14 calendar days
- PATCH /v1/schedule-defaults — tenant-wide
- POST /v1/staff
- PATCH /v1/staff/{staffId}
- PUT /v1/staff/{staffId}/weekly-shift-wish — full replace
- POST /v1/schedule-results/{conditionId}/emergency-shift — paid
- POST /v1/schedule-results/{conditionId}/confirm-assignments
- DELETE /v1/schedule-conditions/{conditionId}
- PUT /v1/schedule-actual/{conditionId} — full replace

Minimal curl (read)
curl -sS -H "x-api-key: YOUR_API_KEY" "https://api.autoschedulers.com/v1/staff"
curl -sS -H "x-api-key: YOUR_API_KEY" "https://api.autoschedulers.com/v1/schedule-results?limit=10"

Contract notes
- Schedule submit body needs a supported apiVersion and valid JSON fields — see api-docs Field reference or Docs MCP Resources; do not invent fields.
- planningHorizon on defaults is only week or two_weeks (month_attendance is rejected).
- Outbound completion webhooks are HMAC-signed HTTPS callbacks configured in API management (not REST CRUD).

Safety
- Write endpoints change tenant data. Confirm destructive or irreversible actions with the user before calling them.
- Prefer read/list first when exploring an unfamiliar tenant.

Endpoint

Envíe una condición de cuadrante como JSON. Es la superficie de integración de pago; la URL base exacta se proporciona por entorno tras aprovisionar el acceso a la API.

URL base

Host de la API REST pública (/v1/*), no la URL del sitio del navegador. Establezca AUTO_SCHEDULER_PUBLIC_API_BASE_URL (MCP) y BASE_URL (curl) en este valor.

AUTO_SCHEDULER_PUBLIC_API_BASE_URL — URL base configurada para este entorno de documentación. Use el mismo valor en MCP y curl.

AUTO_SCHEDULER_PUBLIC_API_BASE_URL=https://api.autoschedulers.com
https://api.autoschedulers.com
POST https://api.autoschedulers.com/v1/schedule

Use la URL base proporcionada cuando se aprovisionó el acceso a la API o por su contacto de operaciones.

Uso (inicio rápido)

Sustituya BASE_URL por la URL base de la API (prefijo de ruta) proporcionada cuando se aprovisionó su acceso.

Envíe su clave API en la cabecera **x-api-key**. Su organización (inquilino) se identifica a partir de la clave; no pasa un id de inquilino aparte en la cadena de consulta.

Las funciones de pago (detalles laborales, algunos valores predeterminados) requieren una suscripción de pago activa. Si la facturación no está configurada, puede recibir **503** (p. ej. código **STRIPE_NOT_CONFIGURED**). El perfil de empresa, los registros de auditoría y la gestión de usuarios (cuentas) se realizan en la aplicación web y no forman parte de la API pública.

Ejemplo con curl (bash / macOS / Linux / WSL)

Windows PowerShell: una barra invertida final `\` **no** continúa la línea. Escriba en una sola línea, o termine cada línea con acento grave (`) para continuar.

curl -sS -D - \
  -H "x-api-key: YOUR_API_KEY" \
  "https://api.autoschedulers.com/v1/schedule-results?limit=10"

curl -sS -D - \
  -H "x-api-key: YOUR_API_KEY" \
  "https://api.autoschedulers.com/v1/staff"

MCP (agentes)

Puede llamar a la misma API REST del producto desde agentes como Cursor, Claude, Gemini y GPT mediante MCP. Las operaciones coinciden con la superficie /v1 de esta página.

Los servidores MCP incluidos usan stdio local. Añada command / args / env a cada archivo de configuración del cliente. Cree claves en Gestión de API (nunca las confirme ni las pegue en chats públicos).

Solo para documentación, un MCP de Resources no requiere inicio de sesión ni clave API (mcp/api-docs). Esta página (/{locale}/api-docs) también se puede ver sin iniciar sesión; crear claves sigue requiriendo Cuenta → Gestión de API.

Camino más rápido (recomendado)

  1. Create an API key in Account → API management (never paste the real key into chat).
  2. In the repo: cd mcp/public-api && npm install && npm run build (also mcp/api-docs if you want documentation Resources).
  3. Copy the env snippet below and the Cursor mcp.json under Client-specific setup; replace paths and YOUR_* placeholders.
  4. Restart the client and confirm Tools (list_staff, …) appear. Prefer read tools before any write.

Qué opción usar

  • Tools MCP (public-api)

    Live /v1 calls with your API key. Use this when the agent should actually list staff, submit schedules, etc.

  • Docs MCP (api-docs Resources)

    Contract markdown only—no API key. Use when the agent needs field rules or request-body shape.

  • Copy for LLM (this page)

    Orientation text for chat assistants without MCP. Not enough alone for correct request bodies—pair with MCP or the sections below.

Variables de entorno requeridas (Tools MCP)

  • AUTO_SCHEDULER_PUBLIC_API_BASE_URL

    URL base de la API REST pública (/v1/*)—no el dominio del sitio. Use el host de API que le dieron (barra final opcional)

  • AUTO_SCHEDULER_API_KEY

    Clave de Gestión de API (no confirmar ni publicar)

VariableDescripción
AUTO_SCHEDULER_PUBLIC_API_BASE_URLURL base de la API REST pública (/v1/*)—no el dominio del sitio. Use el host de API que le dieron (barra final opcional)
AUTO_SCHEDULER_API_KEYClave de Gestión de API (no confirmar ni publicar)

Fragmento de variables de entorno (copiar)

AUTO_SCHEDULER_PUBLIC_API_BASE_URL=https://api.autoschedulers.com
AUTO_SCHEDULER_API_KEY=YOUR_API_KEY

Preparación compartida

  1. Crear una clave API en Gestión de API (solo Tools MCP; no hace falta para el MCP de docs)
  2. En el repositorio: cd mcp/public-api → npm install && npm run build (y mcp/api-docs si quiere Resources)
  3. Siga los pasos por cliente abajo y ajuste rutas y env a su máquina
  4. Reinicie el cliente (o vuelva a conectar MCP) y confirme que aparecen tools / resources

Configuración por cliente

La forma JSON es casi la misma en todas partes. Lo que cambia es la ubicación del archivo de configuración—y que ChatGPT (GPT) no inicia servidores stdio locales.

Cursor

mcp.json de usuario (p. ej. Windows %USERPROFILE%\.cursor\mcp.json). También puede editar vía Cursor Settings → MCP.

  1. Añada el fragmento de abajo en mcpServers (conserve los servidores existentes)
  2. Reemplace rutas absolutas y YOUR_BASE_URL / YOUR_API_KEY
  3. Reinicie Cursor y confirme Tools como list_staff y Resources de api-docs

En Windows escape las barras invertidas como \\ en JSON. En macOS / Linux use rutas con barra diagonal.

{
  "mcpServers": {
    "auto-scheduler-public-api": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\public-api\\dist\\index.js"
      ],
      "env": {
        "AUTO_SCHEDULER_PUBLIC_API_BASE_URL": "https://api.autoschedulers.com",
        "AUTO_SCHEDULER_API_KEY": "YOUR_API_KEY"
      }
    },
    "auto-scheduler-api-docs": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\api-docs\\dist\\index.js"
      ]
    }
  }
}

public-api expone Tools (se requiere clave API). api-docs expone Resources (sin clave).

Claude (Desktop)

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json / Windows: %APPDATA%\Claude\claude_desktop_config.json (Settings → Developer → Edit Config)

  1. Añada el fragmento de abajo en mcpServers de claude_desktop_config.json
  2. Ajuste rutas absolutas y env a su máquina
  3. Cierre por completo y reinicie Claude Desktop, luego revise Connectors / herramientas

Mismo formato mcpServers que Cursor. Siga el flujo de Anthropic «Connect to local MCP servers».

{
  "mcpServers": {
    "auto-scheduler-public-api": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\public-api\\dist\\index.js"
      ],
      "env": {
        "AUTO_SCHEDULER_PUBLIC_API_BASE_URL": "https://api.autoschedulers.com",
        "AUTO_SCHEDULER_API_KEY": "YOUR_API_KEY"
      }
    },
    "auto-scheduler-api-docs": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\api-docs\\dist\\index.js"
      ]
    }
  }
}

Con Claude Code también puede registrar vía .mcp.json del proyecto o claude mcp add.

Gemini (CLI)

Usuario: ~/.gemini/settings.json / Proyecto: .gemini/settings.json (el proyecto gana si existen ambos)

  1. Añada el fragmento en mcpServers (o use gemini mcp add)
  2. Prefiera nombres de servidor con guiones (restricción de Gemini CLI)
  3. Inicie la CLI y verifique con /mcp (conexión + herramientas)

command / args / env coinciden con Cursor y Claude. Campos opcionales: timeout, trust: false.

{
  "mcpServers": {
    "auto-scheduler-public-api": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\public-api\\dist\\index.js"
      ],
      "env": {
        "AUTO_SCHEDULER_PUBLIC_API_BASE_URL": "https://api.autoschedulers.com",
        "AUTO_SCHEDULER_API_KEY": "YOUR_API_KEY"
      }
    },
    "auto-scheduler-api-docs": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\api-docs\\dist\\index.js"
      ]
    }
  }
}

Los conectores de la consola cloud de Gemini apuntan a MCP remoto. Use Gemini CLI para stdio local.

GPT (ChatGPT / OpenAI)

Ajustes del conector de ChatGPT (solo MCP remoto). No hay mcp.json local para ChatGPT.

  1. ChatGPT (conectores web / escritorio) no puede iniciar procesos MCP stdio locales
  2. Este producto solo incluye MCP stdio local, por lo que ChatGPT no puede conectarse directamente
  3. Para agentes tipo GPT: (1) ejecute el mismo MCP en Cursor / Claude / Gemini CLI, o (2) llame a la API REST de esta página con x-api-key desde Custom Actions / su cliente API

Solo puede registrar un conector de ChatGPT si aloja usted mismo un MCP HTTPS remoto (no es una oferta estándar del producto).

OpenAI Agents / Responses API también esperan MCP remoto (HTTP). Los servidores incluidos son para clientes stdio.

Resumen de herramientas (public-api)

Hay herramientas de lectura y escritura. Las escrituras pueden iniciar trabajos facturados o cambiar ajustes de la organización—confirme antes de llamar.

Lectura

  • list_schedule_results / get_schedule_result (resultados)
  • list_schedule_conditions (condiciones)
  • list_staff / get_staff (personal)
  • get_schedule_defaults (valores predeterminados)
  • get_emergency_shift_context

Escritura (confirmar primero)

  • submit_schedule (ejecuta un trabajo de turnos; puede generar cargos)
  • update_schedule_defaults (valores predeterminados de la organización)
  • create_staff / update_staff (personal)
  • upsert_weekly_shift_wish (reemplazo completo del deseo semanal)
  • submit_emergency_shift
  • confirm_schedule_assignments
  • cancel_schedule_condition
  • put_schedule_actual

Confirm destructive writes before calling. Docs MCP (api-docs) is Resources-only.

Crear una clave: Gestión de API

Endpoints de lectura (GET)

Misma URL base y clave API que POST /v1/schedule. Cada tarjeta muestra una respuesta JSON mínima como esbozo de contrato.

Las listas aceptan query limit (1–100, predeterminado 50) y cursor (token opaco de nextCursor). Sin página siguiente, nextCursor se omite.

  • GET{baseUrl}/v1/schedule-results

    Lists schedule-result parent summaries (newest index order).

    Query: limit, cursor.

    Ejemplo de respuesta

    {
      "items": [
        {
          "conditionId": "cond-11111111-1111-1111-1111-111111111111",
          "status": "completed",
          "candidateCount": 3,
          "createdAt": "2026-04-07T10:00:00.000Z",
          "updatedAt": "2026-04-07T10:05:00.000Z",
          "entityType": "SCHEDULE_RESULT"
        }
      ],
      "nextCursor": "eyJwayI6Ii4uLiJ9"
    }
  • GET{baseUrl}/v1/schedule-results/history

    History search over recent + archive data (same shape as the browser history view).

    Query: from, to (ISO 8601; default service start→now), keyword, eventName (comma-separated INSERT,MODIFY,REMOVE), limit, cursor.

    Ejemplo de respuesta

    {
      "items": [
        {
          "conditionId": "cond-11111111-1111-1111-1111-111111111111",
          "status": "completed",
          "candidateCount": 2,
          "createdAt": "2026-04-01T09:00:00.000Z",
          "updatedAt": "2026-04-01T09:10:00.000Z",
          "entityType": "SCHEDULE_RESULT"
        }
      ],
      "nextCursor": "eyJwayI6Ii4uLiJ9"
    }
  • GET{baseUrl}/v1/schedule-results/{conditionId}

    One schedule-result parent row (PK/SK stripped).

    Ejemplo de respuesta

    {
      "scheduleResult": {
        "conditionId": "cond-11111111-1111-1111-1111-111111111111",
        "status": "completed",
        "candidateCount": 3,
        "entityType": "SCHEDULE_RESULT",
        "createdAt": "2026-04-07T10:00:00.000Z",
        "updatedAt": "2026-04-07T10:05:00.000Z"
      }
    }
  • GET{baseUrl}/v1/schedule-results/{conditionId}/resolution

    Resolved optimization output for the condition.

    If status is completed and not yet confirmed, rank-1 may be auto-confirmed on this GET (side effect). Prefer POST …/confirm-assignments for explicit confirmation.

    Ejemplo de respuesta

    {
      "resolution": {
        "status": "completed",
        "candidates": [
          {
            "rank": 1,
            "assignments": [
              {
                "personId": "550e8400-e29b-41d4-a716-446655440000",
                "personName": "Example Staff",
                "date": "2026-04-07",
                "slotId": "09:00",
                "slotLabel": "09:00"
              }
            ]
          }
        ],
        "confirmedAt": "2026-04-07T10:06:00.000Z",
        "confirmedAssignments": [
          {
            "personId": "550e8400-e29b-41d4-a716-446655440000",
            "personName": "Example Staff",
            "date": "2026-04-07",
            "slotId": "09:00",
            "slotLabel": "09:00"
          }
        ]
      }
    }
  • GET{baseUrl}/v1/schedule-results/{conditionId}/review

    Review payload for manual confirmation UI / clients.

    Ejemplo de respuesta

    {
      "review": {
        "conditionId": "cond-11111111-1111-1111-1111-111111111111",
        "status": "completed",
        "timeZone": "Asia/Tokyo",
        "calendarDates": ["2026-04-07"],
        "slotIds": ["09:00", "10:00"],
        "slotLabels": ["09:00", "10:00"],
        "requiredByCellKey": {
          "2026-04-07__09:00": 2
        },
        "candidates": [
          {
            "rank": 1,
            "assignments": [
              {
                "personId": "550e8400-e29b-41d4-a716-446655440000",
                "personName": "Example Staff",
                "date": "2026-04-07",
                "slotId": "09:00",
                "slotLabel": "09:00"
              }
            ]
          }
        ],
        "staff": [
          {
            "staffId": "550e8400-e29b-41d4-a716-446655440000",
            "displayName": "Example Staff",
            "allowedCellKeys": ["2026-04-07__09:00", "2026-04-07__10:00"]
          }
        ]
      }
    }
  • GET{baseUrl}/v1/schedule-results/{conditionId}/emergency-shift-context

    Context for building an emergency-shift request. Paid subscription required.

    When the condition is missing, emergencyShiftContext is null.

    Ejemplo de respuesta

    {
      "emergencyShiftContext": {
        "sourceConditionId": "cond-11111111-1111-1111-1111-111111111111",
        "timeZone": "Asia/Tokyo",
        "calendarDates": ["2026-04-07", "2026-04-08"],
        "staff": [
          {
            "staffId": "550e8400-e29b-41d4-a716-446655440000",
            "displayName": "Example Staff",
            "schedulingRoleIds": [],
            "availabilityByDateYmd": {}
          }
        ],
        "slots": [
          { "slotId": "09:00", "slotLabel": "09:00" }
        ],
        "dayRequirements": [],
        "roleLabelById": {},
        "rosterCandidates": []
      }
    }
  • GET{baseUrl}/v1/schedule-conditions

    Lists schedule-condition index summaries.

    Query: limit, cursor.

    Ejemplo de respuesta

    {
      "items": [
        {
          "conditionId": "cond-11111111-1111-1111-1111-111111111111",
          "createdAt": "2026-04-07T10:00:00.000Z",
          "scheduleStartDate": "2026-04-07",
          "scheduleEndDate": "2026-04-13"
        }
      ],
      "nextCursor": "eyJwayI6Ii4uLiJ9"
    }
  • GET{baseUrl}/v1/schedule-conditions/{conditionId}

    Condition parent plus reqDays and staffSnapshots (PK/SK stripped).

    Ejemplo de respuesta

    {
      "condition": {
        "conditionId": "cond-11111111-1111-1111-1111-111111111111",
        "entityType": "SCHEDULE_CONDITION",
        "scheduleStartDate": "2026-04-07",
        "scheduleEndDate": "2026-04-13",
        "timeZone": "Asia/Tokyo"
      },
      "reqDays": [
        {
          "entityType": "SCHEDULE_CONDITION_REQ_DAY",
          "date": "2026-04-07"
        }
      ],
      "staffSnapshots": [
        {
          "entityType": "SCHEDULE_CONDITION_STAFF",
          "staffId": "550e8400-e29b-41d4-a716-446655440000",
          "displayName": "Example Staff"
        }
      ]
    }
  • GET{baseUrl}/v1/schedule-defaults

    Tenant schedule defaults, or null when not saved yet (still HTTP 200).

    Ejemplo de respuesta

    {
      "scheduleDefaults": {
        "entityType": "SCHEDULE_DEFAULTS",
        "scheduleStartDate": "2026-04-07",
        "scheduleEndDate": "2026-04-13",
        "timeRangeStart": "09:00",
        "timeRangeEnd": "17:00",
        "slotGranularityMinutes": 60,
        "planningHorizon": "week",
        "requirementsByCellKey": {
          "2026-04-07__09:00": 2
        },
        "paidOptimization": {
          "laborLawCompliance": true,
          "balanceStaffLoad": false,
          "honorShiftWishes": true
        }
      }
    }
  • GET{baseUrl}/v1/schedule-actual/{conditionId}

    Saved actual assignments for the condition, or null if none.

    Ejemplo de respuesta

    {
      "actual": {
        "entityType": "SCHEDULE_ACTUAL",
        "conditionId": "cond-11111111-1111-1111-1111-111111111111",
        "assignments": [
          {
            "personId": "550e8400-e29b-41d4-a716-446655440000",
            "personName": "Example Staff",
            "date": "2026-04-07",
            "slotId": "09:00",
            "slotLabel": "09:00"
          }
        ]
      }
    }
  • GET{baseUrl}/v1/staff/{staffId}/weekly-shift-wish

    Weekly wish row for one staff member, or null if none. Soft-deleted staff → 404.

    Ejemplo de respuesta

    {
      "weeklyShiftWish": {
        "entityType": "WEEKLY_SHIFT_WISH",
        "staffId": "550e8400-e29b-41d4-a716-446655440000",
        "scheduleStartDate": "2026-04-07",
        "scheduleEndDate": "2026-04-13",
        "timeRangeStart": "09:00",
        "timeRangeEnd": "11:00",
        "wishByCellKey": {
          "2026-04-07__09:00": "HIGH",
          "2026-04-07__10:00": "NONE"
        }
      }
    }
  • GET{baseUrl}/v1/staff

    Active staff members for the tenant (sorted by displayName).

    Ejemplo de respuesta

    {
      "staff": [
        {
          "staffId": "550e8400-e29b-41d4-a716-446655440000",
          "displayName": "Example Staff",
          "createdAt": "2026-03-01T00:00:00.000Z",
          "updatedAt": "2026-04-01T00:00:00.000Z",
          "laborLawCompliance": true,
          "schedulingRoleIds": [
            "550e8400-e29b-41d4-a716-446655440099"
          ]
        }
      ]
    }
  • GET{baseUrl}/v1/staff/{staffId}

    One staff member including labor / Soft fields when present. Soft-deleted → 404.

    Ejemplo de respuesta

    {
      "staff": {
        "staffId": "550e8400-e29b-41d4-a716-446655440000",
        "displayName": "Example Staff",
        "createdAt": "2026-03-01T00:00:00.000Z",
        "updatedAt": "2026-04-01T00:00:00.000Z",
        "laborLawCompliance": true,
        "laborFlsaExempt": false,
        "personalMaxWeeklyMinutes": 2400,
        "laborConstraintMask": {
          "schema": "v1"
        },
        "schedulingRoleIds": [
          "550e8400-e29b-41d4-a716-446655440099"
        ],
        "preferredSchedulingRoleIds": [],
        "avoidedSchedulingRoleIds": []
      }
    }

Endpoints de escritura (PATCH / POST / PUT / DELETE)

Misma clave API y cuerpos JSON que otras rutas /v1. Cada tarjeta muestra un cuerpo de solicitud mínimo que puede copiar. Usuarios de cuenta, perfil de empresa y auditoría permanecen en la app web — no en esta API. POST /v1/staff devuelve 409 STAFF_LIMIT si la plantilla supera el tope del inquilino.

Los campos laborales y Soft prefer/avoid requieren suscripción de pago. Sustituya UUID, fechas y claves de celda de ejemplo por datos de su inquilino.

  • PATCH{baseUrl}/v1/schedule-defaults

    Saves tenant-wide schedule defaults. Paid-tier fields follow your subscription.

    requirementsByCellKey must include every cell in period × slots (missing/extra keys → 400). Cell key = YYYY-MM-DD__HH:mm. planningHorizon: week | two_weeks (month_attendance rejected). Optional: requiredRolesByCellKey, laborLawJurisdiction, usLaborStateCode, linkedMonthPlanStartDate / linkedMonthPlanEndDate, laborModelVersion.

    Ejemplo de cuerpo de solicitud

    {
      "scheduleStartDate": "2026-04-07",
      "scheduleEndDate": "2026-04-07",
      "timeRangeStart": "09:00",
      "timeRangeEnd": "11:00",
      "slotGranularityMinutes": 60,
      "planningHorizon": "week",
      "requirementsByCellKey": {
        "2026-04-07__09:00": 2,
        "2026-04-07__10:00": 1
      },
      "requiredRolesByCellKey": {
        "2026-04-07__09:00": {
          "550e8400-e29b-41d4-a716-446655440099": 1
        }
      },
      "paidOptimization": {
        "laborLawCompliance": true,
        "balanceStaffLoad": false,
        "honorShiftWishes": true
      }
    }
  • POST{baseUrl}/v1/staff

    Creates a staff member. Returns 201 with staff JSON.

    Only displayName is accepted.

    Ejemplo de cuerpo de solicitud

    {
      "displayName": "Example Staff"
    }
  • POST{baseUrl}/v1/schedule-results/{conditionId}/emergency-shift

    Clones a completed source schedule with absences applied. Returns 201 with new conditionId. Paid subscription required.

    Prefer absentDayPairs. Legacy: absentStaffIds + absentDatesYmd (Cartesian). You may also send absentSlots. Optional substituteDayPairs / substituteSlots open coverage (source must be completed).

    Ejemplo de cuerpo de solicitud

    {
      "absentDayPairs": [
        {
          "staffId": "550e8400-e29b-41d4-a716-446655440000",
          "dateYmd": "2026-04-08"
        }
      ],
      "substituteDayPairs": [
        {
          "staffId": "660e8400-e29b-41d4-a716-446655440001",
          "dateYmd": "2026-04-08"
        }
      ]
    }
  • POST{baseUrl}/v1/schedule-results/{conditionId}/confirm-assignments

    Validates and saves manually edited assignments. Returns 200 with { ok: true }.

    assignments is required. relaxAvailability is optional (boolean).

    Ejemplo de cuerpo de solicitud

    {
      "assignments": [
        {
          "personId": "550e8400-e29b-41d4-a716-446655440000",
          "personName": "Example Staff",
          "date": "2026-04-07",
          "slotId": "09:00",
          "slotLabel": "09:00"
        }
      ],
      "relaxAvailability": false
    }
  • PATCH{baseUrl}/v1/staff/{staffId}

    Updates one staff member. Send any subset of the fields in the example.

    Personal max minutes: integer or null to clear. laborConstraintMask only when laborLawCompliance is true. schedulingRoleIds / Soft prefer-avoid: UUID arrays; unknown catalog IDs filtered; prefer and avoid must be disjoint. Labor and Soft require paid.

    Ejemplo de cuerpo de solicitud

    {
      "displayName": "Example Staff",
      "laborLawCompliance": true,
      "laborFlsaExempt": false,
      "personalMaxWeeklyMinutes": 2400,
      "personalMaxMonthlyMinutes": null,
      "personalMaxThreeMonthMinutes": null,
      "laborConstraintMask": {
        "schema": "v1"
      },
      "schedulingRoleIds": [
        "550e8400-e29b-41d4-a716-446655440099"
      ],
      "preferredSchedulingRoleIds": [
        "550e8400-e29b-41d4-a716-446655440099"
      ],
      "avoidedSchedulingRoleIds": []
    }
  • DELETE{baseUrl}/v1/staff/{staffId}

    Soft-deletes a staff member (sets deletedAt).

    Sin cuerpo de solicitud.

  • DELETE{baseUrl}/v1/schedule-conditions/{conditionId}

    Marks the condition as cancelled (publicApiCancelledAt); does not delete child rows.

    Sin cuerpo de solicitud.

  • PUT{baseUrl}/v1/schedule-actual/{conditionId}

    Saves actual shift assignments (validated against the condition grid).

    Same assignment object shape as confirm-assignments.

    Ejemplo de cuerpo de solicitud

    {
      "assignments": [
        {
          "personId": "550e8400-e29b-41d4-a716-446655440000",
          "personName": "Example Staff",
          "date": "2026-04-07",
          "slotId": "09:00",
          "slotLabel": "09:00"
        }
      ]
    }
  • PUT{baseUrl}/v1/staff/{staffId}/weekly-shift-wish

    Replaces the weekly wish grid for one staff member (full replace).

    Dates/time range must match the tenant weekly-wish navigation window from schedule defaults. wishByCellKey must cover every cell in that window. Values: NONE | LOW | HIGH.

    Ejemplo de cuerpo de solicitud

    {
      "scheduleStartDate": "2026-04-07",
      "scheduleEndDate": "2026-04-13",
      "timeRangeStart": "09:00",
      "timeRangeEnd": "11:00",
      "wishByCellKey": {
        "2026-04-07__09:00": "HIGH",
        "2026-04-07__10:00": "NONE",
        "2026-04-08__09:00": "LOW",
        "2026-04-08__10:00": "NONE"
      }
    }

Webhooks de finalización

Cuando un resultado de turnos alcanza un estado terminal, hacemos POST de una notificación JSON firmada a su URL HTTPS. El cuerpo no incluye el resultado completo; obtenga detalles con GET /v1/schedule-results/{conditionId}.

Los resultados del playground no se entregan. Si el webhook está deshabilitado o no hay URL guardada, no se envía nada.

Configuración

  • Tras iniciar sesión, abra Gestión de API y guarde una URL de notificación HTTPS.
  • Active «Habilitar notificaciones».
  • Copie el secreto de firma mostrado una sola vez (no se puede volver a revelar; regenérelo si se pierde).
  • Verifique la firma en su receptor y luego haga GET de links.result con su clave API si hace falta.

Eventos

Tipo de evento y cuándo se envía.

  • schedule.result.terminal

    El estado del resultado de turnos pasa a completed, no_solution, failed, error o canceled

typeCuándo
schedule.result.terminalEl estado del resultado de turnos pasa a completed, no_solution, failed, error o canceled

Cuerpo de la solicitud

status es solo terminal. customerId se omite del cuerpo.

{
  "type": "schedule.result.terminal",
  "conditionId": "019ee481-e855-7000-abd8-977cbfd64ffc",
  "status": "completed",
  "occurredAt": "2026-07-16T13:00:54.694Z",
  "links": {
    "result": "{baseUrl}/v1/schedule-results/019ee481-e855-7000-abd8-977cbfd64ffc"
  }
}

Encabezados de solicitud

  • Content-Type

    application/json

  • User-Agent

    AutoScheduler-Webhook/1.0

  • X-AutoScheduler-Timestamp

    Segundos Unix como cadena

  • X-AutoScheduler-Signature

    v1=<hex> (ver verificación abajo)

EncabezadoDescripción
Content-Typeapplication/json
User-AgentAutoScheduler-Webhook/1.0
X-AutoScheduler-TimestampSegundos Unix como cadena
X-AutoScheduler-Signaturev1=<hex> (ver verificación abajo)

Verificación de firma

Calcule un digest del cuerpo en bruto (antes del parseo JSON) y el Timestamp, luego compárelo con Signature. Rechace si |now − timestamp| supera 300 segundos (5 minutos), salvo que permita a propósito un desfase de reloj mayor.

HMAC-SHA256(signingSecret, `${timestamp}.${rawBody}`) → hex; el valor del encabezado es v1=<hex>

Reintentos

Ante 5xx o tiempo de espera reintentamos automáticamente. Los fallos persistentes van a una cola dead-letter. Las notificaciones push del navegador usan otra ruta.

Registrar y activar: Gestión de API

Cabeceras

  • x-api-key

    Clave API vinculada a su suscripción de pago (identifica el inquilino y los límites del plan).

  • Content-Type

    application/json

CabeceraDescripción
x-api-keyClave API vinculada a su suscripción de pago (identifica el inquilino y los límites del plan).
Content-Typeapplication/json

Cabeceras de respuesta

Algunas cabeceras de respuesta (como ids de solicitud) son metadatos de trazabilidad, no su clave API. Trate los **cuerpos** JSON como confidenciales cuando contengan datos de empresa o de usuario.

Límites del plan de pago (derechos)

Límites de validación habituales para su contrato (granularidad de 15 minutos, duración del cuadrante, número de personal registrado y límites relacionados).

  • Modelo de facturación

    Suscripción Stripe; los cargos del producto suelen escalar con los asientos de personal registrados según la página de precios (no por llamada API).

  • maxScheduleDays

    Hasta 14 días naturales por envío en la planificación detallada de dos semanas (tope fijo; el contrato no lo amplía).

  • maxStaffPerSchedule

    Hasta 500 filas staff por POST /v1/schedule (PUBLIC_SCHEDULE_MAX_STAFF; staffId en línea en el cuerpo).

  • maxRosterStaff

    Hasta 30 empleados activos vía POST /v1/staff con el tope predeterminado actual (STAFF_ROSTER_MAX_PAID); 409 STAFF_LIMIT si se supera.

  • allowedGranularities

    [60, 15] — los slots de 15 minutos son de pago; 60 minutos también está soportado.

  • maxPayloadBytes

    524288 (512 KiB) UTF-8 salvo que se conceda un tope mayor.

  • strictUnknownRootKeys

    true — se rechazan claves desconocidas en la raíz o en staff

AjusteAPI de pago (típico)
Modelo de facturaciónSuscripción Stripe; los cargos del producto suelen escalar con los asientos de personal registrados según la página de precios (no por llamada API).
maxScheduleDaysHasta 14 días naturales por envío en la planificación detallada de dos semanas (tope fijo; el contrato no lo amplía).
maxStaffPerScheduleHasta 500 filas staff por POST /v1/schedule (PUBLIC_SCHEDULE_MAX_STAFF; staffId en línea en el cuerpo).
maxRosterStaffHasta 30 empleados activos vía POST /v1/staff con el tope predeterminado actual (STAFF_ROSTER_MAX_PAID); 409 STAFF_LIMIT si se supera.
allowedGranularities[60, 15] — los slots de 15 minutos son de pago; 60 minutos también está soportado.
maxPayloadBytes524288 (512 KiB) UTF-8 salvo que se conceda un tope mayor.
strictUnknownRootKeystrue — se rechazan claves desconocidas en la raíz o en staff

La necesidad de personal por celda sigue siendo un entero de 0 a 15. Al superar los límites de tasa puede devolverse una respuesta de error.

Claves raíz permitidas (modo estricto)

Con el modo estricto solo se aceptan las siguientes claves de nivel superior. Cualquier otra devuelve UNKNOWN_FIELD.

  • apiVersion
  • timeZone
  • scheduleStartDate
  • scheduleEndDate
  • timeRangeStart
  • timeRangeEnd
  • slotGranularityMinutes
  • requirementsByCell
  • requiredRolesByCell (2026-09-09+)
  • paidOptimization (2026-09-13+)
  • preferredSchedulingRoleIds / avoidedSchedulingRoleIds (2026-09-14 staff)
  • staff

Cuerpo de la solicitud (resumen)

El payload sigue el modelo público de pago: fechas de calendario, zona horaria, rejilla de slots (60 o 15 minutos en la API de pago), necesidades por celda y disponibilidad del personal. La jurisdicción laboral no está en el JSON. paidOptimization es opcional para apiVersion 2026-09-13+ (si no, valores predeterminados del inquilino). Los campos Soft prefer/avoid del personal requieren 2026-09-14. Véase «Legislación laboral y flags de pago». No incluya claves DynamoDB ni tipos de entidad internos en el cuerpo.

  • apiVersion — Opcional. Omitir o "2026-04-01" = heredado. "2026-09-09" = roles; "2026-09-13" = roles + paidOptimization; "2026-09-14" = Soft prefer/avoid. Última versión: 2026-09-14.
  • Formato de cellKey — Las claves en requirementsByCell y availableCells deben coincidir con `${date}__${slotId}`, donde date es YYYY-MM-DD en el rango y slotId proviene de los slots enumerados para su rango horario y granularidad (igual que `cellKey` en los helpers del playground).

Tabla de referencia rápida

  • timeZone

    Tipo
    string
    Obligatorio
    Sí

    Zona horaria IANA para interpretar fechas y slots.

  • scheduleStartDate / scheduleEndDate

    Tipo
    string (YYYY-MM-DD)
    Obligatorio
    Sí

    Rango de calendario inclusivo; inicio ≤ fin.

  • timeRangeStart / timeRangeEnd

    Tipo
    string (HH:mm)
    Obligatorio
    Sí

    Rango horario que define la columna de slots; debe generar al menos un slot.

  • slotGranularityMinutes

    Tipo
    60 | 15
    Obligatorio
    Sí

    API de pago: 60 (hora) o 15 (cuartos). Debe estar en allowedGranularities.

  • requirementsByCell

    Tipo
    object
    Obligatorio
    Sí

    Claves = cellKey en la rejilla calculada; valores = entero 0–15.

  • requiredRolesByCell

    Tipo
    object
    Obligatorio
    No — solo 2026-09-09

    cellKey → roleId→need. Suma de need por celda ≤ requirementsByCell. Versiones heredadas → UNKNOWN_FIELD.

  • staff

    Tipo
    array
    Obligatorio
    Sí

    No vacío; tamaño máximo según límites; cada ítem: staffId, displayName, availableCells / laborConstraintMask / schedulingRoleIds (2026-09-09+) / Soft prefer-avoid (2026-09-14) opcionales.

CampoTipoObligatorioNotas
timeZonestringSíZona horaria IANA para interpretar fechas y slots.
scheduleStartDate / scheduleEndDatestring (YYYY-MM-DD)SíRango de calendario inclusivo; inicio ≤ fin.
timeRangeStart / timeRangeEndstring (HH:mm)SíRango horario que define la columna de slots; debe generar al menos un slot.
slotGranularityMinutes60 | 15SíAPI de pago: 60 (hora) o 15 (cuartos). Debe estar en allowedGranularities.
requirementsByCellobjectSíClaves = cellKey en la rejilla calculada; valores = entero 0–15.
requiredRolesByCellobjectNo — solo 2026-09-09cellKey → roleId→need. Suma de need por celda ≤ requirementsByCell. Versiones heredadas → UNKNOWN_FIELD.
staffarraySíNo vacío; tamaño máximo según límites; cada ítem: staffId, displayName, availableCells / laborConstraintMask / schedulingRoleIds (2026-09-09+) / Soft prefer-avoid (2026-09-14) opcionales.

Referencia de campos (valores permitidos)

Las reglas de campo siguientes coinciden con el validador de la API pública. Envíe números JSON como números reales (no como strings). Tras la validación, el servidor puede persistir valores predeterminados de la fila padre (optimización de pago, jurisdicción laboral, versión del modelo) que no son claves de solicitud — véase «Legislación laboral y flags de pago».

apiVersion

string | omitido · Obligatorio: No — opcional

Valores permitidos

  • Omitido: aceptado (comportamiento actual).
  • Si está presente, debe ser "2026-04-01", "2026-09-09", "2026-09-13" o "2026-09-14". Última versión publicada: 2026-09-14.
  • Cualquier otra cadena se rechaza (TYPE_ERROR).

Comportamiento

  • Comparación tras el manejo equivalente a trim en sanitizeApiVersion.
  • La versión selecciona los conjuntos de claves permitidos de nivel superior y del objeto staff (roles en 2026-09-09+; paidOptimization en 2026-09-13+; Soft prefer/avoid en 2026-09-14).

Errores típicos

  • TYPE_ERRORValor de apiVersion no admitido.

timeZone

string · Obligatorio: Sí

Valores permitidos

  • Formato: una sola cadena. La API no publica un enum cerrado de todas las zonas: el servidor valida dinámicamente.
  • La validación coincide con `isValidIanaTimeZone`: Luxon `DateTime.now().setZone(zone).isValid` debe ser true.
  • Use identificadores canónicos de la base IANA, p. ej. `Asia/Tokyo`, `America/New_York`, `Europe/Berlin`, `UTC`.
  • No confíe solo en abreviaturas (`EST`, `JST`, `GMT`) — no son IDs IANA estables y pueden rechazarse.
  • Listas de referencia: distribución IANA (https://www.iana.org/time-zones) o la API de zona horaria de su plataforma.

Comportamiento

  • Se usa con fechas y horas de slot en la normalización posterior.
  • Si necesita una lista fija en el cliente, derívela con las mismas reglas (IDs IANA), no espere un enum del servidor en el esquema JSON.

Errores típicos

  • INVALID_TIME_ZONEFalta, vacío o zona IANA no válida.

scheduleStartDate, scheduleEndDate

string, string · Obligatorio: Sí — ambos

Valores permitidos

  • Debe coincidir con /^\d{4}-\d{2}-\d{2}$/ (tras trim).
  • Fechas de calendario reales; el rango inclusivo debe producir al menos un día vía enumerateDates.
  • El número de días no debe superar maxScheduleDays (API de pago: tope fijo de 14 días para planificación de dos semanas).

Comportamiento

  • scheduleStartDate debe ser anterior o igual a scheduleEndDate.

Errores típicos

  • INVALID_DATE_RANGEFormato incorrecto, fechas inválidas o rango vacío.
  • SCHEDULE_SPAN_TOO_LONGMás de maxScheduleDays días.

timeRangeStart, timeRangeEnd

string, string · Obligatorio: Sí — ambos

Valores permitidos

  • Cadenas no vacías (trim) interpretadas con la misma enumeración de slots que la UI (`enumerateSlotsByGranularity`).
  • El par debe generar al menos un slot; si no, falla la validación.

Comportamiento

  • Junto con slotGranularityMinutes define los slotId usados en cellKey.

Errores típicos

  • INVALID_TIME_RANGEValores faltantes o cero slots para el rango.

slotGranularityMinutes

number (número JSON) · Obligatorio: Sí

Valores permitidos

  • Debe ser exactamente 60 o 15 (no una cadena).
  • También debe figurar en allowedGranularities. En la API de pago suelen estar ambos; si 15 está desactivado para su inquilino, INVALID_GRANULARITY.

Comportamiento

  • Define el número de slots junto con el rango horario.

Errores típicos

  • INVALID_GRANULARITYNo es 60/15 o no permitido en el plan.

requirementsByCell

Record<string, number> · Obligatorio: Sí

Valores permitidos

  • Debe ser un objeto JSON plano (no un array).
  • Cada clave debe ser un cellKey en la rejilla esperada (fechas × slotIds). Claves desconocidas → UNKNOWN_CELL_KEY.
  • Cada valor: número JSON entero entre 0 y 15 inclusive.
  • Las celdas omitidas se tratan como necesidad 0 (solo las celdas con necesidad ≥ 1 entran en SHORTFALL).

Comportamiento

  • Las claves se comparan tras trim vía sanitizeCellKey.

Errores típicos

  • INVALID_REQUIREMENTSNo es un objeto o el valor numérico no es válido.
  • UNKNOWN_CELL_KEYClave fuera de la rejilla fecha × slot calculada.

requiredRolesByCell

object | omitted · Obligatorio: No — opcional; solo apiVersion 2026-09-09

Valores permitidos

  • Solo se acepta cuando apiVersion es "2026-09-09". Omitido / 2026-04-01 → UNKNOWN_FIELD.
  • Debe ser un objeto JSON simple. Cada clave es un cellKey de la cuadrícula requirements.
  • Cada valor es un objeto que mapea roleId (UUID) → need entero ≥ 1.
  • Para cada celda, sum(need) debe ser ≤ requirementsByCell[cell] (o 0 si se omite).
  • La ruta de envío solo valida la forma UUID y la suma (sin consulta al catálogo).

Comportamiento

  • Los valores se normalizan y validan (ID de rol UUID; suma de need ≤ plantilla).
  • Se persiste como requiredRolesBySlot en filas de requisitos diarios.

Errores típicos

  • UNKNOWN_FIELDEnviado con apiVersion heredada.
  • INVALID_REQUIREMENTSForma incorrecta, roleId no UUID, o la suma supera la plantilla.
  • UNKNOWN_CELL_KEYcellKey fuera de la cuadrícula calculada.

staff

array · Obligatorio: Sí — array no vacío

Valores permitidos

  • Longitud entre 1 y maxStaffPerSchedule (predeterminado 500 en POST /v1/schedule; distinto del tope de plantilla en POST /v1/staff).
  • Cada elemento debe ser un objeto plano solo con claves permitidas para el apiVersion: staffId, displayName, availableCells, laborConstraintMask; más schedulingRoleIds en 2026-09-09+; más preferredSchedulingRoleIds / avoidedSchedulingRoleIds en 2026-09-14 (modo estricto).
  • staffId y displayName deben pasar la sanitización (véase «Sanitización»).
  • staffId debe ser único en el array (DUPLICATE_STAFF_ID).

Comportamiento

  • Se conserva el orden para el recuento de disponibilidad.

Errores típicos

  • INVALID_STAFFArray vacío, demasiadas filas, objeto inválido o sanitización fallida.
  • UNKNOWN_FIELDClave extra en un objeto staff en modo estricto.
  • DUPLICATE_STAFF_IDEl mismo staffId dos veces.

staff[].availableCells

string[] | omitido · Obligatorio: No — opcional

Valores permitidos

  • Si se omite: el empleado se considera disponible en todas las celdas (internamente null = «todas las celdas»).
  • Si está presente: array JSON de strings; cada string no vacío debe ser un cellKey en la rejilla esperada.
  • Las cadenas vacías en el array son inválidas (INVALID_AVAILABLE_CELL).

Comprobación SHORTFALL

  • Para cada celda con necesidad ≥ 1, el número de empleados disponibles debe ser ≥ necesidad, si no SHORTFALL_CELLS.

Errores típicos

  • INVALID_AVAILABLE_CELLClave de celda desconocida o entrada vacía.
  • SHORTFALL_CELLSPersonal insuficiente frente al cupo requerido en una celda.

staff[].schedulingRoleIds / Soft prefer-avoid

string[] | omitted · Obligatorio: No — opcional; roles en 2026-09-09+; Soft en 2026-09-14

Valores permitidos

  • schedulingRoleIds: aceptado en apiVersion 2026-09-09+. Soft preferredSchedulingRoleIds / avoidedSchedulingRoleIds: solo 2026-09-14. Versiones anteriores → UNKNOWN_FIELD.
  • Matrices JSON de cadenas UUID. Se eliminan duplicados. Soft prefer ∩ avoid debe estar vacío.
  • Matriz vacía / omitir = sin marco de rol Hard / preferencia Soft en la instantánea de condición.
  • La ruta de envío no filtra contra el catálogo del inquilino; PATCH /v1/staff/{staffId} sí (PATCH Soft de pago).

Comportamiento

  • Los valores se normalizan (cadenas UUID; duplicados eliminados). Superposición Soft → INVALID_STAFF.
  • Se copia en filas de instantánea de condición de personal cuando no está vacío.

Errores típicos

  • UNKNOWN_FIELDEnviado con un apiVersion que no permite la clave.
  • INVALID_STAFFNo es una matriz, elemento no UUID o superposición Soft prefer/avoid.

Legislación laboral y optimización de pago (no van en el JSON)

n/c — persistido en el servidor · En la solicitud: No — nunca envíe estas claves

Qué guarda la API en la fila padre

  • La API pública solo acepta las claves de nivel superior y de objeto staff permitidas para su apiVersion. No envíe laborLawJurisdiction, usLaborStateCode ni laborModelVersion. paidOptimization es opcional para apiVersion 2026-09-13+. Los campos Soft prefer/avoid del personal requieren 2026-09-14.
  • Al enviar, el servidor rellena SCHEDULE_CONDITION padre con valores compartidos: paidOptimization del cuerpo (apiVersion 2026-09-13+) o SCHEDULE_DEFAULTS del inquilino si se omite; si no, DEFAULT_PAID_OPTIMIZATION (laborLawCompliance del padre forzado a true). laborLawJurisdiction / usLaborStateCode / laborModelVersion se heredan de SCHEDULE_DEFAULTS del inquilino (reserva JP / GENERIC / modelo según jurisdicción).
  • Las restricciones laborales tipo ley en el optimizador requieren flags de cumplimiento activos en padre y por empleado. Los flags por persona no van en el JSON: el servidor los hereda de la plantilla (staffId ausentes quedan activos por defecto). POST /v1/staff también crea activos; desactivar por persona con PATCH de pago /v1/staff/{staffId}.
  • El modelo laboral es una aproximación para la planificación, no asesoramiento legal. Catálogo: .

Documentación

  • Detalle: this page y §3.1.

Si envía claves no permitidas

  • UNKNOWN_FIELDEl modo estricto rechaza propiedades desconocidas en la raíz o en staff.

Reglas de sanitización

Se aplica antes o durante la validación. Estas reglas explican por qué un valor puede rechazarse como INVALID_STAFF.

staffId

  • Trim; longitud 1–128.
  • Caracteres: /^[a-zA-Z0-9._-]+$/ (sin barras ni contrabarras).

displayName

  • Eliminar caracteres de control y de ancho cero; colapsar espacios; trim.
  • No se permiten los signos < y >.
  • Máx. 128 caracteres tras sanitizar; no puede quedar vacío.

Claves de celda (requirements / availableCells)

  • Las claves se recortan; deben coincidir exactamente con los cellKey de la rejilla calculada.

Respuesta correcta

202 Accepted

El cuerpo pasó la validación y se escribió la condición; la optimización puede continuar de forma asíncrona. El manejador puede devolver JSON con conditionId y campos relacionados.

Códigos de error (lista completa)

Los errores de validación devuelven información estructurada con un `code` estable. El análisis ocurre antes de la validación (INVALID_JSON, PAYLOAD_TOO_LARGE). Los fallos de persistencia pueden aparecer como DYNAMODB_ERROR. PATCH /v1/schedule-defaults puede devolver SCHEDULE_DEFAULTS_SAVE_FAILED (HTTP 400) con detalles.

  • INVALID_JSON

    El cuerpo no es JSON válido.

  • PAYLOAD_TOO_LARGE

    La longitud en bytes UTF-8 supera maxPayloadBytes (por defecto 512 KiB).

  • TYPE_ERROR

    Tipo JSON incorrecto o cadena apiVersion no admitida.

  • UNKNOWN_FIELD

    Modo estricto: propiedad no permitida en la raíz o en staff.

  • INVALID_TIME_ZONE

    timeZone ausente o no es un nombre IANA válido.

  • INVALID_DATE_RANGE

    Fechas no YYYY-MM-DD, rango inválido o enumeración vacía.

  • SCHEDULE_SPAN_TOO_LONG

    Demasiados días entre inicio y fin (véase maxScheduleDays).

  • INVALID_TIME_RANGE

    Rango horario ausente o genera cero slots.

  • INVALID_GRANULARITY

    slotGranularityMinutes no es 60/15 o no permitido en el plan.

  • INVALID_REQUIREMENTS

    requirementsByCell no es objeto o el recuento no es entero 0–15.

  • UNKNOWN_CELL_KEY

    Clave no está en la rejilla de planificación calculada.

  • INVALID_STAFF

    staff vacío, demasiado grande, fila inválida o sanitización fallida.

  • DUPLICATE_STAFF_ID

    Valores staffId duplicados.

  • INVALID_AVAILABLE_CELL

    Entrada vacía o desconocida en availableCells.

  • SHORTFALL_CELLS

    Disponibilidad insuficiente frente a las necesidades.

  • DYNAMODB_ERROR

    Error transitorio o de persistencia tras la validación (depende del manejador).

  • SCHEDULE_DEFAULTS_SAVE_FAILED

    PATCH /v1/schedule-defaults: validación o reglas de negocio fallidas (véase error.details).

  • LABOR_COMPLIANCE_REQUIRED

    PATCH /v1/staff/{staffId}: laborConstraintMask enviado con laborLawCompliance en false.

CódigoSignificado
INVALID_JSONEl cuerpo no es JSON válido.
PAYLOAD_TOO_LARGELa longitud en bytes UTF-8 supera maxPayloadBytes (por defecto 512 KiB).
TYPE_ERRORTipo JSON incorrecto o cadena apiVersion no admitida.
UNKNOWN_FIELDModo estricto: propiedad no permitida en la raíz o en staff.
INVALID_TIME_ZONEtimeZone ausente o no es un nombre IANA válido.
INVALID_DATE_RANGEFechas no YYYY-MM-DD, rango inválido o enumeración vacía.
SCHEDULE_SPAN_TOO_LONGDemasiados días entre inicio y fin (véase maxScheduleDays).
INVALID_TIME_RANGERango horario ausente o genera cero slots.
INVALID_GRANULARITYslotGranularityMinutes no es 60/15 o no permitido en el plan.
INVALID_REQUIREMENTSrequirementsByCell no es objeto o el recuento no es entero 0–15.
UNKNOWN_CELL_KEYClave no está en la rejilla de planificación calculada.
INVALID_STAFFstaff vacío, demasiado grande, fila inválida o sanitización fallida.
DUPLICATE_STAFF_IDValores staffId duplicados.
INVALID_AVAILABLE_CELLEntrada vacía o desconocida en availableCells.
SHORTFALL_CELLSDisponibilidad insuficiente frente a las necesidades.
DYNAMODB_ERRORError transitorio o de persistencia tras la validación (depende del manejador).
SCHEDULE_DEFAULTS_SAVE_FAILEDPATCH /v1/schedule-defaults: validación o reglas de negocio fallidas (véase error.details).
LABOR_COMPLIANCE_REQUIREDPATCH /v1/staff/{staffId}: laborConstraintMask enviado con laborLawCompliance en false.

Ejemplo JSON mínimo

{
  "apiVersion": "2026-04-01",
  "timeZone": "Asia/Tokyo",
  "scheduleStartDate": "2026-04-07",
  "scheduleEndDate": "2026-04-13",
  "timeRangeStart": "08:00",
  "timeRangeEnd": "20:00",
  "slotGranularityMinutes": 60,
  "requirementsByCell": {
    "2026-04-07__slot-0": 2
  },
  "staff": [
    {
      "staffId": "550e8400-e29b-41d4-a716-446655440000",
      "displayName": "Example",
      "availableCells": ["2026-04-07__slot-0"]
    }
  ]
}

En esta página. POST /v1/schedule: referencia de campos y tabla rápida. Valores predeterminados: endpoints de escritura → PATCH /v1/schedule-defaults. Labor / Soft: PATCH /v1/staff/{staffId}. Planes: página de precios.