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}"