REST API
Create reviews, submit evidence, and verify attestations via HTTP endpoints.
The Blanc REST API lives at /api/v1/ and supports two authentication methods:
- API key — for server-to-server calls (
Authorization: Bearer <api_key>) - Review token — for browser SDK calls (
Authorization: Bearer rt_<token>)
Create a review
Provide either document_content (the server computes the SHA-256 hash for you) or a pre-computed document_hash. Use document_content for convenience; use document_hash for privacy when you don't want the content to leave your machine.
POST /api/v1/reviews
Authorization: Bearer <api_key>
Content-Type: application/json
{
"document_content": "Full text of the AI-generated report...",
"document_title": "AI-Generated Medical Report",
"criteria_profile_id": "cp_medical_standard",
"reviewer_id": "user_456"
}Or with a pre-computed hash:
POST /api/v1/reviews
Authorization: Bearer <api_key>
Content-Type: application/json
{
"document_hash": "sha256:abc123...",
"document_title": "AI-Generated Medical Report",
"criteria_profile_id": "cp_medical_standard",
"reviewer_id": "user_456"
}Response 201:
{
"review_id": "rev_abc123",
"document_hash": "sha256:abc123...",
"status": "pending",
"criteria": {
"id": "cp_medical_standard",
"name": "Medical Document Review",
"type": "medical",
"description": "Standard medical document review criteria",
"requirements": {
"minTimeSeconds": 120,
"fullScroll": true,
"requireComment": true,
"requireEdit": false,
"presenceVerification": true,
"sectionsToAcknowledge": ["diagnosis", "treatment_plan", "risks"]
}
},
"review_token": "rt_abc123...",
"expires_at": "2026-03-16T12:00:00Z",
"created_at": "2026-03-15T12:00:00Z"
}Pass the review_token to the React SDK to start the review session in the browser.
Get review status
GET /api/v1/reviews/:id
Authorization: Bearer <api_key>Response 200:
{
"id": "rev_abc123",
"status": "completed",
"document_hash": "sha256:abc123...",
"document_title": "AI-Generated Medical Report",
"criteria": { ... },
"attestation_id": "att_xyz789",
"expires_at": "2026-03-16T12:00:00Z",
"completed_at": "2026-03-15T12:05:00Z",
"created_at": "2026-03-15T12:00:00Z"
}Submit attestation
Submit review evidence. The server validates evidence against the criteria profile and, if all requirements are met, generates a cryptographic attestation.
For action reviews, include a decision field ("approved" or "rejected"). This field is required for actions and ignored for document reviews.
POST /api/v1/reviews/:id/attestation
Authorization: Bearer <api_key>
Content-Type: application/json
{
"timeSpentSeconds": 180,
"scrollPercentage": 98.5,
"presenceVerified": true,
"sectionsAcknowledged": ["diagnosis", "treatment_plan", "risks"],
"comment": "Reviewed all sections. Treatment plan is appropriate.",
"completedAt": "2026-03-15T12:05:00Z",
"decision": "approved"
}Response 201:
{
"id": "att_xyz789",
"review_id": "rev_abc123",
"document_hash": "sha256:abc123...",
"evidence_hash": "sha256:def456...",
"signature": "ed25519:...",
"timestamp": "2026-03-15T12:05:00Z",
"evidence": { ... },
"verified": true,
"demo": false
}Error 422 if criteria not met:
{
"error": "Criteria not met",
"details": [
"Minimum time not met: 30s < 120s",
"Sections not acknowledged: risks"
]
}Verify attestation
Public endpoint — no authentication required.
GET /api/v1/attestations/:id/verifyResponse 200:
{
"valid": true,
"attestation": {
"id": "att_xyz789",
"review_id": "rev_abc123",
"document_hash": "sha256:abc123...",
"evidence_hash": "sha256:def456...",
"signature": "ed25519:...",
"timestamp": "2026-03-15T12:05:00Z",
"demo": false
},
"verification": {
"signature_valid": true,
"hash_valid": true,
"verified_at": "2026-03-15T12:10:00Z"
}
}Create action
Submit an agent action for human approval. The response includes a review_url for the human to open.
POST /api/v1/actions
Authorization: Bearer <api_key>
Content-Type: application/json
{
"action_type": "bank_transfer",
"action_params": {
"from": "acct_001",
"to": "acct_002",
"amount": 15000,
"currency": "USD"
},
"risk_level": "high",
"callback_url": "https://your-app.com/webhooks/poh"
}Request body:
| Field | Type | Required | Description |
|---|---|---|---|
action_type | string | Yes | Type of action (e.g. bank_transfer, deployment) |
action_params | object | Yes | Structured parameters for the action |
risk_level | string | No | low, medium, high, or critical. Defaults to medium. |
callback_url | string | No | URL to receive a webhook POST when the human decides |
action_context | object | No | Additional context for the reviewer |
criteria_profile_id | string | No | Criteria profile override |
reviewer_id | string | No | Assigned reviewer ID |
Response 201:
{
"action_id": "uuid-abc123",
"review_url": "https://blanc.dev/action/uuid-abc123?token=rt_abc123",
"status": "pending",
"action_type": "bank_transfer",
"risk_level": "high",
"review_token": "rt_abc123",
"expires_at": "2026-03-17T12:00:00Z",
"created_at": "2026-03-16T12:00:00Z"
}Example:
curl -X POST https://blanc.dev/api/v1/actions \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"action_type": "bank_transfer",
"action_params": {
"from": "acct_001",
"to": "acct_002",
"amount": 15000,
"currency": "USD"
},
"risk_level": "high"
}'Get action
Retrieve the status and decision for an action. The decision field is null while pending.
GET /api/v1/actions/:id
Authorization: Bearer <api_key>Response 200:
{
"id": "uuid-abc123",
"status": "completed",
"action_type": "bank_transfer",
"action_params": {
"from": "acct_001",
"to": "acct_002",
"amount": 15000,
"currency": "USD"
},
"risk_level": "high",
"callback_url": "https://your-app.com/webhooks/poh",
"document_hash": "sha256:abc123...",
"criteria": { ... },
"attestation_id": "att_xyz789",
"decision": "approved",
"expires_at": "2026-03-17T12:00:00Z",
"completed_at": "2026-03-16T12:05:00Z",
"created_at": "2026-03-16T12:00:00Z"
}Error codes
| Status | Meaning |
|---|---|
400 | Invalid request body or missing fields |
401 | Invalid or missing API key / review token |
404 | Resource not found |
409 | Review already has an attestation |
410 | Review has expired |
422 | Evidence does not meet criteria requirements |
500 | Server error |