Skip to Content

Prisma DIDs Indexer API

Base URL depends on which indexer instance you are querying. The DID indexer and VC indexer run as separate services with different INDEXER_CONFIG values, but they share the same codebase and health endpoint.

All responses are JSON. All timestamps are ISO 8601 strings. The API supports CORS and gzip compression.

Health

GET /health

Returns the current sync state of the indexer. Use this to check if the service is running and how far behind the chain tip it is.

Response

{ "status": "ok", "indexer": "prisma-did-indexer", "network": "preprod", "confirmationDepth": 10, "sync": [ { "label": 199674, "lastBlockHeight": 1234567, "lastBlockHash": "abc123..." } ] }
FieldTypeDescription
statusstringAlways "ok" if the server is responding
indexerstringName of the indexer configuration
networkstringCardano network (preprod or mainnet)
confirmationDepthnumberHow many blocks deep a transaction must be before it is considered confirmed
syncarrayOne entry per metadata label the indexer is tracking. lastBlockHeight tells you the most recent block the indexer has processed

DID Endpoints

These endpoints are available on the DID indexer (INDEXER_CONFIG=did).

GET /did/:did

Resolves a DID to its current document and metadata. By default, the indexer uses the latest valid confirmed event for this DID, fetches the DID Document from IPFS, and returns both.

URL params

ParamTypeDescription
didstringThe full DID string, e.g. did:cardano:stake_test1uq...

Query params

ParamTypeDefaultDescription
includeUnconfirmedstring"false"Set to "true" to include events that have not yet reached confirmation depth. Useful for showing freshly created DIDs before they are fully confirmed

Responses

StatusWhen
200DID found and active
400Invalid DID format
404No events found for this DID
410DID has been revoked

200 Response

{ "did": "did:cardano:stake_test1uq...", "document": { "@context": ["https://www.w3.org/ns/did/v1"], "id": "did:cardano:stake_test1uq...", "verificationMethod": [...], "authentication": [...], "service": [...] }, "metadata": { "created": "2025-01-15T10:30:00.000Z", "updated": "2025-02-01T14:00:00.000Z", "version": 2, "deactivated": false } }
FieldTypeDescription
didstringThe resolved DID
documentobject or nullThe W3C DID Document fetched from IPFS. Null if the IPFS fetch failed
metadata.createdstring or nullTimestamp of the first create event
metadata.updatedstringTimestamp of the most recent event
metadata.versionnumberCurrent version number (starts at 1, increments on each update)
metadata.deactivatedbooleanAlways false for active DIDs (revoked DIDs return 410 instead)

Caching: Responses are cached for 60 seconds. An ETag header is included based on the DID and version number.


GET /did/:did/history

Returns the full event history for a DID with pagination. Each event represents an on-chain action (create, update, or revoke).

URL params

ParamTypeDescription
didstringThe full DID string

Query params

ParamTypeDefaultDescription
limitnumber50Results per page, between 1 and 100
offsetnumber0Number of results to skip
orderstring"desc"Sort order by version. "desc" shows newest first, "asc" shows oldest first
includeUnconfirmedstring"false"Set to "true" to include unconfirmed events

Responses

StatusWhen
200DID found, returning events
400Invalid DID format
404No events found for this DID

200 Response

{ "did": "did:cardano:stake_test1uq...", "events": [ { "txHash": "abc123...", "action": "create", "version": 1, "prevTxHash": null, "ipfsCid": "QmXyz...", "blockHeight": 1234000, "timestamp": "2025-01-15T10:30:00.000Z", "valid": true, "confirmed": true } ], "total": 3, "limit": 50, "offset": 0 }
FieldTypeDescription
events[].txHashstringCardano transaction hash
events[].actionstringOne of create, update, or revoke
events[].versionnumberVersion number at the time of this event
events[].prevTxHashstring or nullTransaction hash of the previous event in the chain. Null for create events
events[].ipfsCidstring or nullIPFS CID pointing to the DID Document for this version
events[].blockHeightnumberBlock number where this transaction was included
events[].timestampstringBlock timestamp
events[].validbooleanWhether the event passed structural and signature validation
events[].confirmedbooleanWhether the event has reached the required confirmation depth
totalnumberTotal number of events matching the query
limitnumberPage size used
offsetnumberOffset used

GET /1.0/identifiers/:did

W3C Universal Resolver compatible endpoint. Returns the same data as GET /did/:did but wrapped in the standard DID Resolution Result format defined by the W3C DID Resolution spec .

URL params

ParamTypeDescription
didstringThe full DID string

Query params

ParamTypeDefaultDescription
includeUnconfirmedstring"false"Set to "true" to include unconfirmed events

200 Response (active DID)

{ "didResolutionMetadata": { "contentType": "application/did+ld+json" }, "didDocument": { "@context": ["https://www.w3.org/ns/did/v1"], "id": "did:cardano:stake_test1uq..." }, "didDocumentMetadata": { "created": "2025-01-15T10:30:00.000Z", "updated": "2025-02-01T14:00:00.000Z", "versionId": "2", "deactivated": false } }

200 Response (revoked DID)

{ "didResolutionMetadata": {}, "didDocument": null, "didDocumentMetadata": { "deactivated": true } }

400 Response (invalid DID)

{ "didResolutionMetadata": { "error": "invalidDid" }, "didDocument": null, "didDocumentMetadata": {} }

404 Response (not found)

{ "didResolutionMetadata": { "error": "notFound" }, "didDocument": null, "didDocumentMetadata": {} }

Verifiable Credential Endpoints

These endpoints are available on the VC indexer (INDEXER_CONFIG=vc).

GET /vc/:vcHash

Returns all on-chain anchor events for a credential, ordered by block height. This includes issue, validate, and revoke events. Useful for building a full audit trail.

URL params

ParamTypeDescription
vcHashstringThe credential’s unique identifier (JTI hash)

Query params

ParamTypeDefaultDescription
includeUnconfirmedstring"false"Set to "true" to include unconfirmed events

Responses

StatusWhen
200Events found
404No events for this vcHash

200 Response

{ "vcHash": "abc123...", "events": [ { "txHash": "def456...", "event": "issue", "issuerDid": "did:cardano:stake_test1uq...", "holderDid": "did:cardano:stake_test1ur...", "validatorDid": null, "vcType": "PrismaIdentityCredential", "vcFormat": "cose-sd", "ipfsCid": "QmXyz...", "reason": null, "confirmed": true, "blockHeight": 1234000, "timestamp": "2025-01-15T10:30:00.000Z" } ] }
FieldTypeDescription
events[].txHashstringCardano transaction hash
events[].eventstringOne of issue, validate, or revoke
events[].issuerDidstringDID of the credential issuer
events[].holderDidstringDID of the credential holder
events[].validatorDidstring or nullDID of the validator (only present for validate events)
events[].vcTypestringCredential type identifier (e.g. PrismaIdentityCredential)
events[].vcFormatstringCredential format. One of cose-sd or ed25519
events[].ipfsCidstring or nullIPFS CID where the credential payload is pinned. Only present on issue events
events[].reasonstring or nullRevocation reason, only present on revoke events
events[].confirmedbooleanWhether this event has reached confirmation depth
events[].blockHeightnumberBlock number
events[].timestampstringBlock timestamp

GET /vc/:vcHash/status

Returns the current status of a credential. The indexer looks at all events for this vcHash and reduces them into a single status using a deterministic algorithm: it finds the first issue event to identify the canonical issuer, then checks if there is an authorized revoke event from that same issuer. Only the original issuer can revoke a credential.

URL params

ParamTypeDescription
vcHashstringThe credential’s unique identifier

Query params

ParamTypeDefaultDescription
includeUnconfirmedstring"false"Set to "true" to see freshly issued credentials that have not been confirmed yet

Responses

StatusWhen
200Status computed
404No events for this vcHash

200 Response (active)

{ "vcHash": "abc123...", "status": "active", "confirmed": true, "issuer": "did:cardano:stake_test1uq...", "holder": "did:cardano:stake_test1ur...", "vcType": "PrismaIdentityCredential", "issuedAt": "2025-01-15T10:30:00.000Z", "issuedTxHash": "def456...", "issuedTxConfirmed": true }

200 Response (revoked)

{ "vcHash": "abc123...", "status": "revoked", "confirmed": true, "issuer": "did:cardano:stake_test1uq...", "holder": "did:cardano:stake_test1ur...", "vcType": "PrismaIdentityCredential", "issuedAt": "2025-01-15T10:30:00.000Z", "issuedTxHash": "def456...", "issuedTxConfirmed": true, "revokedAt": "2025-02-10T08:00:00.000Z", "revokedTxHash": "ghi789...", "reason": "key_compromised" }
FieldTypeDescription
vcHashstringThe credential identifier
statusstringOne of active, revoked, or unknown. For GET /vc/:vcHash/status, unknown means events exist but none are issue events (if no events exist, this endpoint returns 404). In batch status responses, missing vcHashes are returned as unknown
confirmedbooleanTrue if all relevant events (issue and revoke if applicable) have been confirmed
issuerstringDID of the issuer (from the first issue event)
holderstringDID of the holder
vcTypestringCredential type
issuedAtstringWhen the credential was issued
issuedTxHashstringTransaction hash of the issue event
issuedTxConfirmedbooleanWhether the issue transaction is confirmed
revokedAtstringWhen the credential was revoked (only if status is revoked)
revokedTxHashstringTransaction hash of the revoke event (only if revoked)
reasonstringRevocation reason (only if provided by the issuer)

Caching: Responses are cached for 30 seconds.


POST /vc/status/batch

Fetches the status of multiple credentials in a single request. This avoids making one HTTP call per credential when loading a list. Each vcHash is reduced independently using the same algorithm as GET /vc/:vcHash/status.

Request body

{ "vcHashes": ["abc123...", "def456...", "ghi789..."], "includeUnconfirmed": true }
FieldTypeRequiredDescription
vcHashesstring[]YesArray of credential identifiers. Maximum 100 per request
includeUnconfirmedbooleanNoDefaults to false. Set to true to include unconfirmed events in the status computation

Responses

StatusWhen
200Statuses computed
400Missing or invalid vcHashes, or more than 100 items

200 Response

{ "statuses": { "abc123...": { "vcHash": "abc123...", "status": "active", "confirmed": true, "issuer": "did:cardano:stake_test1uq...", "holder": "did:cardano:stake_test1ur...", "vcType": "PrismaIdentityCredential", "issuedAt": "2025-01-15T10:30:00.000Z", "issuedTxHash": "def456...", "issuedTxConfirmed": true }, "def456...": { "vcHash": "def456...", "status": "unknown", "confirmed": true } } }

The statuses object is keyed by vcHash. Each value has the same shape as the response from GET /vc/:vcHash/status. In this batch endpoint, credentials with no events on-chain are returned as status: "unknown" (unlike the single status endpoint, which returns 404 when no events are found).

Caching: Responses are cached for 30 seconds.


GET /issuer/:did/credentials

Returns a paginated list of credentials issued by a specific DID. Only issue events are returned (not revoke or validate events). To check if any of these credentials have been revoked, use the batch status endpoint.

URL params

ParamTypeDescription
didstringThe issuer’s DID

Query params

ParamTypeDefaultDescription
limitnumber20Results per page, between 1 and 100
offsetnumber0Number of results to skip
orderstring"desc"Sort by block height. "desc" shows newest first
includeUnconfirmedstring"false"Set to "true" to include unconfirmed issue events

200 Response

{ "issuer": "did:cardano:stake_test1uq...", "credentials": [ { "vcHash": "abc123...", "holderDid": "did:cardano:stake_test1ur...", "vcType": "PrismaIdentityCredential", "vcFormat": "cose-sd", "ipfsCid": "QmXyz...", "txHash": "def456...", "confirmed": true, "blockHeight": 1234000, "timestamp": "2025-01-15T10:30:00.000Z" } ], "pagination": { "total": 15, "limit": 20, "offset": 0 } }
FieldTypeDescription
credentials[].vcHashstringCredential identifier
credentials[].holderDidstringDID of the holder this credential was issued to
credentials[].vcTypestringCredential type
credentials[].vcFormatstringCredential format
credentials[].ipfsCidstring or nullIPFS CID of the credential payload
credentials[].txHashstringTransaction hash of the issue event
credentials[].confirmedbooleanWhether the issue event is confirmed
credentials[].blockHeightnumberBlock number
credentials[].timestampstringBlock timestamp
pagination.totalnumberTotal credentials matching the query
pagination.limitnumberPage size
pagination.offsetnumberCurrent offset

GET /holder/:did/credentials

Returns a paginated list of credentials held by a specific DID. Same structure and behavior as the issuer endpoint but filtered by holderDid instead of issuerDid.

URL params

ParamTypeDescription
didstringThe holder’s DID

Query params

Same as GET /issuer/:did/credentials.

200 Response

{ "holder": "did:cardano:stake_test1ur...", "credentials": [ { "vcHash": "abc123...", "issuerDid": "did:cardano:stake_test1uq...", "vcType": "PrismaIdentityCredential", "vcFormat": "cose-sd", "ipfsCid": "QmXyz...", "txHash": "def456...", "confirmed": true, "blockHeight": 1234000, "timestamp": "2025-01-15T10:30:00.000Z" } ], "pagination": { "total": 5, "limit": 20, "offset": 0 } }

The only difference from the issuer endpoint is that each credential includes issuerDid instead of holderDid, since the holder is already known from the URL.


GET /schemas

Returns the list of supported credential types from the schema registry. Each schema defines which fields can be selectively disclosed when creating a presentation.

No params.

200 Response

{ "schemas": [ { "vct": "ContributionCredential", "disclosableFields": ["hours", "description", "evidenceUrl"] } ] }
FieldTypeDescription
schemas[].vctstringVerifiable Credential Type identifier. This is the value used in the vcType field when issuing a credential
schemas[].disclosableFieldsstring[]List of claim keys that support selective disclosure. When creating a presentation, the holder can choose which of these fields to reveal

Modifying the Credential Schema

The schema that defines what fields a credential contains lives in a single file: packages/schemas/src/credentials/contribution.ts. This is the only place you need to make changes.

To add, remove, or change fields, edit the ContributionCredentialSchema.extend({}) block. Each field uses a Zod validator, for example z.string().min(1) for a required string or z.number().positive().optional() for an optional positive number.

To change the contribution type options, update the ContributionTypeEnum array at the top of the file. These are the allowed values for the contributionType field.

To update which fields support selective disclosure, edit the contributionDisclosableFields array at the bottom. When a holder creates a presentation, they can choose to reveal or hide any field listed here.

No changes are needed for the on-chain transaction (it only stores a credential hash and an IPFS pointer, so it never sees the schema fields), the indexer (it only indexes on-chain event metadata and never inspects the credential body on IPFS), or the schema registry (packages/schemas/src/registry.ts) which already references this file and feeds the /schemas endpoint automatically.

You also need to update the issuance form. The form in apps/vc-interface/components/IssuanceForm.tsx has a hardcoded credentialFields object (around line 35) that does not read from the Zod schema. If you change the schema, you must mirror those changes in the form or it will break.

Example: adding a role field to ContributionCredential

  1. In packages/schemas/src/credentials/contribution.ts, add the field to the Zod schema:

    role: z.string().min(1), // required text field // or role: z.string().optional(), // optional text field

    If it should support selective disclosure, add 'role' to the contributionDisclosableFields array.

  2. In apps/vc-interface/components/IssuanceForm.tsx, add a matching entry to the ContributionCredential array inside credentialFields:

    { key: 'role', label: 'Role', type: 'text', required: true, canDisclose: false, defaultDisclosed: false },

    Each field needs:

    • key: must match the Zod field name exactly
    • label: what the user sees in the form
    • type: 'text' for strings, 'number' for numbers, 'select' for enums
    • required: true if the Zod field is not .optional()
    • options: only for 'select' type, list the enum values (e.g. ['code', 'design', 'other'])
    • canDisclose: true if the field is in contributionDisclosableFields
    • defaultDisclosed: true if the disclosure checkbox should be pre-checked

The same pattern applies when removing or renaming fields. Delete or update the entry in both files.


Error Format

Most error responses include an error message and may include endpoint-specific context fields (for example, did or vcHash):

{ "error": "Human-readable error message", "did": "did:cardano:stake_test1..." }

The Universal Resolver endpoint (/1.0/identifiers/:did) uses the W3C error format instead, with didResolutionMetadata.error containing the error code.


Common Query Patterns

Check if a DID exists and is active

GET /did/did:cardano:stake_test1uq...

200 means active, 404 means not found, 410 means revoked.

Load a credential list with statuses

  1. GET /holder/did:cardano:stake_test1ur.../credentials?includeUnconfirmed=true to get the list
  2. POST /vc/status/batch with all the vcHash values from step 1 to get statuses in one call

Check if a freshly issued credential is visible

GET /vc/:vcHash/status?includeUnconfirmed=true

The includeUnconfirmed=true flag ensures the credential appears before it reaches confirmation depth. The confirmed field in the response tells you whether it is confirmed yet.

Last updated on