For developers

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

  1. 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.
  2. 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"
  3. 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"}'
  4. 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.

RouteScopeWhat it does
POST /v1/decisionsdecisions:writeOpen 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:readThe run: status, mode, the decision once there is one, and its certification tier.
GET /v1/rosterroster:readWho would decide this, by pseudonym, without running it.
POST /v1/decisions/{id}/outcomeoutcomes:writeReport effectiveness (0 to 1) and, optionally, the right answer. Once per run.
POST /v1/cascade/consultcascade:consultAsk one seated human twin, at tier 2 of a cascade. Returns a typed answer with a measured confidence.
POST /v1/cascade/review-requestscascade:consultTier 3: ask for a person. Holds reasons and ids only, never your case.
GET /v1/usageusage:readThis month’s decision units, runs and consults against your plan.
GET /v1/plansnoneThe 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 refused

Plans

Loading the plan table…

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.