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

# Verifiable credentials

> Issue, share, verify, and revoke W3C-shaped credentials for Dataerai DIDs.

A verifiable credential packages a Dataerai DID into a portable JSON document
that another person or system can verify. Use public credentials for citable
public identities. Use sealed credential shares when a credential should be
opened only by a specific party with a shared key.

### When to use a credential

A credential is a self-contained proof you can hand to someone outside Dataerai.
Reach for one when you want to:

* give an **external reviewer or collaborator** portable proof that a record is
  yours and unchanged, without inviting them into the app;
* attach a **verifiable claim** about a DID to a report, submission, or pipeline
  that travels independently of the record;
* share that proof with **one specific party** — a person, organization, or
  group — using a sealed credential share that only they can open.

<Note>
  Credentials are available through the **REST API** (and any SDK or script that
  calls it) — there is no dedicated web UI for issuing, sharing, or verifying them
  yet. Every example below is a `curl` request you can adapt.
</Note>

Replace `$DATAERAI_SERVER` with your Dataerai host in the examples below.
`$DATAERAI_TOKEN` is an OAuth2 access token — see
[Authentication](/api-reference/authentication) for how to get one. The verify
and public-fetch endpoints need no token.

## Before you issue a public credential

You can issue a credential only for a DID that is already **published**. Private
or gated DIDs cannot receive public credentials.

The person issuing the credential must own the record.

## Issue a public credential

```bash theme={null}
curl -X POST $DATAERAI_SERVER/api/credentials/issue/ \
  -H "Authorization: Bearer $DATAERAI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"did":"did:dataerai:asset:..."}'
```

The response includes the signed credential JSON, `id` as the UUID path segment,
`credential_id` as the full credential URL, and a status URL inside the
credential JSON. The credential contains the DID, the public identity
commitment, the latest identity sequence, and the Dataerai issuer. It does not
include private record metadata.

You can add an optional future `expires_at` timestamp when you want the
credential to stop verifying after a specific time.

## Share a credential

Share either the credential JSON or the returned `credential_id` URL:

```bash theme={null}
curl $CREDENTIAL_ID
```

You can also fetch it from the API path with the returned `id` value:

```bash theme={null}
curl $DATAERAI_SERVER/api/credentials/{id}/
```

Anyone can fetch a credential by URL and check its status. They do not need a
Dataerai account.

## Issue a sealed credential share

Use a sealed credential share when the credential should be readable only by an
intended party. The recipient can be a user, linked person, organization, or
group. The signed credential is encrypted with the shared key; the shared key is
not stored by Dataerai. Shared keys must be at least 24 characters.

```bash theme={null}
curl -X POST $DATAERAI_SERVER/api/credentials/shares/issue/ \
  -H "Authorization: Bearer $DATAERAI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "did":"did:dataerai:asset:...",
    "recipient_type":"group",
    "recipient_id":"00000000-0000-0000-0000-000000000000",
    "shared_key":"correct horse battery staple"
  }'
```

`recipient_type` can be `user`, `person`, `organization`, or `group`.

Sealed credential responses include a share `id`, the credential URL, recipient
metadata, and status. They do not include the signed credential body.

## Open a sealed credential share

The caller must belong to the recipient party and provide the same shared key:

```bash theme={null}
curl -X POST $DATAERAI_SERVER/api/credentials/shares/{share_id}/open/ \
  -H "Authorization: Bearer $RECIPIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"shared_key":"correct horse battery staple"}'
```

A successful response returns the signed credential and a verification result.
Wrong-party callers get 404. Intended-party callers with the wrong key get 403.
Revoked shares return 410.

Public credential fetch and status endpoints return 404 for sealed credentials:

```bash theme={null}
curl $DATAERAI_SERVER/api/credentials/{id}/
curl $DATAERAI_SERVER/api/credentials/{id}/status/
```

## Verify a credential

To verify a credential JSON document:

```bash theme={null}
curl -X POST $DATAERAI_SERVER/api/credentials/verify/ \
  -H "Content-Type: application/json" \
  -d '{"credential":{...}}'
```

To verify a credential already stored by your Dataerai server:

```bash theme={null}
curl -X POST $DATAERAI_SERVER/api/credentials/verify/ \
  -H "Content-Type: application/json" \
  -d '{"id":"'$CREDENTIAL_ID'"}'
```

A valid credential means the signature is intact, the issuer matches your
Dataerai server, the signing key is trusted, the credential status is active,
and the DID commitment still appears in the signed identity log. Opened sealed
credentials verify against the stored credential digest, so Dataerai does not
need to store the sealed credential body in plaintext.

## Check status

```bash theme={null}
curl $DATAERAI_SERVER/api/credentials/{id}/status/
```

The status endpoint reports whether the credential is active or revoked.

## Revoke a credential

```bash theme={null}
curl -X POST $DATAERAI_SERVER/api/credentials/{id}/revoke/ \
  -H "Authorization: Bearer $DATAERAI_TOKEN"
```

Revoking a credential does not delete it. The credential remains fetchable so
existing citations do not disappear, but verification reports it as invalid.

## Revoke a sealed share

```bash theme={null}
curl -X POST $DATAERAI_SERVER/api/credentials/shares/{share_id}/revoke/ \
  -H "Authorization: Bearer $DATAERAI_TOKEN"
```

Revoking a sealed share does two things at once. The recipient party can no
longer open it (the open endpoint returns **410 Gone**), and — because each
sealed share has its own one-to-one credential — the underlying credential is
revoked too. So a copy the recipient already opened (or passed on) immediately
stops verifying as valid. Revocation is permanent; a credential cannot be
un-revoked.

Only the credential owner, an admin, or the user who created the share can
revoke it. The recipient can open the share but cannot revoke it.

<Note>
  Verifiable credentials use the same Dataerai DID and key trust model as identity
  verification. Sealed shares add party membership plus shared-key decryption.
  Neither flow requires a blockchain wallet or any on-chain transaction.
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="Publish & cite" icon="globe" href="/identity/publish-and-cite">
    Make a DID public before issuing a credential.
  </Card>

  <Card title="Resolve & verify" icon="badge-check" href="/identity/verify">
    Verify a DID directly through the public identity endpoints.
  </Card>
</CardGroup>
