---
title: "Get JWKS (public key set)"
method: GET
path: "/v1/jwks"
tags: ["Wallet Auth"]
---

# Get JWKS (public key set)

`GET /v1/jwks`

## Request

- Base URL: `https://api.insumermodel.com`
- URL: `https://api.insumermodel.com/v1/jwks`
- Auth: none required

Returns the JSON Web Key Set containing InsumerAPI's two public signing keys. Use this to verify attestation and trust-profile signatures without hardcoding a key. Five entries are published. Three `kid` labels point at the SAME ECDSA P-256 key: `insumer-attest-v1` (v1 attest, v1 trust, and all commerce discount responses regardless of key generation), `insumer-attest-v2` (v2 attest), `insumer-trust-v2` (v2 trust). They are followed by two RFC 9964 `AKP` entries for the ML-DSA-65 post-quantum signature key, `insumer-attest-pq1` and `insumer-trust-pq1`, appended after the EC entries. Resolve the key by the `kid` (or `pqKid`) on the response you are verifying, never by position; an unknown kid is unverifiable, not refuted. The `kid` also tells you which verification rules to apply (see the `sig` notes on /v1/attest). Keys are never removed: a rotated key stays in this set permanently under its original `kid`, so attestations kept as records remain verifiable. No authentication required. Cached for 24 hours.

## Response `200`

JWKS document

- object
  - `keys` object[]
    - `kty` string: EC on the three classical entries; AKP (RFC 9964) on the two post-quantum entries
    - `crv` string
    - `x` string: Base64url-encoded x coordinate
    - `y` string: Base64url-encoded y coordinate
    - `use` string
    - `alg` string: ES256 on the EC entries; ML-DSA-65 (FIPS 204) on the AKP entries
    - `pub` string: Base64url ML-DSA-65 public key; present only on the AKP entries (which carry no crv, x or y)
    - `kid` string: One of: insumer-attest-v1, insumer-attest-v2, insumer-trust-v2 (all the same EC key; post-quantum AKP entries, kid insumer-attest-pq1 / insumer-trust-pq1, are appended after them).

## Other responses

- `500`: Unexpected server error. Safe to retry; no credits are charged on a 500. Router endpoints return the standard error envelope; standalone endpoints (the ones whose 200 is a flat object) return a flat {"error": "..."} object.

---

[API](https://skmtc.dev/insumermodel/apis/insumerapi.md) · [All operations](https://skmtc.dev/insumermodel/apis/insumerapi/llms.txt) · [OpenAPI document](https://skmtc.dev/insumermodel/apis/insumerapi/revisions/91f56fe9e3d8?raw)
