API Documentation
Provider API Reference
Submit certifications for your graduates programmatically. This page covers authentication, the bulk submission endpoint, request and response schemas, and rate limits.
Authentication
All provider API requests must include your API key in theX-API-Keyheader. API keys are issued when you register as a provider. Contact [email protected] to request one.
API keys are non-transferable. Do not embed them in client-side code. Keep them in server-side environment variables.
Base URL
Bulk Submit Certifications
/api/v1/provider/bulk-submitSubmit up to 500 certification entries per request. Each entry creates (or appends to) a Meritus profile for the named student. Entries are attested under your provider account's binding declaration.
Request Body
{
"entries": [
{
"worker_email": "[email protected]",
"trade_noc_code": "7271",
"level": "Journeyperson",
"certificate_hash": "a1b2c3d4e5f6...64-char-hex-sha256",
"issued_at": "2026-03-01",
"expires_at": "2029-03-01"
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
| worker_email | string | Yes | Email of the registered worker. Must already have a Meritus account. |
| trade_noc_code | string | Yes | NOC/O*NET-SOC trade code (e.g., "7271" for carpenter). Max 10 characters. |
| level | string | Yes | Certification level (e.g., "Journeyperson", "Apprentice Level 3"). Max 50 characters. |
| certificate_hash | string | Yes | SHA-256 hash of the certificate document (64 hex characters). |
| issued_at | string | Yes | ISO 8601 date (YYYY-MM-DD) when the credential was issued. |
| expires_at | string | No | ISO 8601 date (YYYY-MM-DD) when the credential expires. Omit for non-expiring credentials. |
Success Response (200)
{
"success": true,
"data": {
"total": 1,
"created": 1,
"skipped": 0,
"errors": 0,
"results": [
{
"email": "[email protected]",
"status": "created",
"serial_number": "MER-7271-2026-A1B2C3D4"
}
]
}
}Error Response (400)
{
"success": false,
"error": "Validation failed",
"details": [
{
"type": "field",
"msg": "Invalid value",
"path": "entries[0].worker_email",
"location": "body"
}
]
}If validation fails, the request is rejected with details about which fields need correction. Fix the errors and resubmit.
Rate Limits
| Plan | Entries per batch | Monthly limit | Rate limit |
|---|---|---|---|
| Starter (Free) | 500 | 10 entries | 60 requests/minute |
| Professional ($149/mo) | 500 | 250 entries | 60 requests/minute |
| Institution ($499/mo) | 500 | 2,500 entries | 60 requests/minute |
| Enterprise (Free for institutional partners) | 500 | Unlimited | 60 requests/minute |
The rate limit is per client IP and the same on every plan. Rate limit headers are included in every response:RateLimit-RemainingandRateLimit-Reset.
Example: cURL
curl -X POST https://getmeritus.org/api/v1/provider/bulk-submit \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key-here" \
-d '{
"entries": [
{
"worker_email": "[email protected]",
"trade_noc_code": "7271",
"level": "Journeyperson",
"certificate_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"issued_at": "2026-03-01",
"expires_at": "2029-03-01"
},
{
"worker_email": "[email protected]",
"trade_noc_code": "7271",
"level": "Apprentice Level 4",
"certificate_hash": "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
"issued_at": "2026-03-01"
}
]
}'HTTP Status Codes
| Code | Description |
|---|---|
| 200 | Batch submitted successfully. All entries attested. |
| 400 | Validation failed: malformed body, invalid entry fields, or more than 500 entries. The details array lists each problem. |
| 401 | Missing or invalid X-API-Key header. |
| 403 | API key is valid but account is suspended. |
| 429 | Rate limit exceeded. Wait and retry. |
| 500 | Internal server error. Contact support if persistent. |
Need an API Key?
Contact us to register as a provider and receive your API credentials.