Skip to content
Decision-Evidence Operating System

Developers

Integrating against a reference that drifts from what actually answers is a rewrite waiting to happen.

This page lists exactly what answers on the wire today, each with the repository path it is observed at. Nothing here is a roadmap wearing a reference's clothes.

The one public endpoint

One HTTP endpoint is served on the public domain today: the demo-booking form’s handler. It accepts form-encoded or multipart submissions and answers with a reference you can quote back at us.

POST https://honestas.ai/api/demo
Content-Type: application/x-www-form-urlencoded   (multipart/form-data also accepted)

email=…&org=…&question=…
intent=demo|assessment|paper|tier   &intentLabel=…   &assessment=1

200 OK
{ "reference": "DEMO-9C41AE", "messageId": "…" }

The reference is "DEMO-" plus the first six hex characters of an HMAC-SHA256 (key honestas-demo-ref) over email|org|YYYY-MM-DD, upper-cased — deterministic per email and organisation per UTC day, so resubmitting the form returns the same reference. The idempotency is by construction, not by a stored deduplication table. Recompute it yourself: the key and the seed are both above, and the answer should match the one we sent you character for character.

intent is what the visitor came for, declared rather than inferred: one of demo, assessment, paper or tier. An unrecognised or absent value falls back to assessment if the compatibility field below is set and to demo otherwise — never to an invented label. intentLabel is the free-text thing being asked for (the document title, the pricing tier), truncated to 200 characters. Both exist because the operator inbox previously received every submission subject-lined as a booking, so a person who asked for a document was answered about a meeting. assessment=1 is the older boolean form of intent=assessment. It is still read, and still posted by our own form, so a build of the server that predates intent keeps working. It is a compatibility field, not a second contract: where both are present, intent wins.

Machine codes served by the demo endpoint
CodeStatusWhen
INVALID_SUBMISSION400a required field is missing or malformed
EMAIL_CONFIG_MISSING500the sending credential is not configured — the submission is refused, not queued
OPERATOR_EMAIL_NOT_CONFIGURED500no operator inbox is configured to receive it
RESEND_API_FAILED502the delivery provider answered with a failure
RESEND_PARSE_ERROR502the delivery provider answered with something unparseable
UNEXPECTED_ERROR500anything else — still typed, never a bare stack trace

Every failure body is { error, code, message, troubleshooting[] } — a code a machine can branch on and steps a person can follow, in the same response. The steps a visitor receives are visitor-safe by construction: operator detail — env var names, secret locations, the provider’s raw error body — goes to the server log, never over the wire. A page arguing for evidence integrity does not hand strangers the path to its own credentials.

the demo endpoint(shipped)honestas-marketing/src/app/api/demo/route.ts

The console plane is deliberately not internet-reachable

The console at app.honestas.ai proxies /api/bff/* to a backend that runs in-cluster and is not reachable from the internet — its deployment manifest carries no Gateway and no VirtualService, and says so. The proxy forwards only the authorization, content-type and accept headers, and never attaches a service credential of its own — a request that arrives unauthenticated leaves unauthenticated.

Route policy is a build gate, not a convention: every /api/ route must register the scope middleware, and only /healthz and /readyz are exempt — by exact path, not by prefix.

the console proxy(shipped)honestas/src/app/api/bff/[...path]/route.tsthe route-policy gate(shipped)honestas-bff/src/server.ts

Refusals are typed

A refusal is a machine code and a verbose message, never a placeholder value and never a silently widened read. Every code below is served on the wire today.

Refusal codes served by the console backend today
CodeStatusWhat it means
AUTH_MISSING · AUTH_SCHEME401no Authorization header, or a scheme other than Bearer
JWT_MALFORMED · JWT_BAD_HEADER · JWT_ALG_UNSUPPORTED · JWT_SIGNATURE_INVALID · JWT_BAD_PAYLOAD401the token fails structural or signature verification — each failure names its exact stage
JWT_EXPIRED · JWT_NOT_YET_VALID401the token is outside its validity window
JWT_SUBJECT_INVALID · JWT_ORG_INVALID401the subject or organisation claim does not resolve to a usable identity
SCOPE_PREDICATE_MISSING403the tenant/owner predicate cannot be resolved — the body carries resolved[], missing[] and troubleshooting[] rather than guessing an id
CAPABILITY_NOT_BUILT501a real, scoped, verified route whose capability is designed and not built — it says so, instead of returning an empty list that looks like data
UNO_DISPATCH_FAILED · UNO_RESPONSE_UNPARSEABLE · UNO_UNREACHABLE502the outbound dispatch to the platform orchestrator failed, and the failure mode is named
DEADLINE_EXCEEDED504the bounded 20-second dispatch deadline elapsed — bounded by design, never an unbounded wait
ROUTE_NOT_FOUND404no such route behind the proxy — typed like every other refusal

The console itself renders five further states that never travel on the wire: NOT_SIGNED_IN, SESSION_REJECTED, BFF_UNREACHABLE, GRANT_PROVENANCE_MISSING (a ledger write with no resolvable grantor — the console refuses to offer the control at all) and FAULT_HTTP (an HTTP answer outside every contracted shape, named by its status; its verdict word is FAULT, not REFUSED, because nothing refused anything).

the dispatch refusals(shipped)honestas-bff/src/lib/uno.tsthe scope refusal(shipped)honestas-bff/src/lib/scope.tsthe auth refusals(shipped)@adverant/auth-middleware

The session shape, honestly

A signed-in console session can read its own resolved scope back. The response states what the platform actually minted — including the axis it does not mint yet.

GET /api/v1/session            (behind the console proxy; signed-in only)

200 OK
{
  "scope":    { "tenant": "…", "owner": "…", "unit": null },
  "identity": { "userId": "…", "email": "…", "organizationId": "…",
                "organizationSlug": "…", "roles": [ … ], … },
  "axes":     { … }
}

The unit axis is honest about its own state: the platform mints no business_unit_id claim yet, and the response says so rather than inventing one. An axis that cannot be resolved is reported as unresolved, never filled with a placeholder.

the session route(shipped)honestas-bff/src/routes/session.ts

Dispatch is outbound, not offered

There is no public dispatch endpoint on any honestas domain. All compute dispatch is outbound — from the console backend to the platform orchestrator, in-cluster. The one dispatch a signed-in caller can trigger today is an echo: a real tier-1 round trip through the orchestrator and back, which exists so the seam can be proven live rather than asserted.

POST /api/v1/dispatch/echo     (behind the console proxy; signed-in only)

200 OK
{ "ok": true, "tier": 1, "dispatchId": "…", "result": { … } }

— or the UNO_DISPATCH_FAILED / UNO_RESPONSE_UNPARSEABLE / UNO_UNREACHABLE
  refusals from the table above, verbatim.

the echo dispatch(shipped)honestas-bff/src/routes/console.ts

The full ladder — how a dispatch is tiered, routed to a model and turned into evidence — is laid out on the architecture page.

Agent-to-agent

Conformance platform endpoint(shipped)ROS/src/routes/public/beacon-agent-public.ts

The conformant A2A v0.3.0 endpoint and its executable conformance suite live in the platform repository — it is a platform endpoint, and no honestas repository serves an A2A endpoint on a honestas domain today.

the conformance suite(shipped)ROS/src/__tests__/routes/beacon-a2a-conformance.test.ts

Getting access

Access is scoped through a conversation rather than a self-serve signup. A developer who wants access against the real thing books the demo — that is the honest current path, and this page will state a different one when a different one exists.

Send me the paper

Four working papers. A person sends the one you pick — no download wall, and no meeting is booked.

Work out what this costs