CCW Hub Public API, version 1
The CCW Hub Public API lets Growth and Pro training organizations create, update, and sync classes programmatically, including from AI tools like Claude Code.
The Public API lets a training organization manage its classes, availability, and read its bookings programmatically. Use it to sync your schedule with another platform, power a custom site, or let an AI tool like Claude Code manage classes on your behalf.
Base URL: https://www.ccwhub.com/api/v1
The API is available on the Growth and Pro plans. Trials of an eligible plan can use it at a reduced quota while you build an integration. Every request is scoped to your own organization, so you can never read or write another organization's data.
Go to Dashboard, Settings, API Keys, then click Create Key. Give it a name and choose the scopes it needs. Copy the key when it is shown. It is displayed only once, because we store only a hash and cannot show it to you again. Keep it in a secret manager or an environment variable.
A key looks like ccwh_live_ followed by 32 hex characters. Revoke a key from the same screen. Revoked keys stop working immediately.
Send the key in the Authorization header on every request:
Authorization: Bearer ccwh_live_...Check that a key works and see your plan and quota:
curl https://www.ccwhub.com/api/v1/me \
-H "Authorization: Bearer $CCWHUB_API_KEY"A key only does what its scopes allow. Grant the least it needs.
| Scope | Grants |
|---|---|
| classes:read | List and read classes; read locations |
| classes:write | Create, update, and cancel classes |
| availability:read | Read class availability |
| availability:write | Update a class's available spots |
| bookings:read | Read bookings |
| templates:read | Read course templates |
Burst: 60 requests per minute per key. Monthly quota: counted per organization across all your keys, resetting on the 1st of each month (UTC). Every response includes X-Quota-Remaining.
| Plan or state | Monthly requests |
|---|---|
| Trial | 500 requests / month |
| Growth | 10,000 requests / month |
| Pro | 100,000 requests / month |
Use a unique Idempotency-Key header on POST and PATCH so a retried request never creates a duplicate class.
Create a class from one of your course templates at one of your locations. The response is 201 with the created class. Resolve template and location IDs first with GET /templates and GET /locations.
curl -X POST https://www.ccwhub.com/api/v1/classes \
-H "Authorization: Bearer $CCWHUB_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"courseTemplateId": "clx_template_id",
"locationId": "clx_location_id",
"title": "Michigan CPL Class",
"startTime": "2026-08-15T14:00:00.000Z",
"endTime": "2026-08-15T22:00:00.000Z",
"maxStudents": 20,
"priceOverride": 125.00,
"status": "PUBLISHED"
}'Update only the fields you want to change:
curl -X PATCH https://www.ccwhub.com/api/v1/classes/clx_class_id \
-H "Authorization: Bearer $CCWHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "PUBLISHED", "priceOverride": 149.99 }'Cancel a class with DELETE /classes/{id}. It soft-cancels the class and stops it appearing in listings. Read endpoints include GET /classes, GET /bookings, and GET /availability, all cursor-paginated with an optional since filter for incremental sync.
Every response is JSON shaped as { success, data, error, meta }. On failure, error.code is machine-readable.
| HTTP | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | The request body or query failed validation |
| 401 | MISSING_API_KEY | No Authorization: Bearer header |
| 401 | INVALID_API_KEY | The key does not exist |
| 401 | KEY_REVOKED | The key was revoked |
| 401 | KEY_EXPIRED | The key passed its expiry date |
| 403 | API_NOT_AVAILABLE | The plan does not include API access (needs Growth or Pro) |
| 403 | SUBSCRIPTION_REQUIRED | No active subscription (past due, cancelled, or expired trial) |
| 403 | INSUFFICIENT_SCOPE | The key lacks a required scope |
| 404 | NOT_FOUND | No such class in your organization |
| 409 | IDEMPOTENCY_MISMATCH | Same idempotency key, different body |
| 429 | RATE_LIMIT_EXCEEDED | More than 60 requests in a minute |
| 429 | QUOTA_EXCEEDED | Monthly quota used up |
You can point your own Claude Code (or any agent) at this API. Give it the key as an environment variable and the base URL, then let it drive the endpoints. Keep the key out of your prompts and logs; pass it only through the Authorization header.
export CCWHUB_API_KEY="ccwh_live_..."Then ask it to, for example, list your templates and locations and publish a recurring Saturday class for next month. The agent resolves IDs with GET /templates and GET /locations, then calls POST /classes once per date with a unique Idempotency-Key.
Need higher volume or help wiring up an integration? Pro includes a larger quota and priority support. Contact us.