# DeltaX Evaluate — Free account API

Current public integration reference · evaluation contract `2026-09-16.beta2`.

Sign in with email or Google at https://deltaxevaluate.com/account, complete human
verification, then create a credential in **API access**. Each account includes
100 evaluations per UTC calendar month, shared across its credentials. Public
registration is initially limited to 100 accounts. No card is required. Paid
signup and x402 remain disabled. Selection does not execute or authorize an action.

## Customer endpoints

| Purpose | Endpoint |
| --- | --- |
| Exchange a credential | `POST https://access-api.deltaxevaluate.com/api/builder/oauth/token` |
| Evaluate or replay a request | `POST https://access-api.deltaxevaluate.com/api/builder/evaluations` |

These are the account gateway endpoints. It forwards evaluations to the
evaluator's `POST /v1/evaluations` route. Customer credentials belong to this
gateway; do not send them to the underlying evaluator or its identity provider.

## 1. Request an access token

Store `DELTAX_CLIENT_ID` and `DELTAX_CLIENT_SECRET` in your server environment.
The body is **URL-encoded form data, not JSON**:

```sh
curl --fail-with-body 'https://access-api.deltaxevaluate.com/api/builder/oauth/token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode "client_id=$DELTAX_CLIENT_ID" \
  --data-urlencode "client_secret=$DELTAX_CLIENT_SECRET" \
  --data-urlencode 'scope=deltax:evaluate'
```

| Field | Rule |
| --- | --- |
| `grant_type` | Required; `client_credentials` |
| `client_id` | Account credential ID, `dxb_` followed by 32 lowercase hex characters |
| `client_secret` | Secret shown once when created, `dxbs_` followed by 64 lowercase hex characters |
| `scope` | Optional; if supplied, `deltax:evaluate` |

HTTP Basic client authentication is also accepted instead of the two credential
body fields. Do not provide both forms of client authentication. There is no
customer-supplied `audience` field to configure.

A successful response is JSON with `access_token`, `token_type: "Bearer"`,
`expires_in: 900`, and `scope: "deltax:evaluate"`. The access token starts with
`dxbt_` and lasts 15 minutes. Store it as `DELTAX_ACCESS_TOKEN` for the next command.
Reuse that token until it approaches expiry; do not request a new token for every
evaluation or retry. Token renewal does not reset request limits.
Revoking a credential also prevents its existing tokens from being used. Never
put credentials or access tokens in browser code, URLs, source control, or logs.

### Python standard-library token example

```python
import json
import os
import urllib.parse
import urllib.request

form = urllib.parse.urlencode({
    "grant_type": "client_credentials",
    "client_id": os.environ["DELTAX_CLIENT_ID"],
    "client_secret": os.environ["DELTAX_CLIENT_SECRET"],
    "scope": "deltax:evaluate",
}).encode("utf-8")
request = urllib.request.Request(
    "https://access-api.deltaxevaluate.com/api/builder/oauth/token",
    data=form,
    headers={
        "Content-Type": "application/x-www-form-urlencoded",
    },
)
with urllib.request.urlopen(request, timeout=20) as response:
    access_token = json.load(response)["access_token"]
# Keep access_token server-side; use it in the Bearer header below.
```

Standard Python clients can use these machine endpoints with their default user
agent. No custom `User-Agent`, browser cookies, or human-verification token is
needed for API calls. Free account creation still requires human verification on
the website. Use the dedicated API hostname shown above for scripts.

An API JSON error such as `invalid_client` means the request reached DeltaX and
the credential needs checking. When reporting a failure, include the endpoint,
status, response type and any request reference; omit credentials and tokens.

## 2. Submit an evaluation

Download https://deltaxevaluate.com/downloads/evaluation.json as `evaluation.json`.

```sh
curl --fail-with-body 'https://access-api.deltaxevaluate.com/api/builder/evaluations' \
  -H "Authorization: Bearer $DELTAX_ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'X-DeltaX-API-Version: 2026-09-16.beta2' \
  -H 'Idempotency-Key: my-first-review-001' \
  --data @evaluation.json
```

The only top-level request fields are `profile_id`, `objective`, `context`, and
`candidates`. Use profile `deltax-hosted-bounded-review-evaluation-v1`.
Each candidate has exactly `candidate_id`, `semantic_class`, `description`,
and `operator_reported_support`.

`analyze`, `compare`, `draft`, and `validate` are review classes. `external`
is shadow-only and cannot be selected. Support is caller-reported, between
0 and 1; it is not DeltaX confidence or verification of supplied facts. The fixed
profile does not infer arbitrary policies from your objective or descriptions.

### Current account request limits

These limits describe the current account gateway, not the beta1 teaching kit.

| Limit | Current value |
| --- | --- |
| Evaluations | 100 per account per UTC calendar month |
| Monthly reset | First day at 00:00 UTC; unused allowance does not roll over |
| Candidates | 1–8, with unique IDs |
| Request body | At most 32,768 UTF-8 bytes; the canonical body must also fit |
| Objective | Nonblank, at most 1,024 characters |
| Context | At most 16 scalar properties; no objects or arrays as values |
| Context keys | 1–64 characters; start with a letter; then letters, digits, `_`, `.`, `-` |
| Context values | `null`, boolean, string up to 256 characters, or finite number with absolute value at most 1,000,000,000 |
| Candidate ID | 1–64 characters; start with a letter or digit; then letters, digits, `.`, `_`, `~`, `-` |
| Candidate description | Nonblank, at most 512 characters |
| Caller-reported support | Finite number from 0 to 1 |
| Idempotency key | 16–128 characters from letters, digits, `.`, `_`, `~`, `-` |
| Token request body | At most 4,096 bytes |
| Machine API requests | 30 per minute per source IP across both routes; also subject to shared service capacity |
| New evaluation requests | 60 per minute per account, also subject to allowance and shared service capacity |

Context keys reserved for credentials, executable content, files or external
destinations are rejected: `authorization`, `bearer`, `callback`, `command`,
`cookie`, `credential`, `credentials`, `file`, `filepath`, `password`, `path`,
`plugin`, `recovery_code`, `secret`, `session`, `shell`, `subprocess`, `token`,
`tool`, `url`, `webhook`. Matching is case-insensitive and treats `-` as `_`.
Minimize sensitive data. Rate limits are ceilings, not throughput or availability guarantees.

## 3. Read the response and retain its records

A completed response has this structure (field names only; not a sample receipt):

```text
receipt_id                         account evaluation record ID (eval_…)
evaluated_at                       gateway response timestamp
counted                            whether this result used one evaluation
result.outcome                     selected | governed_noop_refusal
result.selected_candidate_id       submitted review candidate ID, or null
result.reason_codes                bounded outcome codes
result.trace                       request digests, gate decisions, trace ID and time
result.commercial_receipt           evaluator receipt ID, hashes, mode and time
result.authority                    explicit false authority flags
```

The two receipt IDs identify **different records**:

- Top-level `receipt_id`: the account's evaluation record, used in account
  history, reconciliation and support.
- `result.commercial_receipt.receipt_id`: the evaluator's committed receipt.
  Retain it alongside `receipt_sha256`, `commercial_binding_sha256` and the trace.

They are not expected to match. The contract's `commercial_receipt` name and
`mode: "free_beta"` are retained wire fields; they do not mean a payment occurred.

The trace records the outcome, bounded reason codes, request bindings, and
service gate decisions. It is **not a per-candidate ranking explanation**.
`trace.lambda_decisions` must not be presented as a rejection reason for each
individual candidate. A hash is an integrity reference, not proof that supplied
facts are true, a safety certification, or permission to execute anything.

All authority flags and the trace's `submitted_candidate_executed`,
`external_effect`, `learning_applied`, and `operator_reported_context_verified`
flags remain false. Your application or reviewer decides what happens next.

## Usage, replay and errors

- A completed selection or governed refusal counts once. Exact replay of the
  same body and account-scoped key returns the stored response without using
  another evaluation. The replayed body's `counted: true` describes the original
  result; the `Idempotent-Replayed: true` response header identifies the replay.
- Reuse the same key and body after a network interruption. Never create a new
  key just to retry an uncertain request. Changed content under the same key
  returns `409` with `idempotency_key_conflict`.
- `202` means the outcome is unconfirmed or still reserved. Its allowance stays
  reserved pending reconciliation. Replaying reads stored status; it does not
  start another evaluation or guarantee automatic resolution. Contact support
  with the account record ID if it remains uncertain.
- `400` indicates a malformed or invalid request. `401` indicates missing,
  invalid, expired or revoked credentials/token. `413` indicates an oversized
  body. `415` indicates the wrong content type.
- `429` can indicate monthly allowance, request rate or upstream capacity.
  `evaluator_rejected_request` with `upstream_status: 429` is an upstream refusal,
  not proof that your account used all 100 evaluations. Check account usage.
- Failed admission does not count as a completed evaluation. A `202` reservation
  is different and must not be discarded as unused work.
- New unconfirmed responses include a bounded `unconfirmed_reason` (for example,
  `upstream_timeout` or `invalid_evaluator_response`) and, when known,
  `upstream_status`. These describe what the gateway observed, not proof that
  the evaluator did or did not complete. Historical responses may lack them.
- Gateway errors use JSON; they do not follow the archived beta1 error schema.

### Retry discipline

Keep the original body and idempotency key together. Never use a new key to get
around a `202`, timeout, or rate limit. A `202` is not a completed result and is
not an instruction to create new work. Stop automatic retries and retain its
`receipt_id` for support; exact replay only reads the stored status.

A `429` is not a governed evaluation outcome. Respect `Retry-After`, use bounded
backoff with jitter, and avoid concurrent retry loops. Check the response's
retry instructions: `retryable: false` with `retry_mode: "cached_rejection"`
means this key will only replay its rejection, even when `upstream_retryable`
is true. That upstream hint is diagnostic; it does not authorize a gateway retry.
`Retry-After` supplies pacing information, not permission to re-execute. Historical
rejected responses may lack these fields and remain cached. Replaying a
cached rejection does not make a new evaluation succeed. If no supported retry
path is indicated, retain the record ID and contact support. Do not treat
`counted: false` by itself as permission to submit under a different key.

## Historical kit

The downloadable OpenAPI, schemas, client and specimens remain the pinned
`2026-09-16.beta1` teaching snapshot. Their limits and placeholder token URL are
not the current account API. Use this reference and the
[beta2 summary](https://deltaxevaluate.com/developers/evaluate/v1#beta2)
for new integrations. No beta2 OpenAPI file is supplied in the beta1 kit.
