Ask for a person’s judgment, from your own system.
Your decision system handles what it can. When it isn’t sure, or the stakes call for it, it can ask the BEHALVES network: a small council of measured human twins answers, and a real person confirms when they disagree. You get one typed answer, and the record of how it was reached.
This is an early build. Plan numbers below are provisional, and keys are issued by our team.
Quickstart
- Ask us for a key. Each key belongs to one tenant, has only the scopes you need, and can be limited to your addresses. It looks like
bhk_…and is shown to you once. - Check it works. Paste it into “Check my key” below, or run:
curl -s https://network.behalves.space/v1/usage \ -H "Authorization: Bearer $BEHALVES_KEY" - Open a decision when your system needs a person or a council:
curl -s https://network.behalves.space/v1/decisions \ -H "Authorization: Bearer $BEHALVES_KEY" -H "Content-Type: application/json" \ -d '{"question": {"type": "choice", "prompt": "Which framing should the launch use?", "options": ["value_framing", "broad_awareness"]}, "context": "Two sentences of context, no personal data.", "domain": "industry.consumer_behaviour.practice", "idempotency_key": "launch-42"}' - Report how it turned out, once you know. This is how a twin’s accuracy is measured, and it is the only way:
curl -s https://network.behalves.space/v1/decisions/$RUN_ID/outcome \ -H "Authorization: Bearer $BEHALVES_KEY" -H "Content-Type: application/json" \ -d '{"effectiveness": 0.7, "correct_answer": "value_framing"}'
What a key can do
Each route needs one scope. Everything else on the platform refuses a tenant key.
| Route | Scope | What it does |
|---|---|---|
POST /v1/decisions | decisions:write | Open a council run for a choice. Refused above your plan’s stakes ceiling. Safe to repeat with an idempotency_key. |
GET /v1/decisions/{id} | decisions:read | The run: status, mode, the decision once there is one, and its certification tier. |
GET /v1/roster | roster:read | Who would decide this, by pseudonym, without running it. |
POST /v1/decisions/{id}/outcome | outcomes:write | Report effectiveness (0 to 1) and, optionally, the right answer. Once per run. |
POST /v1/cascade/consult | cascade:consult | Ask one seated human twin, at tier 2 of a cascade. Returns a typed answer with a measured confidence. |
POST /v1/cascade/review-requests | cascade:consult | Tier 3: ask for a person. Holds reasons and ids only, never your case. |
GET /v1/usage | usage:read | This month’s decision units, runs and consults against your plan. |
GET /v1/plans | none | The plan table below. Public. |
The full contract is contracts/openapi.yaml in the repository. Errors are always {"error": {"code": "…", "detail": {…}}}.
From a Python cascade
If your decision system is a typed cascade, the escalation port speaks to this API for you. It refuses to send a key over plain http (except to your own machine), and never raises: when the network can’t be reached your cascade gets nothing back and moves on to its own fallback.
from behalves_cascade.http_escalation import HttpEscalation
from behalves_cascade.cascade import Cascade
escalation = HttpEscalation("https://network.behalves.space", api_key)
cascade = Cascade(router, env="pilot", escalation=escalation) # tier 2 asks a seated human twin; tier 3 opens a review request
# escalation.last_error holds the reason code if the last call was refusedPlans
Loading the plan table…
| Plan | Highest stakes | Requests per minute | Open runs | Decision units per month |
|---|
Check my key
Paste a key to see this month’s usage. The key is sent only to this site, is held in memory for the one request, and is cleared from the box straight away.