List Decola Progress
Endpoint used to list student learning progress (storyboard activity and course enrollments) for the institution in the JWT. Designed for RX pull by an external cron (e.g. iFood Decola). Pagination uses an opaque cursor (no global total / COUNT).
Note: This endpoint is served by Toolzz LXP API (Encore
decolaservice), not by the institution monolith domain. Use the LXP API base URL (e.g.https://lxp.prod.api.toolzz.media).
Warning: Requires a JWT for ADMIN (
privilegio_id = 2) or MANAGER (privilegio_id = 5). Report rows include only active students (privilegio_id = 4).
Request Example
Section titled “Request Example”curl --request GET \ --url 'https://lxp.prod.api.toolzz.media/api/v1/decola/progress?limit=100' \ --header 'Authorization: Bearer <token>' \ --header 'Accept: application/json'With optional date filter (D-1 incremental ingest):
curl --request GET \ --url 'https://lxp.prod.api.toolzz.media/api/v1/decola/progress?limit=100&date_field=completion_date&date_from=2026-07-14&date_to=2026-07-14' \ --header 'Authorization: Bearer <token>'Response Example
Section titled “Response Example”{ "data": [ { "user_email": "ana.restaurante@toolzz.local", "user_name": "Ana Costa Restaurante", "cnpj": "22.222.222/0001-05", "schools": ["Escola Sede Decola Teste"], "storyboard_title": "Gestão de Estoque em Restaurantes", "storyboard_id": "sb70131892014dec014", "storyboard_likes": 0, "storyboard_dislikes": 0, "storyboard_completed": false, "storyboard_views": 1, "storyboard_updated": "2026-07-02T06:03:57.000Z", "storyboard_start_date": "2026-07-02T06:03:57.000Z", "storyboard_end_date": null, "course_name": null, "course_id": null, "enrollment_date": null, "completion_date": null, "grade": null, "completion_percentage": null }, { "user_email": "ana.restaurante@toolzz.local", "user_name": "Ana Costa Restaurante", "cnpj": "22.222.222/0001-05", "schools": ["Escola Sede Decola Teste"], "storyboard_title": null, "storyboard_id": null, "storyboard_likes": null, "storyboard_dislikes": null, "storyboard_completed": null, "storyboard_views": null, "storyboard_updated": null, "storyboard_start_date": null, "storyboard_end_date": null, "course_name": "Segurança Alimentar Avançada", "course_id": 70131801, "enrollment_date": "2026-05-24T06:03:57.000Z", "completion_date": null, "grade": null, "completion_percentage": 0 } ], "pagination": { "limit": 100, "next_cursor": "eyJuIjoiLi4uIn0", "has_more": true }}Request description
Section titled “Request description”Access Token
Section titled “Access Token”| Parameter | Type | Description | Required |
|---|---|---|---|
Authorization | String | JWT access token (Bearer <token>). Institution is taken from the JWT institution claim. | Yes |
URL Parameters (Query)
Section titled “URL Parameters (Query)”| Parameter | Type | Description | Required |
|---|---|---|---|
limit | number | Items per page. Default 100. Maximum controlled by secret DecolaMaxPerPage (default 100). | No |
cursor | string | Opaque cursor from the previous response (pagination.next_cursor). Omit on the first page. | No |
date_from | string | Start of date range (YYYY-MM-DD or ISO-8601). Must be sent together with date_to. | No |
date_to | string | End of date range (YYYY-MM-DD or ISO-8601). Must be sent together with date_from. | No |
date_field | string | Required when dates are set. One of: storyboard_updated, storyboard_start_date, storyboard_end_date, enrollment_date, completion_date. | Conditionally |
Response description
Section titled “Response description”| Key | Type | Description |
|---|---|---|
data | array | Progress rows for the current page. |
data[].user_email | string | null | Student email. |
data[].user_name | string | null | Student name. |
data[].cnpj | string | null | Company CNPJ from personal data. |
data[].schools | string[] | School titles linked to the student. |
data[].storyboard_* | mixed | Filled on storyboard rows; null on course rows. |
data[].course_* / enrollment_date / completion_date / grade / completion_percentage | mixed | Filled on course rows; null on storyboard rows. |
pagination.limit | number | Requested page size. |
pagination.next_cursor | string | null | Cursor for the next page; null when finished. |
pagination.has_more | boolean | true if more pages are available. |
Each item is either a storyboard row or a course row (MySQL UNION ALL). The other type’s fields are null.
completion_percentage on course rows is derived per student+course (completed contents ÷ course contents × 100). It is not stored as a column and is not an average of the page.
Cursor pagination (cron)
Section titled “Cursor pagination (cron)”- Call without
cursor. - Process
data. - If
pagination.has_moreistrue, call again withcursor=pagination.next_cursor. - Repeat until
has_moreisfalse.
There is no total / total_pages — the API does not run a full-table COUNT.
Error responses
Section titled “Error responses”| HTTP | Code | When |
|---|---|---|
| 400 | invalid_argument | Invalid limit, cursor, or incomplete/invalid date filter |
| 401 | unauthenticated | Missing or invalid JWT |
| 403 | permission_denied | User is not ADMIN or MANAGER in the institution |
| 429 | resource_exhausted | Rate limit (60 requests/minute per institution) |
| 503 | unavailable | MySQL unavailable |
| 504 | deadline_exceeded | MySQL query exceeded DecolaMysqlQueryTimeoutMs |
Example:
{ "code": "permission_denied", "message": "Access denied. Only administrators or managers can access this endpoint.", "details": null}Security
Section titled “Security”- Requires valid JWT with ADMIN or MANAGER privilege (
auth: true). - Data is scoped to the institution from the token.
- Report subjects are active students only (
privilegio_id = 4). - Responses may be cached in Redis (~30 minutes) per institution + cursor + limit + date filter.