Research prototype. Synthetic data and simulated payments only — not an official or production security service. Limitations

Developers

API reference

All JSON is snake_case; timestamps are ISO-8601 UTC; errors use a single envelope.
{ "error": { "code": "release_blocked", "message": "Release refused: the payment is HELD…", "details": {} } }

Public verification API

MethodPathDescription
POST/api/v1/verify/receiptVerify a receipt. Body: receipt, content?, intended_action?, audience?. No side effects except an attempt log visible to the issuer. 60/min/IP.
GET/api/v1/issuersDemo trust registry: issuers, status and public JWKs. Also at /.well-known/tumaini-trust-registry.json.
POST/api/v1/verify/evidenceVerify a signed case-evidence report (JWS). 30/min/IP.
GET/api/v1/evidence-keysPublic keys used to sign evidence reports.
POST/api/v1/sandbox/receiptIssue a 1-hour sandbox receipt from Falcon Demo Bank (fictional). 10/min/IP.
GET/api/healthService health: database, media service (model, C2PA) and contextual-analysis state.
GET/api/context/statusContextual-analysis capability state: disabled | not_configured | configured_not_enabled | ready. Never exposes credentials.

Consumer API (session cookie)

State-changing requests must be same-origin. Rate limit: 120 mutations/min per workspace.

MethodPathDescription
POST/api/sessionCreate or resume an anonymous isolated demo workspace (httpOnly cookie).
GET/POST/api/casesList / create verification cases.
GET/api/cases/{id}Full case: assets, analyses, provenance, actions, challenges, timeline.
POST/api/cases/{id}/mediaUpload audio/image/video (multipart, ≤ 4 MB).
POST/api/cases/{id}/receiptAttach and verify a signed authorisation.
POST/api/cases/{id}/assessRe-run extraction and risk policy.
POST/api/cases/{id}/decisionRecord the final decision.
GET/api/cases/{id}/reportSigned evidence report (?download=1).
POST/api/actionsCreate a protected (simulated) payment. idempotency_key required.
POST/api/actions/{id}/challengeSend verification to a pre-registered trusted contact.
POST/api/actions/{id}/releaseRelease — refused unless VERIFIED and all checks satisfied.
POST/api/actions/{id}/cancelCancel.
POST/api/challenges/respondContact's answer, authenticated by one-time token.
GET/POST/api/trusted-contactsList / add trusted contacts.
GET/POST/api/reportsList / file impersonation reports.
POST/api/context/analyzeContextual analysis (Gemini adapter). JSON {text, consent: true, claimed_sender?, locale?, case_id?} or multipart with file. Requires consent; 503 context_unavailable until enabled; 10/hour/workspace.
POST/api/demo/scenarios/{key}family-voice | government-notice | bank-payment | tampered-request | ai-outage | child-message (?lang=ar).
POST/api/demo/resetReset the caller's workspace only.

Institution API (institution session)

POST /api/institution/login, /overview, /keys, /keys/{kid}/revoke, /communications, /communications/{id}/revoke, /verifications, /incidents, /audit, /c2pa/sign. Key generation, revocation, payment requests and C2PA signing require the admin role.

Contextual analysis response

Returned only when the capability is enabled. Observations are signals, never proof; assessment_with_context is computed by a function that can only add caution and is never saved.

{ "status": "completed", "role": "contextual_signal", "provider": "gemini", "model": "<configured>",
  "observation": { "summary": "…", "claimed_identity": { "name": "Falcon Bank", "type": "institution" },
    "requests": [ { "kind": "payment", "detail": "AED 150 fee" } ], "urls": ["…"], "urgency": true,
    "secrecy": false, "indicators": [ … ], "explanation": { "en": "…", "ar": "…" }, "confidence": "medium" },
  "usage": { "input_tokens": 420, "output_tokens": 180, "estimated_cost_usd": 0.0006 },
  "redactions": { "card": 0, "iban": 0, "code": 1, "email": 0 }, "assessment_with_context": null }

Webhooks

Not implemented. Planned: signed callbacks for verification outcomes and incident reports.

Error codes

HTTPCodes
400invalid_request, invalid_json, unsupported_media, invalid_upload
401no_session, no_institution_session, invalid_credentials
403cross_origin, forbidden
404case_not_found, action_not_found, contact_not_found, invalid_token
409invalid_transition, checks_unsatisfied, release_blocked, guard_rejected, contact_not_pre_established, challenge_closed, case_closed
410challenge_expired
413file_too_large, payload_too_large
422provider_blocked (contextual analysis)
429rate_limited
502/503/504context_unavailable, provider_timeout, provider_unreachable, provider_auth_failed, provider_invalid_response
500internal_error (no internal details are returned)