Attestra
Endpoints

Endpoints

Nine endpoints. Eight answer questions; one writes to a chain.

MethodPathPurpose
GET/v1/healthConfirms the service is up.
GET/v1/resolve/{did}Resolves a DID document.
GET/v1/status/{credentialId}Looks up a credential's validity by its hash.
GET/v1/schema/{hash}Looks up a registered schema by its hash.
GET/v1/attestation/{did}/{credentialId}Reads back a previously stored attestation.
POST/v1/verifyVerifies a presentation and signs the result.
POST/v1/verify-quorumVerifies a presentation against multiple oracle nodes and signs the agreed result.
POST/v1/credential-statusChecks an entry in a W3C Bitstring Status List.
POST/v1/pushWrites a signed attestation to a chain.

Reads versus writes

Only /v1/push sends a transaction. It is the one call on this list that costs gas and changes chain state.

Every other endpoint is a read plus a signature. The oracle looks something up, signs a statement about what it found, and returns it. Nothing is written and no gas is spent, whether the answer is "valid", "revoked", or "not found".

The ?chain= parameter

A bare credential hash or schema hash does not name a chain by itself: the same hash format says nothing about whether the record lives on eIDChain, Ethereum, or Hyperledger Fabric. Where the path alone is ambiguous, the endpoint takes a ?chain= query parameter and falls back to a default when the caller omits it.

The defaults are not the same across endpoints:

EndpointDefault chain
/v1/statuseid
/v1/schemaeid
/v1/attestationfabric

/v1/resolve does not need ?chain=: the DID method (did:eid:…, did:ethr:…, did:fabric:…) already says which chain to ask.

What each chain answers today

The dispatch architecture is chain-agnostic by design. An adapter registers itself for the capabilities it implements, and for /v1/verify specifically, for the credentialStatus.type value it knows how to check. Adding a chain means writing one adapter that implements the relevant interface; nothing about the endpoints themselves changes. What varies deployment to deployment is which adapters are actually registered. Here is what is registered in this one:

EndpointeIDChainEthereumHyperledger Fabric
/v1/resolveyesyesyes
/v1/statusyesno, always 404yes
/v1/schemayesyesyes
/v1/attestationno, 501no, 501yes
/v1/verifyyesno, 422no, 422

A few of these are worth stating plainly rather than leaving to the table:

  • /v1/attestation read-back is implemented by Hyperledger Fabric only. A request with ?chain=eid or ?chain=ethr returns 501, because neither adapter implements the read-back interface. This is why the endpoint defaults to chain=fabric.
  • /v1/verify has exactly one registered presentation verifier today, for eIDChain credentials whose credentialStatus.type is EidChainRevocation2024. A presentation carrying any other status type has no verifier to dispatch to and returns 422.
  • Ethereum does not serve /v1/status at all. It always returns 404, because on Ethereum the credential's status travels inside the credential itself rather than in a separate on-chain record. Point Ethereum integrations at /v1/verify or /v1/credential-status instead.

Signed responses

Every response that carries a signature is described in one place: The attestation. Read it once rather than on each endpoint page.

On this page