CertVerify
Platform guide API guide Certificate guide ← Back to portal

API Reference

Complete guide to CertVerify's REST API for certificate verification, learner authentication, and admin operations.

Verification

Public endpoints for verifying certificates and generating share links.

GET /api/verify/:certId

Verify a certificate's authenticity and retrieve its details. Public endpoint — no authentication required.

Parameters

NameTypeDescription
certIdstringHMAC-protected certificate ID (e.g., CV-ELT-202606-dHtBMxjI-d40a1a4d)

Response

{
  "certId": "CV-ELT-202606-dHtBMxjI-d40a1a4d",
  "holderName": "Jane Smith",
  "courseName": "English Learning Course 2026",
  "platform": "ELT",
  "issuedAt": "2026-06-27T01:05:00Z",
  "expiresAt": "2027-06-27T01:05:00Z",
  "score": 92,
  "passMark": 70,
  "revoked": false,
  "verified": true
}

Authentication & Signup

Learner authentication endpoints for the external user signup flow.

POST /api/auth/otp-send

Send a 6-digit OTP code to verify certificate email. Rate limited: max 3 per email per hour.

Request Body

FieldType
emailstringRequired Work/school email to verify

Response

{
  "otpToken": "uid_1719443450000",
  "otpCode": "123456"  // Returned only if Resend email fails (fallback for testing)
}
If Resend email service is not configured, the OTP code is displayed on-screen. In production, it's sent via email only.
POST /api/auth/otp-verify

Verify the OTP code sent to the user's email. Valid for 10 minutes. Max 5 failed attempts before account deletion.

Request Body

FieldType
otpTokenstringRequired Token from otp-send response
codestringRequired 6-digit code entered by user

Response

{
  "success": true
}
POST /api/auth/signup-complete

Complete learner signup and create account with certificate email & preferences. Called after OTP verification succeeds.

Request Body

FieldType
certificateEmailstringRequired Verified work/school email
preferencesobjectRequired
preferences.productUpdatesbooleanOpt-in to product updates
preferences.courseUpdatesbooleanOpt-in to course updates

Response

{
  "success": true
}

Errors

StatusError CodeMeaning
403account_suspendedAccount has been suspended by admin
403Certificate email not verifiedOTP verification not completed
POST /api/auth/check-suspension

Check if the current user's account is suspended. Called immediately after Firebase login to block access for suspended users.

Response

{
  "suspended": false  // true if account is suspended
}
This endpoint is called after Firebase OAuth/email signup to prevent suspended users from proceeding past login.

Admin Management

Protected endpoints (admin role required) for managing external learner accounts.

PATCH /api/admin/external-users/:uid/status

Suspend or reactivate a learner account. Suspended users cannot login or access certificates.

Request Body

FieldType
statusstringRequired "active" or "suspended"

Response

{
  "success": true
}
DELETE /api/admin/external-users/:uid

Permanently delete a learner account and all associated data. This action is irreversible.

Response

{
  "success": true
}
Deletion removes the Firebase Auth user, Firestore external user record, and all related certificate access.
POST /api/admin/external-users/export

Export opted-in learners as CSV for email campaigns. Only includes users who consented to updates.

Response

Content-Type: text/csv

Email,Joined,Preferences
user@gmail.com,2026-06-28T19:00:00Z,"Product Updates, Course Updates"
another@school.edu,2026-06-27T15:30:00Z,"Course Updates"

Error Handling

All endpoints return standard HTTP status codes. Error responses include an error field:

{
  "error": "error_code",
  "detail": "Human-readable error message"
}

Common errors:

  • 401 missing_token — Authorization header missing
  • 401 invalid_token — Firebase token verification failed
  • 403 forbidden — User lacks required role
  • 403 account_suspended — Learner account is suspended
  • 404 not_found — Certificate or resource not found
  • 429 too_many_requests — Rate limit exceeded
  • 500 server_error — Internal server error