# Attestations

Verify signed reachability answers and pin their trust anchors.


**Auth:** No device authorization.
## Request and response

Angle-bracket values describe placeholders, including nested objects and numeric types; these are wire shapes, not captured service data. Replace them before sending.

```http
POST /v1/query/verify HTTP/1.1
Host: trust-staging.rebellion.systems
Content-Type: application/json

{
  "attestation": "<complete-attestation-from-query>"
}
```

Response shape:

```json role="response"
{
  "verified": "<boolean>",
  "scheme": "<reported-scheme>",
  "assertion": "<claim-and-limits-object>",
  "epochBinding": {
    "citedGraphEpochRoot": "<cited-root-or-null>",
    "currentGraphEpochRoot": "<current-root>",
    "matchesCurrentEpoch": "<boolean>",
    "unsignedServerAssertion": true
  }
}
```




Reachability evidence is the `attestation` returned by [the query API](/api/query). Positive v2 answers combine an Ed25519-signed envelope with a zero-knowledge path-existence proof. Verify both against independently pinned signing keys, the expected question and the supported circuit verification key.

## Attestation keys

`GET /v1/attestation-keys` returns the current public Ed25519 key as JWKS. No authorization is required.


**Never**
Do not turn a key fetched from the answer's issuer into your trust anchor during verification. Distribute trusted JWKS pins through application configuration and use the SDK's pinned circuit verification key.

The SDK `/zk` verifier checks the envelope signature, pinned circuit key hash and circuit inputs against the signed question and Poseidon epoch root, then verifies the proof. Release its resources with `destroy()` when finished. See [local verification in the quickstart](/quickstart).

A negative v2 answer explicitly carries null `zkProof`, `circuitPublicInputs` and `verificationKeyHash`. Applications should present it as a signed report.

## Ask the server to verify

`POST /v1/query/verify` accepts `{attestation}` without device authorization. Its HTTP 200 response has:

| Field | Meaning |
| --- | --- |
| `verified` | Whether verification succeeded |
| `scheme` | Attestation scheme reported by verification |
| `assertion` | Explicit description of what the result establishes and does not establish |
| `verdict` | Signed answer projection, present when available |
| `reason` | Failure explanation when available |
| `epochBinding` | Comparison between the cited and current graph epoch root |

`epochBinding` contains `citedGraphEpochRoot`, `currentGraphEpochRoot`, `matchesCurrentEpoch` and `unsignedServerAssertion: true`.


**Does not establish**
The server verification response is a report by that server. Its epoch comparison is unsigned and is not covered by the submitted attestation. Use local verification for an independent check, and apply your application's freshness policy to the signed evaluation time.

## Deprecated envelope check

`POST /v1/proofs/verify` accepts the legacy `dev-reachability-v0` envelope. It reports checksum consistency with `envelopeIntegrityOnly: true`, `deprecated: true` and `valid: false`. It is not a path-proof verifier and must not authorize a trust decision.
