Build on CertBoost
Bring certification practice into the tools your learners already use. Read progress, run graded quizzes, react to results in real time, and let AI agents coach learners — all with one API key.
Overview
https://certboost.xyz/api/v1. Profiles, progress, attempts, review queue and practice quizzes.
WebhooksSigned POSTs when a learner finishes an exam or a plan activates. Automatic retries.
MCP serverPlug CertBoost into Claude, ChatGPT, Cursor or your own agent as a set of tools.
Enterprise SSOOkta, Microsoft Entra ID, Google Workspace and any OpenID Connect provider.
Authentication
Create a key on the Developers page and send it as a bearer token. Keys are shown once; we store only a fingerprint.
curl https://certboost.xyz/api/v1/me \ -H "Authorization: Bearer cb_your_key"
| Key type | Acts on | Can |
|---|---|---|
| Personal, read only | Its owner | Read profile, progress, attempts, review queue, webhooks |
| Personal, read & write | Its owner | Everything above, plus run practice quizzes and manage webhooks |
| System (server config) | Any learner — pass userId | Everything, for LMS and HR integrations run by your organization |
The X-CertBoost-Key header is also accepted. Keep keys out of browsers and mobile apps; call the API from your server.
Errors & limits
Errors use standard status codes and one shape:
{ "error": { "code": "plan_required", "message": "An active CertBoost plan is required…" } }
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Missing or malformed input |
| 401 | missing_api_key, invalid_api_key | No key, or it was revoked |
| 402 | plan_required | Graded practice needs an active plan |
| 403 | insufficient_permission, forbidden | Read-only key, or another learner's data |
| 404 | not_found | No such resource (or not yours) |
| 409 | session_rejected | Practice session expired, already submitted, or belongs to someone else |
| 429 | — | Over 120 requests a minute for this key; honour Retry-After |
Endpoints
Base URL https://certboost.xyz/api/v1. Full schemas are in the OpenAPI 3.1 document.
| Path | What it does | |
|---|---|---|
| GET | /me | Name, email, plan and organization |
| GET | /certifications | Exams with practice questions (?search=) |
| GET | /progress | Averages, passing attempts, per-certification results |
| GET | /attempts | Attempt history (?certificationId=&limit=) |
| GET | /attempts/{id} | One attempt with every answer and explanation |
| GET | /review-queue | Missed questions due for review today |
| POST | /practice-sessions | Start a graded quiz (questions without answers) |
| POST | /practice-sessions/submit | Score it, record it, return explanations |
| GET | /webhooks | Your webhook endpoints |
| POST | /webhooks | Add an endpoint (returns the signing secret once) |
| PATCH | /webhooks/{id} | Change URL, events, description or pause it |
| DELETE | /webhooks/{id} | Remove an endpoint |
| POST | /webhooks/{id}/test | Send a webhook.ping |
| POST | /webhooks/{id}/rotate-secret | Issue a new signing secret |
| GET | /webhooks/{id}/deliveries | Delivery log with status codes and errors |
| POST | /webhook-deliveries/{id}/redeliver | Send a delivery again |
Run a practice quiz
Practice sessions use the same signed, single-use tokens as the web app, so a score can't be forged or submitted twice. Results land in the learner's history, review queue and challenges, and fire attempt.completed.
1. Start
curl -X POST https://certboost.xyz/api/v1/practice-sessions \
-H "Authorization: Bearer cb_your_key" -H "Content-Type: application/json" \
-d '{ "certificationId": 42, "count": 10, "mode": "adaptive" }'
// 201 Created
{
"sessionToken": "CfDJ8…",
"certificationName": "AWS Certified Developer",
"questionCount": 10, "timeLimitMinutes": 20, "passMarkPercent": 70,
"questions": [
{ "number": 1, "question": "Which service…?",
"options": [ { "letter": "A", "text": "Amazon SQS" }, { "letter": "B", "text": "Amazon SNS" } ] }
]
}
2. Submit
curl -X POST https://certboost.xyz/api/v1/practice-sessions/submit \
-H "Authorization: Bearer cb_your_key" -H "Content-Type: application/json" \
-d '{ "sessionToken": "CfDJ8…", "answers": ["B","D","A","","C","A","B","B","D","A"] }'
The response is the scored attempt: percent, passed and, per question, yourAnswer, correctAnswer and explanation.
Webhooks
Add endpoints on the Developers page or with POST /webhooks. Personal endpoints receive events about their owner only; system endpoints receive events for every learner.
| Event | When |
|---|---|
attempt.completed | A learner finishes any graded quiz, simulation, adaptive quiz, readiness check or API practice session |
subscription.activated | A paid plan becomes active |
assignment.created | An assignment is created through the LMS API |
webhook.ping | You sent a test event |
What we send
POST /hooks/certboost HTTP/1.1
Content-Type: application/json
User-Agent: CertBoost-Webhook/2.0
X-CertBoost-Event: attempt.completed
X-CertBoost-Delivery: dlv_9f2c…
X-CertBoost-Timestamp: 1761321600
X-CertBoost-Signature-256: t=1761321600,v1=5d1c…
X-CertBoost-Signature: sha256=a9b0…
{
"id": "evt_41ab…", "event": "attempt.completed", "apiVersion": "2026-10-24",
"deliveryId": "dlv_9f2c…", "occurredAt": "2026-10-24T16:00:00Z",
"data": { "attemptId": "671a…", "userId": "…", "categoryId": 42, "categoryName": "AWS Certified Developer",
"correct": 12, "total": 15, "percent": 80.0, "passed": true, "source": "main-quiz", "takenAt": "…" }
}
Respond with any 2xx within 10 seconds. Anything else is retried after 30s, 2m, 10m, 30m, 2h, 6h and 12h. An endpoint that fails five deliveries in a row is paused and flagged on your dashboard. Use deliveryId to ignore duplicates.
Verify the signature
Compute HMAC-SHA256 of timestamp + "." + raw body with your endpoint's secret and compare it to v1 in constant time. Reject timestamps more than five minutes old.
import crypto from "node:crypto";
export function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
import hmac, hashlib, time
def verify(raw_body: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > 300:
return False
expected = hmac.new(secret.encode(), f'{parts["t"]}.'.encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
static bool Verify(string rawBody, string header, string secret)
{
var parts = header.Split(',').Select(p => p.Split('=', 2)).ToDictionary(p => p[0], p => p[1]);
if (Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - long.Parse(parts["t"])) > 300) return false;
using var h = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var expected = Convert.ToHexString(h.ComputeHash(Encoding.UTF8.GetBytes(parts["t"] + "." + rawBody))).ToLowerInvariant();
return CryptographicOperations.FixedTimeEquals(Encoding.UTF8.GetBytes(expected), Encoding.UTF8.GetBytes(parts["v1"]));
}
Endpoints must be public HTTPS URLs. Private and internal network addresses are refused, and redirects are not followed.
AI agents (MCP)
CertBoost runs a remote Model Context Protocol server at https://certboost.xyz/mcp (Streamable HTTP). Any MCP client can connect with an API key and use CertBoost as tools — for example, an assistant that quizzes a learner in chat, explains their mistakes from past attempts, and tracks them against the 70% line.
claude mcp add --transport http certboost https://certboost.xyz/mcp \ --header "Authorization: Bearer cb_your_key"
| Tool | What it does |
|---|---|
list_certifications | Find exams and their ids |
get_my_profile, get_progress | Plan, averages, passing attempts, per-certification results |
list_attempts, get_attempt | History, and every answer with explanations |
get_review_queue | Missed questions due today |
start_practice_quiz, submit_practice_quiz | Run and score a graded quiz (read & write key) |
list_webhooks, create_webhook, send_test_webhook, delete_webhook | Let an agent wire up integrations |
Setup snippets for Claude Desktop, Cursor and VS Code are on the Developers page. Agents get exactly the access of the key they use.
Enterprise SSO
Organizations can sign their people in through their own identity provider using OpenID Connect — Okta, Microsoft Entra ID (Azure AD), Google Workspace, OneLogin, Auth0, JumpCloud, Ping and others.
- Learners choose Sign in with SSO or go to
https://certboost.xyz/ssoand enter their work email. - Accounts and team membership are created on first sign-in (optional).
- SSO can be required for your domains, which turns off password sign-in and sign-up for them.
- Your identity provider handles MFA and offboarding: remove someone there and they can no longer sign in.
To enable it, send your CertBoost contact the issuer URL, client ID, client secret and email domains; we'll give you the redirect URI to register.
LMS API (v1, legacy)
The earlier /api/lms/v1 endpoints (categories, users/{id}/progress, assignments, webhooks) keep working and share the same keys and webhook store. New integrations should use /api/v1.