Loading...
Technical documentation and endpoint specifications
https://planifica.educationAll API endpoints are relative to this base URL. For example, to optimize a schedule, POST to https://planifica.education/api/v1/edt/optimize
All API requests require authentication using an API key. Include your API key in the request header.
X-API-Key: digi_xxxxxxxxxxxxxxxxxxxxxxxx Authorization: ApiKey digi_xxxxxxxxxxxxxxxxxxxxxxxx
Either header works — use whichever fits your HTTP client.
Keep your API key secure and never expose it in client-side code. Use environment variables in production.
In addition to your API key, every optimize, allocation, and validate request must include schoolExternalId and schoolNameas top-level fields identifying which school the request is for. This is enforced server-side — requests without them are rejected.
{
"schoolExternalId": "your-school-id",
"schoolName": "School Display Name"
}schoolExternalId is a stable identifier you choose (e.g. your own school ID) and is used as the grouping key for usage tracking and per-school rate limits.schoolName is a human-readable label. Both fields are required strings, max 255 characters.
https://planifica.education/api/v1/edt/optimizeStart an asynchronous optimization task
The request body is the EDT optimization payload, plus two required top-level fields, schoolExternalId and schoolName (identify the school for usage tracking, see Authentication). There is no wrapper object — if you already send EDTRequest bodies directly to the ML backend, just add these two fields.
{
"schoolExternalId": "your-school-id",
"schoolName": "School Display Name",
"requestid": "unique-request-identifier",
"config": {
"max_time_in_seconds": 600,
"objective_type": "AFFINITY",
"use_objective": false,
"debug_enabled": true,
"debug_level": "full"
},
"data": {
"requestid": "unique-request-identifier",
"config": {
"max_time_in_seconds": 600,
"objective_type": "AFFINITY",
"use_objective": false,
"debug_enabled": true,
"debug_level": "full"
},
{
"code": "MA",
"name": "Mathematics"
}
],
"grades": [
{
"code": "CP",
"groups": ["A", "B"],
"working_hours": [
["Monday", {
"available_hours": [["08:00", "12:00"], ["13:00", "17:00"]],
"unavailable_periods": [["10:00", "10:30"]]
}]
]
}
],
"classrooms": [
{
"id": 1,
"subjects": ["AR", "MA"]
}
],
"instructors": [
{
"id": 1,
"name": "John Doe",
"subjects": ["MA"],
"capacity": 24,
"grades": ["CP"],
"available_days": [
["Monday", {
"available_hours": [["08:00", "17:00"]],
"unavailable_periods": [["12:00", "13:00"]]
}]
]
}
],
"schemas": [
{
"grade": "CP",
"sessions": [
{
"id": "session_1",
"session": "MATH_001",
"grade": "CP",
"group": "A",
"duration": 2,
"subject": "MA"
},
{
"id": "session_2",
"session": "MATH_002",
"grade": "CP",
"group": "B",
"duration": 2,
"subject": "MA"
}
]
}
]
}Note: Requests missing schoolExternalId or schoolName are rejected with a 400 error (SCHOOL_REQUIRED).
{
"id": "task_123456",
"status": "queued",
"message": "Optimization task queued successfully"
}Control optimization behavior with intelligent stop conditions that balance solution quality, processing time, and resource consumption.
Set hard limits on processing time to ensure responsive applications.
max_time_in_seconds: 300Stop automatically when solution quality stops improving.
no_improvement_timeout_seconds: 60Key objects used across the optimization, allocation, and validation endpoints.
Top-level fields identifying the target school for the request, alongside your EDTRequest fields. Required on every optimize, allocation, and validate call.
| Field | Type | Description |
|---|---|---|
schoolExternalId | string (required, max 255) | Stable identifier you assign to the school. Used to group requests by school for usage and rate-limiting purposes. |
schoolName | string (required, max 255) | Human-readable school name. |
{
"schoolExternalId": "your-school-id",
"schoolName": "School Display Name"
}The endpoints above belong to a dedicated gateway for managed partner integrations: validate a payload, submit an optimization or allocation job, and poll the task by ID. Authentication and request shape are the same as described in Authentication above.
Include one of these headers on every request to the partner gateway.
X-API-Key: digi_xxxxxxxxxxxxxxxxxxxxxxxxAuthorization: ApiKey digi_xxxxxxxxxxxxxxxxxxxxxxxx/api/v1/app/planifica/api/optimize/api/v1/app/planifica/api/allocate/api/v1/app/planifica/api/validate/api/v1/app/planifica/api/tasks/{taskId}/api/v1/app/planifica/api/tasks/{taskId}See Error Codes below for the optimizer's domain-level errors, and the dedicated error code reference for the partner gateway's own auth/HTTP error codes (invalid key, rate limit, etc.).
The API returns specific error codes to help identify and resolve scheduling issues. Each errors[]/warnings[] entry has a stable code you should branch on, plus a human-readable message that's safe to show end users but may be reworded between releases.
A 200/202 response is not, by itself, success. Domain-level scheduling problems are returned inside the response body, not as HTTP error statuses. Always check status (/optimize, /allocation) or valid (/validate) and inspect errors[] before assuming a request succeeded. errors[] entries are fatal; warnings[]entries are non-fatal — the request still processed, but something is worth surfacing to the end user.
The full catalog — optimizer/scheduling error codes (data integrity, setup, availability, capacity, locked sessions, ordering, cardinality) plus the partner gateway's own auth/HTTP error codes — lives on a dedicated page so it doesn't crowd out the rest of this reference.
View all error codes →Success
Request completed successfully
Bad Request
Invalid request data or missing required fields
Unauthorized
Missing or invalid API key
Too Many Requests
Rate limit exceeded
Internal Server Error
Unexpected server error
{
"error": {
"code": "INVALID_REQUEST",
"message": "Missing required field: timetable.working_days",
"details": {
"field": "timetable.working_days",
"expected": "array",
"received": "undefined"
}
}
}Rate limit information is included in response headers:
X-RateLimit-Limit: 100 X-RateLimit-Remaining: 99 X-RateLimit-Reset: 1640995200