API Guide
The BlockID REST API lets you automate everything in the dashboard — minting DIDs, defining schemas, issuing, verifying, and revoking credentials, and reading the ledger and audit logs. All requests are authenticated with a Bearer token and return a consistent JSON envelope.
Base URL & envelope
All endpoints live under /api/v1. Examples here use https://example.com as the base — replace it with your own host.
Every response uses the same envelope, so you can handle them uniformly:
{
"success": true,
"code": "OK",
"message": "Human-readable summary",
"data": { }
}
success— boolean;falseon any error.code— a stable machine-readable string (see error codes).message— a short description, safe to log.data— the payload (object or array); empty{}on errors.
Authentication
Send your token in the Authorization header on every request:
Authorization: Bearer <token>
401s.Creating tokens
Tokens are created in the dashboard under API Management by an Org Admin or Super Admin. They are:
- Shown once. Stored server-side only as a SHA-256 hash — copy it immediately.
- Scoped to one organization. A token can only ever touch its own org's data.
- Scope-limited. You choose exactly which actions it may perform.
- Expirable and revocable. Set an expiry and revoke instantly if leaked.
- Rate-limited and logged. 120 requests/min; every call is recorded for audit.
Scopes
Grant a token only the scopes it needs.
| Scope | Allows |
|---|---|
dids:read | List and read DIDs. |
dids:create | Create a new DID (mints an RSA-2048 keypair). |
schemas:read | List and read credential schemas. |
schemas:create | Create a new schema. |
credentials:read | List and read credentials. |
credentials:issue | Issue a new credential. |
credentials:revoke | Revoke a credential. |
credentials:verify | Verify a credential. |
ledger:read | Read ledger entries and run integrity verification. |
audit:read | Read audit-log entries. |
Rate limits
Each token is limited to 120 requests per minute. Exceeding it returns 429 RATE_LIMITED. Back off and retry after a short pause; batch where you can.
Error codes
| Code | HTTP | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | Missing, invalid, expired, or revoked token. |
FORBIDDEN | 403 | Token lacks the required scope, or cross-organization access. |
NOT_FOUND | 404 | The resource doesn't exist (or isn't in your org). |
METHOD_NOT_ALLOWED | 405 | Wrong HTTP method for the endpoint. |
VALIDATION / INVALID_* | 422 | Request body failed validation (e.g. INVALID_DID). |
RATE_LIMITED | 429 | Over 120 requests/min for this token. |
DB_ERROR | 503 | Database temporarily unavailable. |
SERVER_ERROR | 500 | Unexpected server error (no stack trace is leaked). |
Endpoints
Each endpoint below lists its method, path, required scope, and copy-paste examples in four forms: cURL, JavaScript (fetch), PHP (cURL), and a Postman setup as plain text.
Health check
Liveness probe. No scope required; safe to call from monitoring.
cURLcurl https://example.com/api/v1/health.php
JavaScript (fetch)
const r = await fetch("https://example.com/api/v1/health.php"); console.log(await r.json());
PHP (cURL)
$ch = curl_init("https://example.com/api/v1/health.php"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); echo curl_exec($ch); curl_close($ch);
Postman
Method: GET URL: https://example.com/api/v1/health.php Auth: none
DIDs — list & create
List DIDs, create a new one (BlockID generates the did:blockid:{uuid} and RSA-2048 keypair), or fetch a single DID.
curl -X POST https://example.com/api/v1/dids.php -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"label":"Acme University issuer"}'
JavaScript (fetch) — create a DID
const r = await fetch("https://example.com/api/v1/dids.php", { method: "POST", headers: { "Authorization": `Bearer ${TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ label: "Acme University issuer" }) }); console.log(await r.json());
PHP (cURL) — create a DID
$ch = curl_init("https://example.com/api/v1/dids.php"); curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>["Authorization: Bearer $token","Content-Type: application/json"], CURLOPT_POSTFIELDS=>json_encode(["label"=>"Acme University issuer"])]); echo curl_exec($ch); curl_close($ch);
Postman — create a DID
Method: POST URL: https://example.com/api/v1/dids.php Auth: Bearer Token = {{token}} Body: raw/JSON = {"label":"Acme University issuer"}
Example response
{ "success": true, "code": "CREATED", "message": "DID created", "data": { "did": "did:blockid:7c9e6679-7425-40de-944b-e07fc1f90ae7", "key_type": "RSA-2048", "created_at": "2026-06-25T10:00:00Z" } }
Schemas — list & create
curl -X POST https://example.com/api/v1/schemas.php -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"name":"Course Completion","fields":[{"key":"fullName","type":"string"},{"key":"course","type":"string"},{"key":"completedOn","type":"date"}]}'
JavaScript (fetch)
const r = await fetch("https://example.com/api/v1/schemas.php", { method: "POST", headers: { "Authorization": `Bearer ${TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ name: "Course Completion", fields: [{ key: "fullName", type: "string" }] }) }); console.log(await r.json());
PHP (cURL)
$ch = curl_init("https://example.com/api/v1/schemas.php"); curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>["Authorization: Bearer $token","Content-Type: application/json"], CURLOPT_POSTFIELDS=>json_encode(["name"=>"Course Completion","fields"=>[["key"=>"fullName","type"=>"string"]]])]); echo curl_exec($ch); curl_close($ch);
Postman
Method: POST URL: https://example.com/api/v1/schemas.php Auth: Bearer {{token}} Body raw/JSON = {"name":"Course Completion","fields":[{"key":"fullName","type":"string"}]}
Issue a credential
Signs a new credential against a DID and schema for a holder, computing the SHA-256 hash and RSA-SHA256 signature and writing a ledger entry.
cURLcurl -X POST https://example.com/api/v1/credentials/issue.php -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"did":"did:blockid:7c9e6679-7425-40de-944b-e07fc1f90ae7","schema_id":"sch_courses","holder_email":"alex@example.com","claims":{"fullName":"Alex Rivera","course":"Workplace Safety","completedOn":"2026-06-25"},"expires_at":"2027-01-31"}'
JavaScript (fetch)
const r = await fetch("https://example.com/api/v1/credentials/issue.php", { method: "POST", headers: { "Authorization": `Bearer ${TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ did: "did:blockid:7c9e...", schema_id: "sch_courses", holder_email: "alex@example.com", claims: { fullName: "Alex Rivera", course: "Workplace Safety" }, expires_at: "2027-01-31" }) }); console.log(await r.json());
PHP (cURL)
$ch = curl_init("https://example.com/api/v1/credentials/issue.php"); curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>["Authorization: Bearer $token","Content-Type: application/json"], CURLOPT_POSTFIELDS=>json_encode(["did"=>"did:blockid:7c9e...","schema_id"=>"sch_courses","holder_email"=>"alex@example.com","claims"=>["fullName"=>"Alex Rivera"],"expires_at"=>"2027-01-31"])]); echo curl_exec($ch); curl_close($ch);
Postman
Method: POST URL: https://example.com/api/v1/credentials/issue.php Auth: Bearer {{token}} Body raw/JSON = {"did":"did:blockid:7c9e...","schema_id":"sch_courses","holder_email":"alex@example.com","claims":{"fullName":"Alex Rivera"},"expires_at":"2027-01-31"}
Example response
{ "success": true, "code": "CREATED", "message": "Credential issued", "data": { "credential_id": "CRD-4821", "verification_token": "VTKN-9F2A-7C13-A0E5", "hash": "sha256:9b2c...", "signature": "RSA-SHA256:...", "expires_at": "2027-01-31" } }
Verify a credential
Supply a token, a credential_id, or an inline credential JSON. Returns a verdict plus per-check booleans.
curl -X POST https://example.com/api/v1/credentials/verify.php -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"token":"VTKN-9F2A-7C13-A0E5"}'
JavaScript (fetch)
const r = await fetch("https://example.com/api/v1/credentials/verify.php", { method: "POST", headers: { "Authorization": `Bearer ${TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ token: "VTKN-9F2A-7C13-A0E5" }) }); console.log(await r.json());
PHP (cURL)
$ch = curl_init("https://example.com/api/v1/credentials/verify.php"); curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>["Authorization: Bearer $token","Content-Type: application/json"], CURLOPT_POSTFIELDS=>json_encode(["token"=>"VTKN-9F2A-7C13-A0E5"])]); echo curl_exec($ch); curl_close($ch);
Postman
Method: POST URL: https://example.com/api/v1/credentials/verify.php Auth: Bearer {{token}} Body raw/JSON = {"token":"VTKN-9F2A-7C13-A0E5"}
Example response
{ "success": true, "code": "OK", "message": "Verification complete", "data": { "verdict": "VALID", "credential_id": "CRD-4821", "checks": { "signature_valid": true, "hash_matches": true, "issuer_known": true, "revoked": false, "expired": false } } }
Possible verdicts: VALID, EXPIRED, REVOKED, TAMPERED, UNKNOWN_ISSUER, NOT_FOUND (see the Verifier Guide).
Revoke a credential
curl -X POST https://example.com/api/v1/credentials/revoke.php -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"credential_id":"CRD-4821","reason":"Issued in error"}'
JavaScript (fetch)
const r = await fetch("https://example.com/api/v1/credentials/revoke.php", { method: "POST", headers: { "Authorization": `Bearer ${TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ credential_id: "CRD-4821", reason: "Issued in error" }) }); console.log(await r.json());
PHP (cURL)
$ch = curl_init("https://example.com/api/v1/credentials/revoke.php"); curl_setopt_array($ch, [CURLOPT_POST=>true, CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>["Authorization: Bearer $token","Content-Type: application/json"], CURLOPT_POSTFIELDS=>json_encode(["credential_id"=>"CRD-4821","reason"=>"Issued in error"])]); echo curl_exec($ch); curl_close($ch);
Postman
Method: POST URL: https://example.com/api/v1/credentials/revoke.php Auth: Bearer {{token}} Body raw/JSON = {"credential_id":"CRD-4821","reason":"Issued in error"}
Credential status
curl "https://example.com/api/v1/credentials/status.php?id=CRD-4821" -H "Authorization: Bearer $TOKEN"
JavaScript (fetch)
const r = await fetch("https://example.com/api/v1/credentials/status.php?id=CRD-4821", { headers: { "Authorization": `Bearer ${TOKEN}` } }); console.log(await r.json());
PHP (cURL)
$ch = curl_init("https://example.com/api/v1/credentials/status.php?id=CRD-4821"); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>["Authorization: Bearer $token"]]); echo curl_exec($ch); curl_close($ch);
Postman
Method: GET URL: https://example.com/api/v1/credentials/status.php?id=CRD-4821 Auth: Bearer {{token}}
Ledger integrity
Re-walks the hash chain and reports whether every record is intact — the API equivalent of Verify Ledger Integrity.
cURLcurl https://example.com/api/v1/ledger/verify.php -H "Authorization: Bearer $TOKEN"
JavaScript (fetch)
const r = await fetch("https://example.com/api/v1/ledger/verify.php", { headers: { "Authorization": `Bearer ${TOKEN}` } }); console.log(await r.json());
PHP (cURL)
$ch = curl_init("https://example.com/api/v1/ledger/verify.php"); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>["Authorization: Bearer $token"]]); echo curl_exec($ch); curl_close($ch);
Postman
Method: GET URL: https://example.com/api/v1/ledger/verify.php Auth: Bearer {{token}}
Example response
{ "success": true, "code": "OK", "message": "Ledger intact", "data": { "intact": true, "records_checked": 5821, "last_hash": "sha256:c1d4..." } }
Audit log
curl "https://example.com/api/v1/audit.php?limit=50" -H "Authorization: Bearer $TOKEN"
JavaScript (fetch)
const r = await fetch("https://example.com/api/v1/audit.php?limit=50", { headers: { "Authorization": `Bearer ${TOKEN}` } }); console.log(await r.json());
PHP (cURL)
$ch = curl_init("https://example.com/api/v1/audit.php?limit=50"); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_HTTPHEADER=>["Authorization: Bearer $token"]]); echo curl_exec($ch); curl_close($ch);
Postman
Method: GET URL: https://example.com/api/v1/audit.php?limit=50 Auth: Bearer {{token}}
Security best practices
- Store tokens in a secrets manager — never in source control or client-side code.
- Use the narrowest scopes a token needs; create separate tokens per integration.
- Set expiries and rotate tokens on a schedule.
- Always use HTTPS so the Bearer token is never sent in clear text.
- Handle the envelope uniformly — branch on
successandcode, not HTTP status alone. - Respect rate limits — implement backoff on
429. - Revoke immediately if a token is exposed; check the audit log for misuse.
Production API checklist
HTTPS everywhere
No plaintext API calls. Verify TLS is enforced and headers are set (see Security).
Authorization header forwarded
Confirm Apache/Nginx passes
Authorizationto PHP (see Deployment).Least-privilege tokens
One token per integration, minimal scopes, with expiry.
Secrets stored safely
Tokens live in a vault/secret store, not in code or env files committed to git.
Backoff & retries
Handle
429and503gracefully.Monitoring
Poll
/api/v1/health.phpand alert on failures.Audit review
Regularly review token usage via the audit log.