Developers

Accept Petra credentials in your app.

A Petra credential is a compact JWS signed with ES256. You can verify it yourself, in any browser or server, without trusting or even reaching Petra's app servers. The trust is the issuer's published key plus the signature.

The drop-in: @petra/verifier-js

One function. It fetches the public issuer registry, checks the signature, and hands you the decoded credential. Works in the browser and in Node 18+ (pure Web Crypto, no native deps).

Install
npm install @petra/verifier-js
Verify
import { verify } from '@petra/verifier-js'

// jws is the compact credential string (from a QR scan, an upload, an API).
const result = await verify(jws)

if (result.signatureValid) {
  // Authentic — signed by a known Petra issuer.
  console.log('Signed by', result.issuer.name)
  console.log('Subject', result.credential.credentialSubject)
} else {
  // Signature did not verify — do not trust it.
}
Offline-friendly
Cache the issuer registry yourself and call verifyJWS(jws, issuers) to skip the network entirely on the hot path. The registry changes only when an issuer rotates a key.

The manual recipe

If you'd rather not take a dependency, the whole check is four steps with any JWS / crypto library:

1Fetch the issuer registry (published public keys) from https://api.petraverify.id/.well-known/petra-issuers.json.
2Split the compact JWS, read its kid header, and match the issuer key with the same kid.
3ECDSA P-256 / SHA-256 verify the signature over header.payload.
4Optionally recompute the SHA-256 of the payload and cross-check it against the on-chain anchor for a second, Petra-independent proof.
Fetch the registry
curl https://api.petraverify.id/.well-known/petra-issuers.json

Public endpoints

GET /.well-known/petra-issuers.json The issuer registry — every published issuer key. The root of trust.
GET /credentials/{id} A stored credential by id, including its jws, status, and on-chain anchor (when present).
petraverify.id/verify/{id} The human-readable verify page — what a Petra QR code points to.

Base URL: https://api.petraverify.id

Why this is safe to accept

Petra-the-API only serves data; it never asserts validity. A credential carries its own proof — the issuer's signature over the payload — so verification works even if Petra is unreachable, and a forged or tampered credential fails the signature check. Revocation and key rotation are reflected in the registry; the on-chain anchor lets you confirm a credential existed at a point in time independently of Petra entirely.