BlockID Portal — Docs

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.

BASEhttps://example.com/api/v1

Every response uses the same envelope, so you can handle them uniformly:

{
  "success": true,
  "code": "OK",
  "message": "Human-readable summary",
  "data": { }
}
  • success — boolean; false on 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>
Some servers strip the Authorization header. On Apache/Nginx behind PHP, make sure the header is forwarded to PHP (see Deployment → forward Authorization), or you'll get unexpected 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.

ScopeAllows
dids:readList and read DIDs.
dids:createCreate a new DID (mints an RSA-2048 keypair).
schemas:readList and read credential schemas.
schemas:createCreate a new schema.
credentials:readList and read credentials.
credentials:issueIssue a new credential.
credentials:revokeRevoke a credential.
credentials:verifyVerify a credential.
ledger:readRead ledger entries and run integrity verification.
audit:readRead 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

CodeHTTPMeaning
UNAUTHORIZED401Missing, invalid, expired, or revoked token.
FORBIDDEN403Token lacks the required scope, or cross-organization access.
NOT_FOUND404The resource doesn't exist (or isn't in your org).
METHOD_NOT_ALLOWED405Wrong HTTP method for the endpoint.
VALIDATION / INVALID_*422Request body failed validation (e.g. INVALID_DID).
RATE_LIMITED429Over 120 requests/min for this token.
DB_ERROR503Database temporarily unavailable.
SERVER_ERROR500Unexpected 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

GET/api/v1/health.php

Liveness probe. No scope required; safe to call from monitoring.

cURL
curl 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

GET/api/v1/dids.php· scope: dids:read
POST/api/v1/dids.php· scope: dids:create
GET/api/v1/did.php?id=<did>· scope: dids:read

List DIDs, create a new one (BlockID generates the did:blockid:{uuid} and RSA-2048 keypair), or fetch a single DID.

cURL — create a 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

GET/api/v1/schemas.php· scope: schemas:read
POST/api/v1/schemas.php· scope: schemas:create
cURL — create a schema
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

POST/api/v1/credentials/issue.php· scope: credentials:issue

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.

cURL
curl -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

POST/api/v1/credentials/verify.php· scope: credentials:verify

Supply a token, a credential_id, or an inline credential JSON. Returns a verdict plus per-check booleans.

cURL
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

POST/api/v1/credentials/revoke.php· scope: credentials:revoke
cURL
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

GET/api/v1/credentials/status.php?id=<credential_id>· scope: credentials:read
GET/api/v1/credentials.php· scope: credentials:read · list
cURL
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

GET/api/v1/ledger/verify.php· scope: ledger:read

Re-walks the hash chain and reports whether every record is intact — the API equivalent of Verify Ledger Integrity.

cURL
curl 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

GET/api/v1/audit.php· scope: audit:read
cURL
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 success and code, 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

  1. HTTPS everywhere

    No plaintext API calls. Verify TLS is enforced and headers are set (see Security).

  2. Authorization header forwarded

    Confirm Apache/Nginx passes Authorization to PHP (see Deployment).

  3. Least-privilege tokens

    One token per integration, minimal scopes, with expiry.

  4. Secrets stored safely

    Tokens live in a vault/secret store, not in code or env files committed to git.

  5. Backoff & retries

    Handle 429 and 503 gracefully.

  6. Monitoring

    Poll /api/v1/health.php and alert on failures.

  7. Audit review

    Regularly review token usage via the audit log.

No matching topics on this page.