Skip to content

API Endpoints

Base URL: https://api.perfxcel.com/api/v1

All protected endpoints require Authorization: Bearer <token> and the caller must have an active user_tenant_roles entry for the perfxcel app.


Courses

Method Path Auth Description
GET /courses Public List published, active, public courses. Supports category_ids, city_ids, association_ids, delivery_mode_ids, search, sort, page, limit query params.
GET /courses/:id Public Get a single course by UUID or slug. Returns full course including course_outline, overview, brochure_url.
POST /courses Admin Create a course. Accepts full courseInputSchema payload.
PUT /courses/:id Admin Update a course.
PATCH /courses/bulk Admin Bulk update is_published or status for an array of course IDs.
DELETE /courses/:id Admin Soft-delete a course (status = 'deleted').
POST /courses/:id/interest Public (Turnstile) Register interest in a course. Pass request_brochure: true to also trigger a brochure email.

Interests

Method Path Auth Description
GET /interests Admin Paginated list. Supports search, status, course_id, date_from, date_to, sort, page, limit.
POST /interests Admin Manually create an interest record (no Turnstile). Pass send_brochure: true to trigger a brochure email.
PATCH /interests/:id Admin Update interest status (new / contacted / enrolled / rejected).
DELETE /interests Admin Bulk soft-delete. Body: { ids: string[] }.
POST /interests/:id/resend-brochure Admin Resend brochure email. Regenerates token if expired. Returns { regenerated: boolean }.
POST /interests/:id/hard-delete Admin GDPR erasure — anonymises PII fields. Irreversible.
GET /interests/brochure/:token Public Validate token and stream brochure PDF. Returns 403 if expired.

Enrollments

Method Path Auth Description
GET /enrollments Admin Paginated list with search, status, sort, page, limit.
POST /enrollments Admin Create enrollment from an interest ID.
PATCH /enrollments/:id Admin Update status (pending / in_progress / achieved / dropped). Marking achieved triggers certificate generation and email.
POST /enrollments/:id/resend-certificate Admin Resend certificate email. Fetches existing PDF from storage.

Training Plans

Method Path Auth Description
GET /training-plan Admin Paginated list. Supports search, date_from, date_to, page, limit.
POST /training-plan/request Public (Turnstile) Public form submission. Sends download email.
POST /training-plan Admin Manually create a training plan request and send email (no Turnstile).
GET /training-plan/download/:token Public Validate token and stream training plan PDF. Returns 403 if expired.
DELETE /training-plan Admin Bulk soft-delete. Body: { ids: string[] }.
POST /training-plan/:id/resend Admin Resend download email. Regenerates token if expired. Returns { regenerated: boolean }.
POST /training-plan/:id/hard-delete Admin GDPR erasure.

Enquiries

Method Path Auth Description
GET /enquiries Admin Paginated list. Supports search, status, date_from, date_to, page, limit.
PATCH /enquiries/:id Admin Update status (new / responded).
POST /contact Public (Turnstile) Submit a contact enquiry.

Settings

Method Path Auth Description
GET /settings Admin Returns current settings as a flat object: { training_plan_expiry_days: 180, brochure_expiry_days: 180 }.
PUT /settings Admin Update one or both expiry settings. Body: { training_plan_expiry_days?: number, brochure_expiry_days?: number }.

Upload (File Proxy)

All file uploads go through these endpoints — never directly to Supabase Storage from the frontend.

Method Path Auth Description
POST /upload/training-plan Admin Upload a new training plan PDF (multipart/form-data, field file). Writes to assets bucket as training_plan.pdf.
GET /upload/training-plan/download Admin Generate a 60-second signed URL for the current training plan PDF.
POST /upload/course-brochure Admin Upload a course brochure PDF (multipart/form-data, fields file + short_code). Writes to course-brochures bucket.

Verify (Certificates)

Method Path Auth Description
POST /verify Public (Turnstile) Verify a certificate by credential_id. Returns candidate name, course, and issue date.
GET /verify/:id/pdf Public Stream certificate PDF by credential ID.

Metrics & Audit

Method Path Auth Description
GET /metrics Admin Dashboard metrics (course counts, interests, enrollments, etc.).
GET /audit-logs Admin Query audit log entries. Proxied to portal-api. Supports action, entityType, from, to, page, pageSize.
POST /audit-logs Admin Write audit log entries. Proxied to portal-api.

Taxonomies

Method Path Auth Description
GET /taxonomies Public Returns all categories, cities, associations, and delivery modes.
POST /taxonomies/:type Admin Create a taxonomy item. type = categories / cities / associations / delivery_modes.
PUT /taxonomies/:type/:id Admin Update a taxonomy item name.
DELETE /taxonomies/:type/:id Admin Delete a taxonomy item (hard delete — only used for admin-managed reference data).