API REST v1

Guia por recurso. Para o esquema OpenAPI completo e um explorador interativo, ver Referência.

Students

GET /students Limite: 120/60s

List students

Every user who has at least one course application and is not an administrator. Requires the `students:read` token scope.

Parâmetros

search (query)Case-insensitive match against name or email.
status (query)Filter by email verification state.
sort (query)Sort column.
direction (query)Sort direction.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/students?per_page=20"
GET /students/{student} Limite: 120/60s

Get a student

Not implicit route-model-binding to App\Models\User — that would let any user id resolve, including admins. "Student" isn't User's own natural scope, so this resolves manually and 404s the same way for a nonexistent id and for a real user id that just isn't a student, never revealing which.

Parâmetros

student (path, obrigatório)

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/students/{student}"

Courses

GET /courses Limite: 120/60s

List courses

The training catalogue. Requires the `courses:read` token scope.

Parâmetros

active (query)Filter by publication state (1/0/true/false).
sort (query)Sort column.
direction (query)Sort direction.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses?per_page=20"
GET /courses/{course} Limite: 120/60s

Get a course

Implicit binding by slug — Course::getRouteKeyName() already returns "slug" (Sprint 13), the same convention every existing course route already uses.

Parâmetros

course (path, obrigatório)The course slug

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}"
GET /courses/{course}/sessions Limite: 120/60s

List a course's training sessions

Requires the `courses:read` token scope.

Parâmetros

course (path, obrigatório)The course slug
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}/sessions?per_page=20"
GET /courses/{course}/sessions/{session} Limite: 120/60s

Get a training session

Parâmetros

course (path, obrigatório)The course slug
session (path, obrigatório)The session ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}/sessions/{session}"
GET /courses/{course}/sessions/{session}/assessments Limite: 120/60s

List a session's assessments

Requires the `courses:read` token scope.

Parâmetros

course (path, obrigatório)The course slug
session (path, obrigatório)The session ID
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}/sessions/{session}/assessments?per_page=20"
GET /courses/{course}/sessions/{session}/assessments/{assessment} Limite: 120/60s

Get an assessment

Parâmetros

course (path, obrigatório)The course slug
session (path, obrigatório)The session ID
assessment (path, obrigatório)The assessment ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}/sessions/{session}/assessments/{assessment}"
GET /courses/{course}/sessions/{session}/resources Limite: 120/60s

List a session's learning resources

Only published resources are returned. Requires the `courses:read` token scope.

Parâmetros

course (path, obrigatório)The course slug
session (path, obrigatório)The session ID
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}/sessions/{session}/resources?per_page=20"
GET /courses/{course}/sessions/{session}/resources/{resource} Limite: 120/60s

Get a learning resource

Returns 404 for a Draft resource — its existence is not exposed via the API, the same as if the id didn't exist at all.

Parâmetros

course (path, obrigatório)The course slug
session (path, obrigatório)The session ID
resource (path, obrigatório)The resource ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}/sessions/{session}/resources/{resource}"
GET /courses/{course}/sessions/{session}/meetings Limite: 120/60s

List a session's meetings

Requires the `courses:read` token scope.

Parâmetros

course (path, obrigatório)The course slug
session (path, obrigatório)The session ID
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}/sessions/{session}/meetings?per_page=20"
GET /courses/{course}/sessions/{session}/meetings/{meeting} Limite: 120/60s

Get a meeting

Parâmetros

course (path, obrigatório)The course slug
session (path, obrigatório)The session ID
meeting (path, obrigatório)The meeting ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/courses/{course}/sessions/{session}/meetings/{meeting}"

Users

GET /users Limite: 120/60s

List users

Admin/staff users only — never students. Requires the `users:read` token scope.

Parâmetros

status (query)Filter by lifecycle status.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/users?per_page=20"
POST /users Limite: 120/60s

Create a user

Creates a "draft" user — no invitation is sent from here; call the invite action separately. Requires the `users:write` token scope.

GET /users/{user} Limite: 120/60s

Get a user

Requires the `users:read` token scope.

Parâmetros

user (path, obrigatório)The user ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/users/{user}"
PATCH /users/{user} Limite: 120/60s

Update a user

Requires the `users:write` token scope.

Parâmetros

user (path, obrigatório)The user ID
POST /users/{user}/invite Limite: 120/60s

Invite a user

draft -> invited. Requires the `users:write` token scope.

Parâmetros

user (path, obrigatório)The user ID
POST /users/{user}/suspend Limite: 120/60s

Suspend a user

active -> suspended. Requires the `users:write` token scope.

Parâmetros

user (path, obrigatório)The user ID
POST /users/{user}/reactivate Limite: 120/60s

Reactivate a user

suspended -> active. Requires the `users:write` token scope.

Parâmetros

user (path, obrigatório)The user ID
POST /users/{user}/archive Limite: 120/60s

Archive a user

Terminal transition. Requires the `users:write` token scope.

Parâmetros

user (path, obrigatório)The user ID

Enrolments

GET /enrolments Limite: 120/60s

List enrolments

Requires the `enrolments:read` token scope.

Parâmetros

student_id (query)Filter to a single student.
course_id (query)Filter to a single course (matched through the enrolment's intake).
status (query)Filter by enrolment status (confirmed/waitlisted/cancelled).
sort (query)Sort column.
direction (query)Sort direction.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/enrolments?per_page=20"
GET /enrolments/{enrolment} Limite: 120/60s

Get an enrolment

Route parameter is spelled "enrolment" (the approved API naming), the underlying Eloquent model stays Enrollment (American spelling, unchanged) — implicit binding only cares about the type-hint, so the spelling mismatch is cosmetic, not a functional concern.

Parâmetros

enrolment (path, obrigatório)The enrolment ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/enrolments/{enrolment}"

Notifications

GET /notifications Limite: 120/60s

List notifications

Identity-lifecycle email notifications (invitations, activation, suspension, reactivation, archival). Requires the `identity-notifications:read` token scope.

Parâmetros

type (query)Filter by notification type.
status (query)Filter by delivery status.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/notifications?per_page=20"
GET /notifications/{notification} Limite: 120/60s

Get a notification

Requires the `identity-notifications:read` token scope.

Parâmetros

notification (path, obrigatório)The notification ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/notifications/{notification}"

Certificates

GET /certificates Limite: 120/60s

List certificates

Requires the `certificates:read` token scope.

Parâmetros

student_id (query)Filter to a single student.
course_id (query)Filter to a single course (matched through the certificate's enrolment/intake).
sort (query)Sort column.
direction (query)Sort direction.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/certificates?per_page=20"
GET /certificates/{certificate} Limite: 120/60s

Get a certificate

Parâmetros

certificate (path, obrigatório)The certificate ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/certificates/{certificate}"
GET /certificates/verify/{certificate} Público Limite: 30/60s

Verify a certificate

Public — no token required. Mirrors the existing public web route exactly: resolves by the opaque verification_token only, never certificate_number or the row's own id, and 404s automatically for any unmatched or tampered token via Laravel's standard implicit-binding failure — no signal given either way about why it didn't resolve.

Parâmetros

certificate (path, obrigatório)The certificate verification token

Exemplo (cURL)

curl \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/certificates/verify/{certificate}"

Documents

GET /documents Limite: 120/60s

List documents

Requires the `documents:read` token scope.

Parâmetros

type (query)Filter by document type.
status (query)Filter by lifecycle status.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/documents?per_page=20"
POST /documents Limite: 120/60s

Upload a document

Multipart upload. Requires the `documents:write` token scope.

GET /documents/{document} Limite: 120/60s

Get a document

Requires the `documents:read` token scope.

Parâmetros

document (path, obrigatório)The document ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/documents/{document}"
PATCH /documents/{document} Limite: 120/60s

Update document metadata

Never re-uploads the file — a new version is a new `store` call with `supersedes_id`. Requires the `documents:write` token scope.

Parâmetros

document (path, obrigatório)The document ID
DELETE /documents/{document} Limite: 120/60s

Delete a document

Soft, terminal transition — the underlying file is not physically removed. Requires the `documents:write` token scope.

Parâmetros

document (path, obrigatório)The document ID
GET /documents/{document}/download Limite: 120/60s

Download a document

Requires the `documents:read` token scope.

Parâmetros

document (path, obrigatório)The document ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/documents/{document}/download"
POST /documents/{document}/archive Limite: 120/60s

Archive a document

stored/available -> archived. Requires the `documents:write` token scope.

Parâmetros

document (path, obrigatório)The document ID

Reports

GET /reports Limite: 120/60s

List reports

Requires the `reports:read` token scope.

Parâmetros

type (query)Filter by report type.
status (query)Filter by lifecycle status.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/reports?per_page=20"
POST /reports Limite: 120/60s

Request a report

Generation is always asynchronous — this returns immediately with the report in "requested" status; poll `GET /reports/{id}` or use the download endpoint once it reports "available". Requires the `reports:write` token scope.

GET /reports/{report} Limite: 120/60s

Get a report

Requires the `reports:read` token scope.

Parâmetros

report (path, obrigatório)The report ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/reports/{report}"
GET /reports/{report}/download Limite: 120/60s

Download a report

409 if the report is not yet available. Requires the `reports:read` token scope.

Parâmetros

report (path, obrigatório)The report ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/reports/{report}/download"

Search

GET /search Limite: 120/60s

Search

Searches every registered resource (Users, Documents, Reports, Notifications, and the pre-existing academic/training resources) and returns results grouped by resource type. A blank query returns every group with empty results. Requires the `search:read` token scope.

Parâmetros

q (query)The search query.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/search?per_page=20"

Organization

GET /organization Limite: 120/60s

Get the organization

Requires the `organization:read` token scope.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/organization"
PATCH /organization Limite: 120/60s

Update the organization

Partial update — only the fields present in the request body are changed. Requires the `organization:write` token scope.

Workflows

GET /workflows Limite: 120/60s

List workflow instances

Requires the `workflows:read` token scope.

Parâmetros

workflow (query)Filter by workflow key.
state (query)Filter by current state.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/workflows?per_page=20"
GET /workflows/{workflow} Limite: 120/60s

Get a workflow instance

Requires the `workflows:read` token scope.

Parâmetros

workflow (path, obrigatório)The workflow ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/workflows/{workflow}"
POST /workflows/{workflow}/transition Limite: 120/60s

Transition a workflow instance

Records an approval decision and moves the instance to `to_state`. Requires the `workflows:write` token scope, and the acting user must hold the workflow's own `approval_policy.required_permission`.

Parâmetros

workflow (path, obrigatório)The workflow ID
POST /workflows/{workflow}/assign Limite: 120/60s

Assign a workflow instance

Requires the `workflows:write` token scope, and the acting user must hold the workflow's own `approval_policy.required_permission`.

Parâmetros

workflow (path, obrigatório)The workflow ID

Tasks

GET /tasks Limite: 120/60s

List scheduled tasks

Requires the `tasks:read` token scope.

Parâmetros

task_type (query)Filter by task type.
enabled (query)Filter by enabled status.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/tasks?per_page=20"
GET /tasks/{task} Limite: 120/60s

Get a scheduled task

Requires the `tasks:read` token scope.

Parâmetros

task (path, obrigatório)The task ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/tasks/{task}"
POST /tasks/{task}/run Limite: 120/60s

Run a scheduled task now

Bypasses the cron timer but otherwise queues exactly like a real fire. Requires the `tasks:write` token scope.

Parâmetros

task (path, obrigatório)The task ID

Integrations

GET /integrations Limite: 120/60s

List integration messages

Requires the `integration-messages:read` token scope.

Parâmetros

integration_key (query)Filter by integration key.
status (query)Filter by delivery status.
per_page (query)Results per page, clamped to api.max_page_size.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/integrations?per_page=20"
GET /integrations/{message} Limite: 120/60s

Get an integration message

Requires the `integration-messages:read` token scope.

Parâmetros

message (path, obrigatório)The message ID

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/integrations/{message}"
POST /integrations/{message}/retry Limite: 120/60s

Retry an integration message

Only a failed message may be retried. Requires the `integration-messages:write` token scope.

Parâmetros

message (path, obrigatório)The message ID

Health

GET /health Limite: 120/60s

List health check results

Runs every active, enabled health check and returns each result alongside the aggregated overall status. Requires the `health:read` token scope.

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/health"
GET /health/{check} Limite: 120/60s

Get a single health check result

Requires the `health:read` token scope.

Parâmetros

check (path, obrigatório)

Exemplo (cURL)

curl \
  -H "Authorization: Bearer $CATDI_TOKEN" \
  -H "Accept: application/json" \
  "https://catdi.org/api/v1/health/{check}"