> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heretic.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Tenant verdict endpoint

> Retrieve a settled Heretic projection by request ID with a server-only site secret key.

Call the tenant verdict endpoint from your backend:

```http theme={null}
GET https://heretic.tech/v1/verdict/{requestId}
Authorization: Bearer hrtc_sk_<32 lowercase hex>
```

The secret key scopes the read to one site. Keep it out of browser code.

## Request ID

Use the raw 32-character lowercase hexadecimal request ID returned by ordinary collection. The endpoint tolerates one legacy `req_` prefix for compatibility, but new integrations must pass the raw ID unchanged.

## Server example

```js theme={null}
const VERDICT_ORIGIN = 'https://heretic.tech';

export async function readHereticVerdict(requestId) {
  const response = await fetch(
    `${VERDICT_ORIGIN}/v1/verdict/${encodeURIComponent(requestId)}`,
    {
      headers: {
        authorization: `Bearer ${process.env.HERETIC_VERDICT_KEY}`,
      },
    },
  );

  if (response.status === 200) {
    return { state: 'available', value: await response.json() };
  }

  if (response.status === 404) {
    return { state: 'unavailable' };
  }

  if (response.status === 401) {
    throw new Error(
      'Heretic verdict key is missing, malformed, unknown, or revoked',
    );
  }

  throw new Error(`Heretic verdict read failed with HTTP ${response.status}`);
}
```

A curl request uses the raw nonce:

```bash theme={null}
curl -H "Authorization: Bearer $HERETIC_VERDICT_KEY" "https://heretic.tech/v1/verdict/0123456789abcdef0123456789abcdef"
```

## Status codes

| Status | Meaning                                                                                      |
| ------ | -------------------------------------------------------------------------------------------- |
| `200`  | A row exists and belongs to the authenticated key's site.                                    |
| `401`  | The key is missing, malformed, unknown, or revoked.                                          |
| `404`  | The ID is missing, invalid, foreign, archived, deleted, pruned, or belongs to a ZDR request. |

The endpoint returns plain text for `401` and `404`. Cross-site and missing IDs deliberately share `404`.

The route defines no application-level `429` contract. Treat other statuses as unexpected HTTP failures, not assessment verdicts.

## Availability

Successful ordinary collection means D1 acknowledged a tenant-visible commit. The authenticated owning tenant can retrieve the returned ID immediately. Projection failure makes collection fail instead of returning a request ID.

The 60-second settlement threshold and 30-second sweep apply only to local NDJSON persistence. ZDR creates no tenant row.

## Success response

A `200` response returns tenant API version `1`:

```json theme={null}
{
  "api_version": "1",
  "request_id": "0123456789abcdef0123456789abcdef",
  "verdict": "disputed",
  "conclusive": false,
  "insufficient_reason": null,
  "refused": false,
  "summary": "Human-readable assessment summary",
  "signals": [
    {
      "id": "stack.os-contradiction",
      "tier": "composite",
      "family": "transport-stack",
      "headline": "Human-readable finding headline",
      "detail": "Human-readable finding detail"
    }
  ],
  "families": [
    {
      "family": "network-geometry",
      "status": "consistent",
      "highest_tier": null,
      "coverage": { "state": "measured" }
    },
    {
      "family": "transport-stack",
      "status": "contradicted",
      "highest_tier": "composite",
      "coverage": { "state": "measured" }
    },
    {
      "family": "transport-reachability",
      "status": "consistent",
      "highest_tier": null,
      "coverage": { "state": "measured" }
    },
    {
      "family": "tls-construction",
      "status": "consistent",
      "highest_tier": null,
      "coverage": { "state": "measured" }
    },
    {
      "family": "http-construction",
      "status": "consistent",
      "highest_tier": null,
      "coverage": { "state": "measured" }
    },
    {
      "family": "compute",
      "status": "consistent",
      "highest_tier": null,
      "coverage": { "state": "measured" }
    }
  ],
  "provenance": {
    "schema": 10,
    "build": "0.0.1+f19fb27",
    "ruleset_revision": 6,
    "compute_probe_version": 2
  },
  "network": {
    "asn": 64500,
    "country": "US",
    "description": "Example network",
    "classification": "access"
  },
  "identity": {
    "version": 2,
    "instance": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "machine": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "tier": {
      "instance": "absolute",
      "machine": "conditional"
    },
    "components": {
      "display": "1920x1080@2",
      "cores": 8,
      "platform": "MacIntel",
      "timezone": "America/New_York"
    }
  },
  "edge": "waw-01",
  "created_at": 1787700000000,
  "ingested_at": 1787700000500
}
```

The prose and sample values are illustrative. The six family reports are part of the current assessment projection. `network`, `identity`, `provenance`, `edge`, and timestamps can be `null` when the stored row lacks valid values. Inside a non-null identity object, missing IDs and components are omitted.

See [Tenant verdict schema](/api/verdict-schema) for every field.

## Projection boundary

The endpoint does not return the full edge assessment or session. It omits:

* the full session and raw measured or declared claims
* raw IP and detailed transport records
* geometry arithmetic
* the full concealment report, apart from projected network classification
* the sensor report and per-finding sensor admissions
* `contradicting_families`
* each family report's internal signal-ID list

A tenant secret key authorizes this projection. It is not an edge operator credential.

## Stable fields

Use documented IDs, enums, booleans, versions, provenance, and timestamps as program inputs. Treat `summary`, signal `headline`, signal `detail`, network descriptions, and coverage reasons as prose.

The endpoint reports an assessment. It does not prescribe a consequence.


## Related topics

- [Collector reference](/integration/collector.md)
- [Quickstart](/quickstart.md)
- [Dashboard and keys](/dashboard/dashboard-and-keys.md)
- [Tenant verdict schema](/api/verdict-schema.md)
- [Heretic documentation](/index.md)
