Developers
Training School API
Contract-backed training school API reference generated from the same OpenAPI document the application serves.
Overview
Contract reference
Generated from the same OpenAPI document the application serves. Default environment is sandbox; switching to production requires an intentional opt-in.
| Field | Value |
|---|---|
| Source | generated-openapi-prefix-parity |
| Sandbox key prefix | arcv_sandbox_ |
| Production key prefix | arcv_live_ |
| Sandbox base URL | https://arcova_ai.test/api/v1 |
| Production base URL | https://arcova_ai.test/api/v1 |
Only switch to production credentials after sandbox validation and response-shape verification pass.
Setup
Authentication headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer arcv_sandbox_your_key | Yes |
Accept | application/json | Yes |
X-Idempotency-Key | sandbox-request-001 | No |
Endpoint
Verify certificate
/api/v1/training-school/certificates/verify/{certificateNumber}Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
certificateNumber | string | Yes |
Success response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/certificates/verify/{certificateNumber}" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/certificates/verify/{certificateNumber}" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
List enrollable classes
/api/v1/training-school/classesSuccess response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/classes" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/classes" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
Get class detail
/api/v1/training-school/classes/{classId}Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
classId | integer | Yes |
Success response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/classes/{classId}" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/classes/{classId}" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
List courses
/api/v1/training-school/coursesSuccess response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/courses" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/courses" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
Get enrollment detail
/api/v1/training-school/enrollments/{enrollmentUuid}Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
enrollmentUuid | string | Yes |
Success response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/enrollments/{enrollmentUuid}" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/enrollments/{enrollmentUuid}" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
Cancel enrollment
/api/v1/training-school/enrollments/{enrollmentUuid}/cancelRequest parameters
| Name | Type | Required | Description |
|---|---|---|---|
enrollmentUuid | string | Yes | |
reason | string|null | No | Human-readable reason for the cancellation. Stored on the enrollment record and included in the student notification email. |
Success response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X POST "https://arcova_ai.test/api/v1/training-school/enrollments/{enrollmentUuid}/cancel" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X POST "https://arcova_ai.test/api/v1/training-school/enrollments/{enrollmentUuid}/cancel" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
Get enrollment payment info
/api/v1/training-school/enrollments/{enrollmentUuid}/paymentRequest parameters
| Name | Type | Required | Description |
|---|---|---|---|
enrollmentUuid | string | Yes |
Success response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/enrollments/{enrollmentUuid}/payment" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/enrollments/{enrollmentUuid}/payment" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
Register student to class
/api/v1/training-school/registrationsRequest parameters
| Name | Type | Required | Description |
|---|---|---|---|
class_id | integer | Yes | Target class identifier from the list classes endpoint. Must belong to the API key's school. |
student_id | integer | Yes | Student identifier from the create-or-find student endpoint. Must belong to the API key's school. |
payment_method | string|null | No | How the student will pay. `card` (default) generates a Stripe checkout link. `cash` and `check` record an offline payment intent. |
payment_link_type | string|null | No | Controls the generated payment URL amount. `auto` (default) uses the deposit amount when configured, otherwise the full balance. `deposit` forces a deposit-only payment link and fails if no deposit is configured. `full` forces a full-balance checkout, ignoring any deposit setting. |
payment_amount | number|null | No | Explicit payment amount for non-card registration flows. Ignored when `payment_method` is `card`. |
payment_reference | string|null | No | External reference for offline payments (e.g., check number or cash receipt ID). |
discount_code | string|null | No | Discount code to apply to the enrollment invoice. Returns a validation error if the code is invalid or expired. |
notes | string|null | No | Free-text registration notes visible to school admins. |
Success response
200 — Successful response
Sandbox curl
curl -X POST "https://arcova_ai.test/api/v1/training-school/registrations" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X POST "https://arcova_ai.test/api/v1/training-school/registrations" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
Create or find student
/api/v1/training-school/studentsRequest parameters
| Name | Type | Required | Description |
|---|---|---|---|
first_name | string | Yes | Student's first name. |
last_name | string | Yes | Student's last name. |
email | string | Yes | Student's email address. Used for idempotent matching — if a student with this email already exists in the school, the existing record is returned instead of creating a duplicate. Case-insensitive. |
phone | string|null | No | Student's phone number. |
Success response
200 — Successful response
Sandbox curl
curl -X POST "https://arcova_ai.test/api/v1/training-school/students" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X POST "https://arcova_ai.test/api/v1/training-school/students" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
Get student detail
/api/v1/training-school/students/{studentId}Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
studentId | integer | Yes |
Success response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/students/{studentId}" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/students/{studentId}" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
List student certificates
/api/v1/training-school/students/{studentId}/certificatesRequest parameters
| Name | Type | Required | Description |
|---|---|---|---|
studentId | integer | Yes |
Success response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/students/{studentId}/certificates" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/students/{studentId}/certificates" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Endpoint
List student enrollments
/api/v1/training-school/students/{studentId}/enrollmentsRequest parameters
| Name | Type | Required | Description |
|---|---|---|---|
studentId | integer | Yes |
Success response
200 — Successful response
Fields: datameta
Sandbox curl
curl -X GET "https://arcova_ai.test/api/v1/training-school/students/{studentId}/enrollments" \
-H "Authorization: Bearer arcv_sandbox_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Production curl (intentional switch only)
Only switch to production credentials after sandbox validation and response-shape verification pass.
curl -X GET "https://arcova_ai.test/api/v1/training-school/students/{studentId}/enrollments" \
-H "Authorization: Bearer arcv_live_your_key" \
-H "Accept: application/json" \
-H "X-Idempotency-Key: sandbox-request-001"Common failures
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key. |
| 403 | API key scope does not allow this operation. |
Reference
Error response format
All error responses follow a consistent shape with an error code, message, and optional detail.
{
"error": {
"code": "invalid_api_key",
"message": "The provided API key is invalid or has been revoked.",
"detail": "Key arcv_sbx_abc123 was revoked at 2024-01-15T10:30:00Z"
}
}Status codes
| Status | Code | Meaning | Action |
|---|---|---|---|
| 401 | invalid_api_key | Key revoked or malformed | Regenerate key |
| 403 | insufficient_scope | Missing permission | Add scope to key |
| 404 | not_found | Resource does not exist | Check resource ID |
| 422 | validation_error | Request body invalid | Check error.detail |
| 429 | rate_limited | Too many requests | Implement backoff |
| 500 | internal_error | Server error | Retry with backoff |
Reference
Pagination
List endpoints return paginated results with page-based navigation.
GET /api/v1/incidents?page=1&per_page=15
Response:
{
"data": [...],
"meta": {
"current_page": 1,
"per_page": 15,
"total": 100,
"last_page": 7
},
"links": {
"first": "/api/v1/incidents?page=1",
"last": "/api/v1/incidents?page=7",
"next": "/api/v1/incidents?page=2",
"prev": null
}
}page(query) — Page number, default 1.per_page(query) — Items per page, default 15, max 100.
Reference
Rate limiting
All endpoints are rate limited per API key. The default limit is 60 requests per minute and may vary by endpoint.
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1700000060When rate limited, the API returns HTTP 429 with a retry_after value in seconds.