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

# POST /verify/v0/proof

> Verify a location proof with cross-correlation analysis

<Warning>
  **Research Preview** — This API is under development.
</Warning>

# Verify proof

Verify a location proof (a claim bundled with one or more stamps). This endpoint verifies each stamp individually, then cross-correlates them to produce a [CredibilityVector](/api-reference/types#credibilityvector) — a multidimensional assessment of how well the evidence supports the claim.

```
POST /verify/v0/proof
```

<Note>
  The Verify API does **not** return a single summary score. The `CredibilityVector` provides spatial, temporal, validity, and independence dimensions so your application can define its own trust model.
</Note>

## Request body

<ParamField body="proof" type="LocationProof" required>
  The proof to verify. Contains a `claim` ([LocationClaim](/api-reference/types#locationclaim)) and an array of `stamps` ([LocationStamp](/api-reference/types#locationstamp)).
</ParamField>

<ParamField body="options.chainId" type="number">
  Chain ID for EAS attestation signing (e.g., `84532` for Base Sepolia).
</ParamField>

<ParamField body="options.submitOnchain" type="boolean">
  Whether to submit the attestation onchain. Defaults to `false`.
</ParamField>

## Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://staging-api.astral.global/verify/v0/proof \
    -H "Content-Type: application/json" \
    -H "X-API-Key: your-api-key" \
    -d '{
      "proof": {
        "claim": {
          "lpVersion": "0.2",
          "locationType": "geojson-point",
          "location": { "type": "Point", "coordinates": [-122.4194, 37.7749] },
          "srs": "http://www.opengis.net/def/crs/OGC/1.3/CRS84",
          "subject": { "scheme": "eth-address", "value": "0x1234..." },
          "radius": 100,
          "time": { "start": 1706900000, "end": 1706903600 }
        },
        "stamps": [
          {
            "lpVersion": "0.2",
            "locationType": "geojson-point",
            "location": { "type": "Point", "coordinates": [-122.4195, 37.7750] },
            "srs": "http://www.opengis.net/def/crs/OGC/1.3/CRS84",
            "temporalFootprint": { "start": 1706901000, "end": 1706901060 },
            "plugin": "proofmode",
            "pluginVersion": "0.1.0",
            "signals": {},
            "signatures": [{ "signer": { "scheme": "device-pubkey", "value": "0x..." }, "algorithm": "secp256k1", "value": "0x...", "timestamp": 1706901030 }]
          },
          {
            "lpVersion": "0.2",
            "locationType": "geojson-point",
            "location": { "type": "Point", "coordinates": [-122.4193, 37.7748] },
            "srs": "http://www.opengis.net/def/crs/OGC/1.3/CRS84",
            "temporalFootprint": { "start": 1706901000, "end": 1706901120 },
            "plugin": "witnesschain",
            "pluginVersion": "0.1.0",
            "signals": {},
            "signatures": [{ "signer": { "scheme": "eth-address", "value": "0x..." }, "algorithm": "secp256k1", "value": "0x...", "timestamp": 1706901060 }]
          }
        ]
      },
      "options": {
        "chainId": 84532
      }
    }'
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch('https://staging-api.astral.global/verify/v0/proof', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': 'your-api-key'
    },
    body: JSON.stringify({
      proof: {
        claim: {
          lpVersion: '0.2',
          locationType: 'geojson-point',
          location: { type: 'Point', coordinates: [-122.4194, 37.7749] },
          srs: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84',
          subject: { scheme: 'eth-address', value: '0x1234...' },
          radius: 100,
          time: { start: 1706900000, end: 1706903600 }
        },
        stamps: [
          // ... stamps array
        ]
      },
      options: { chainId: 84532 }
    })
  });
  ```
</CodeGroup>

## Response

The response contains the verified proof, a credibility vector, and optional EAS attestation data.

<ResponseField name="proof" type="LocationProof" required>
  The verified proof object.
</ResponseField>

<ResponseField name="credibility" type="CredibilityVector" required>
  Multidimensional assessment of how well the stamps support the claim. See [CredibilityVector](/api-reference/types#credibilityvector) for the full type.
</ResponseField>

<ResponseField name="evaluationMethod" type="string" required>
  The evaluation method used (e.g., `"multifactor-v0"`).
</ResponseField>

<ResponseField name="evaluatedAt" type="number" required>
  Unix timestamp (seconds) of when the evaluation was performed.
</ResponseField>

<ResponseField name="attestation" type="AttestationData">
  EAS attestation data. Present when `chainId` is provided. See [AttestationData](/api-reference/types#attestationdata).
</ResponseField>

<ResponseField name="delegatedAttestation" type="DelegatedAttestationData">
  Delegated attestation for onchain submission. See [DelegatedAttestationData](/api-reference/types#delegatedattestationdata).
</ResponseField>

## Example response

<Warning>
  **Illustrative example.** ProofMode verification is working today; the `witnesschain` stamp below is shown to illustrate multi-source cross-correlation, but WitnessChain (along with `gpsd`, `geoclue`, `wifi-mls`, `ip-geolocation`) is still experimental. Some `details` fields shown here (for example `certificateChainValid`) correspond to checks that are **planned but not yet performed in v0** — see the [ProofMode plugin](/plugins/proofmode) for exactly what verification does today. The credibility-vector structure is also still evolving.
</Warning>

```json theme={null}
{
  "proof": {
    "claim": { "..." : "..." },
    "stamps": ["..."]
  },
  "credibility": {
    "dimensions": {
      "spatial": {
        "meanDistanceMeters": 12.5,
        "maxDistanceMeters": 18.3,
        "withinRadiusFraction": 1.0
      },
      "temporal": {
        "meanOverlap": 0.95,
        "minOverlap": 0.90,
        "fullyOverlappingFraction": 0.5
      },
      "validity": {
        "signaturesValidFraction": 1.0,
        "structureValidFraction": 1.0,
        "signalsConsistentFraction": 1.0
      },
      "independence": {
        "uniquePluginRatio": 1.0,
        "spatialAgreement": 0.88,
        "pluginNames": ["proofmode", "witnesschain"]
      }
    },
    "stampResults": [
      {
        "stampIndex": 0,
        "plugin": "proofmode",
        "signaturesValid": true,
        "structureValid": true,
        "signalsConsistent": true,
        "distanceMeters": 12.5,
        "temporalOverlap": 0.95,
        "withinRadius": true,
        "details": {
          "hashVerified": true,
          "certificateChainValid": true
        }
      },
      {
        "stampIndex": 1,
        "plugin": "witnesschain",
        "signaturesValid": true,
        "structureValid": true,
        "signalsConsistent": true,
        "distanceMeters": 18.3,
        "temporalOverlap": 0.90,
        "withinRadius": true,
        "details": {
          "latencyVerified": true,
          "nodeCount": 3
        }
      }
    ],
    "meta": {
      "stampCount": 2,
      "evaluatedAt": 1706961600,
      "evaluationMode": "local"
    }
  },
  "evaluationMethod": "multifactor-v0",
  "evaluatedAt": 1706961600,
  "attestation": {
    "uid": "0xdef456...",
    "schema": "0x...",
    "attester": "0x590fdb53ed3f0B52694876d42367192a5336700F",
    "recipient": "0x1234...",
    "data": "0x...",
    "revocable": true,
    "refUID": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "signature": "0x..."
  },
  "delegatedAttestation": {
    "signature": "0x...",
    "attester": "0x590fdb53ed3f0B52694876d42367192a5336700F",
    "deadline": 1706403600,
    "nonce": 0
  }
}
```

## Credibility vector

The `credibility` field is a `CredibilityVector` with four dimension groups:

### `dimensions.spatial`

How close each stamp's observed location is to the claimed location.

| Field                  | Type     | Description                                                   |
| ---------------------- | -------- | ------------------------------------------------------------- |
| `meanDistanceMeters`   | `number` | Average distance between stamp locations and claimed location |
| `maxDistanceMeters`    | `number` | Largest distance from any stamp to the claim                  |
| `withinRadiusFraction` | `number` | Fraction of stamps within the claim's radius (0-1)            |

### `dimensions.temporal`

How well each stamp's temporal footprint overlaps with the claimed time window.

| Field                      | Type     | Description                                             |
| -------------------------- | -------- | ------------------------------------------------------- |
| `meanOverlap`              | `number` | Average temporal overlap ratio (0-1)                    |
| `minOverlap`               | `number` | Smallest overlap of any stamp                           |
| `fullyOverlappingFraction` | `number` | Fraction of stamps fully within the claim's time window |

### `dimensions.validity`

Fraction of stamps passing each verification check.

| Field                       | Type     | Description                            |
| --------------------------- | -------- | -------------------------------------- |
| `signaturesValidFraction`   | `number` | Fraction with valid signatures (0-1)   |
| `structureValidFraction`    | `number` | Fraction with valid structure (0-1)    |
| `signalsConsistentFraction` | `number` | Fraction with consistent signals (0-1) |

### `dimensions.independence`

How independent and corroborative the evidence sources are.

| Field               | Type       | Description                                   |
| ------------------- | ---------- | --------------------------------------------- |
| `uniquePluginRatio` | `number`   | Ratio of unique plugins to total stamps (0-1) |
| `spatialAgreement`  | `number`   | How well stamps agree spatially (0-1)         |
| `pluginNames`       | `string[]` | List of plugins that contributed stamps       |

### `stampResults`

Per-stamp verification results. See [StampResult](/api-reference/types#stampresult) for the full type.

### `meta`

| Field            | Type     | Description                                    |
| ---------------- | -------- | ---------------------------------------------- |
| `stampCount`     | `number` | Number of stamps evaluated                     |
| `evaluatedAt`    | `number` | Unix timestamp (seconds)                       |
| `evaluationMode` | `string` | Evaluation mode: `"local"`, `"tee"`, or `"zk"` |

## Errors

Errors follow [RFC 7807](https://tools.ietf.org/html/rfc7807):

| Type              | Status | Description                                    |
| ----------------- | ------ | ---------------------------------------------- |
| `invalid-input`   | 400    | Malformed proof, missing claim fields          |
| `validation`      | 400    | Claim validation failed (e.g., missing radius) |
| `not-implemented` | 501    | Plugin not supported                           |
| `internal`        | 500    | Internal verification error                    |
| `rate-limited`    | 429    | Too many requests                              |
| `unauthorized`    | 401    | Invalid or missing API key                     |

<Card title="SDK: Location proofs" icon="code" href="/sdk/location-proofs">
  See the SDK documentation for client-side usage
</Card>
