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

# Issuance vs credential

> Two resources, one workflow: the issuance session and the credentials it produces.

## Two things, not one

When you call [Issue a credential](/products/didx-me/guides/issuers/issue-credential), the platform creates **two kinds of resources at once**:

* An **issuance** — the offer session. It has `offerUri`/`offerQrUri`, a status that tracks the offer/acceptance flow (`offered` → `completed`, or `failed`/`expired`), and any errors that happened along the way.
* One or more **credentials** — the actual credentials that will end up in the user's wallet. Each has its own id, its own status (`offered`/`issued`/`revoked`), and is what you act on later (e.g. to revoke).

In the issuance response, the credentials live one level deeper, in a `credentials[]` array:

```json theme={null}
{
  "data": {
    "id": "cm7d9cq5600pwk3zq3kmpg8uc", // ← issuance id
    "status": "offered",
    "credentials": [
      {
        "id": "cm7d9cq5600pzk3zq9wzxxtc3", // ← credential id
        "status": "offered",
        "format": "sd-jwt-vc",
        "revocable": true
      }
    ],
    "offerUri": "...",
    "offerQrUri": "..."
  }
}
```

The two ids look similar but mean different things, and the API has separate endpoints for each.

## Which one do you need?

| If you want to…                                                | Use the…                                            |
| -------------------------------------------------------------- | --------------------------------------------------- |
| Look up the state of the offer (was it accepted? did it fail?) | **Issuance** — `GET /v1/issuances/{id}`             |
| List historical offer sessions                                 | **Issuance** — `GET /v1/issuances`                  |
| Revoke a credential after it was accepted                      | **Credential** — `POST /v1/credentials/{id}/revoke` |
| List credentials by format / status / template                 | **Credential** — `GET /v1/credentials`              |

## Lifecycles, side by side

Two resources, two state machines:

| Issuance status | Meaning                                          |
| --------------- | ------------------------------------------------ |
| `offered`       | Offer created, waiting for the user to accept    |
| `completed`     | User accepted; the credential is in their wallet |
| `failed`        | Something went wrong during the exchange         |
| `expired`       | The offer wasn't accepted in time                |

| Credential status | Meaning                                                                                                              |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- |
| `offered`         | Created as part of an issuance, not yet accepted                                                                     |
| `issued`          | Accepted and active in the user's wallet                                                                             |
| `revoked`         | Explicitly invalidated (SD-JWT only — see [Revoke a credential](/products/didx-me/guides/issuers/revoke-credential)) |

## Capture both ids at issuance time

The issuance and credential ids are both stable from the moment the issuance is created. You don't need to wait for the user to accept.

The cheapest thing you can do is store both ids against your own record when you issue:

* **issuance id** — so you can ask "was this offer ever accepted?" later, or wire up the `openid4vc.issuance.completed` [webhook](/products/didx-me/guides/webhooks).
* **credential id** — so you can revoke it without having to hunt for it later.

Capturing now is much easier than recovering later.

## Reading them back later

If you didn't capture an id at issuance time, you can recover it:

**By issuance id**, fetch the issuance back and read `credentials[].id` from it:

```bash theme={null}
curl -X GET "https://test.didxtech.com/me-creds/api/v1/issuances/<issuance-id>" \
  -H "Authorization: Bearer <access_token>"
```

**Without any id**, list credentials and narrow with filters:

```bash theme={null}
curl -X GET "https://test.didxtech.com/me-creds/api/v1/credentials?filter[status]=issued&filter[format]=sd-jwt-vc" \
  -H "Authorization: Bearer <access_token>"
```

Supported filters: `filter[id]`, `filter[status]`, `filter[format]`, `filter[credentialTemplateId]`, `filter[exchange]`. Standard cursor pagination via `page[size]`, `page[before]`, `page[after]`.

Full schemas: [Credentials API reference](/products/didx-me/api-reference/v1/me-creds).
