# Try IXO Credentials on devnet

> Try the whole IXO Credentials chain on devnet with the test issuer and test verifier: read the live services, verify a status list with the kit, save a test credential in the devnet Auth Hub and answer a test request.

This quick start walks you through IXO Credentials on devnet, end to end, with IXO's test issuer and test verifier. Use it to see what an offer, a stored credential, a proof request and a revocation look like before you build your own issuer, verifier or wallet. The parts you run yourself take about 10 minutes.

<Warning>
  **Test tooling only.** The devnet test issuer issues fake "Test Credential" credentials whose claims are whatever the test operator typed, and the test verifier only reports whether a proof was shown. Never use either for real people, and never treat a Test Credential as evidence of anything.
</Warning>

## The devnet services

| Service | Address | DID |
| --- | --- | --- |
| Credentials worker | `https://dev.credentials.ixo.earth` ([API reference](https://dev.credentials.ixo.earth/docs)) | `did:web:dev.credentials.ixo.earth` |
| Auth Hub wallet | `https://dev.auth.ixo.earth/credentials` | |
| Test issuer | `https://test-issuer.dev.credentials.ixo.earth` | `did:web:test-issuer.dev.credentials.ixo.earth` |
| Test verifier | `https://test-verifier.dev.credentials.ixo.earth` ([API reference](https://test-verifier.dev.credentials.ixo.earth/docs)) | `did:web:test-verifier.dev.credentials.ixo.earth` |

The test issuer issues one type:

| Field | Value |
| --- | --- |
| Configuration id | `TestCredential` (`dc+sd-jwt`, signed with Ed25519, bound to a `did:ixo` key) |
| `vct` | `https://test-issuer.dev.credentials.ixo.earth/types/TestCredential` |
| Claims (all selectively disclosable) | `name`, `age_over_18`, `age_over_21`, `level`, `member_number`, `favourite_colour`, `city` |
| Lifetime | 30 days, with a status list entry for every credential |
| Status list | `https://dev.credentials.ixo.earth/status/did:web:test-issuer.dev.credentials.ixo.earth/test1` |

The test verifier asks for `age_over_18` ("Confirm that you are over 18") or for no claim at all ("Confirm that your identity is verified"), and accepts only credentials from the test issuer.

## Prerequisites

- `curl` and Node.js 22 or later.
- A devnet IXO account: sign in at `https://dev.auth.ixo.earth`. Your DID is `did:ixo:` followed by your devnet IXO address (`ixo1…`), shown on the Hub's wallet pages.

## Step 1 — Read the live services

Everything a wallet or verifier reads is public. Start with the Credentials worker and its DID document:

```bash
curl -s https://dev.credentials.ixo.earth/health
curl -s https://dev.credentials.ixo.earth/.well-known/did.json
```

```json
{"status":"ok","version":"0.1.0","timestamp":"2026-11-09T03:38:03.329Z","environment":"devnet"}
```

Read the test issuer's OpenID4VCI metadata, the way a wallet finds the credential and token endpoints:

```bash
curl -s https://test-issuer.dev.credentials.ixo.earth/.well-known/openid-credential-issuer
curl -s https://test-issuer.dev.credentials.ixo.earth/.well-known/oauth-authorization-server
```

```json
{
  "issuer": "https://test-issuer.dev.credentials.ixo.earth",
  "token_endpoint": "https://test-issuer.dev.credentials.ixo.earth/oid4vci/token",
  "grant_types_supported": ["urn:ietf:params:oauth:grant-type:pre-authorized_code"],
  "token_endpoint_auth_methods_supported": ["none"],
  "pre-authorized_grant_anonymous_access_supported": true
}
```

Read both catalog entries. This is where the Hub takes each sender's name and card look from:

```bash
curl -s https://dev.credentials.ixo.earth/v1/catalog/issuers/did:web:test-issuer.dev.credentials.ixo.earth
curl -s https://dev.credentials.ixo.earth/v1/catalog/verifiers/did:web:test-verifier.dev.credentials.ixo.earth
```

```json
{
  "sender_key": "did:web:test-verifier.dev.credentials.ixo.earth",
  "entry": {
    "did": "did:web:test-verifier.dev.credentials.ixo.earth",
    "name": "IXO Test Verifier (devnet)",
    "accepts": [
      {
        "purpose": "Confirm that you are over 18",
        "vct": "https://test-issuer.dev.credentials.ixo.earth/types/TestCredential",
        "claims": ["age_over_18"],
        "issuers": ["did:web:test-issuer.dev.credentials.ixo.earth"]
      }
    ],
    "color": "#5b21b6"
  },
  "updated_at": 1794145603
}
```

The answer above is shortened: the live entry also lists `IdentityLevel1` and the possession-only purpose.

## Step 2 — Verify a status list with the kit

Install the kit and check the test issuer's status list the way a verifier does: resolve the issuer's `did:web`, verify the token's signature and `sub`, and read one bit.

```bash
mkdir credentials-try && cd credentials-try
npm init -y && npm pkg set type=module
npm install @ixo/credentials-kit@0.1.1
```

```js check-status.mjs
import { createWebResolver } from '@ixo/credentials-kit/did';
import { verifyStatusListToken, statusAt } from '@ixo/credentials-kit/status';

const issuer = 'did:web:test-issuer.dev.credentials.ixo.earth';
const uri = `https://dev.credentials.ixo.earth/status/${issuer}/test1`;

const resolver = createWebResolver({ fetch });
const issuerDoc = await resolver(issuer); // https://test-issuer.dev.credentials.ixo.earth/.well-known/did.json
const token = await (await fetch(uri)).text();

const list = await verifyStatusListToken(token, { uri, issuerDoc });
console.log('signed by', list.kid, 'ttl', list.ttl);
console.log('index 0 is', statusAt(list.bits, 0, list.bitsPerEntry) === 0 ? 'valid' : 'revoked');
```

```bash
node check-status.mjs
```

```text
signed by did:web:test-issuer.dev.credentials.ixo.earth#key-1 ttl 60
index 0 is valid
```

## Step 3 — Save a test credential in the Hub

The test issuer's offer endpoint and the test verifier's check endpoint are operated by IXO and are not public: whoever can call them makes the Hub show an offer or a request to the person named. To receive a test offer and a test request, post your devnet DID in the [IXO Community Slack](https://ixofoundation.slack.com/archives/C04UERAUHQT) or send it to [assistant@ixo.world](mailto:assistant@ixo.world), and say which claims you want on your Test Credential (for example `age_over_18: true`).

When the offer arrives:

1. Open `https://dev.auth.ixo.earth/credentials`. The offer from "IXO Test Issuer (devnet)" is under **Needs you**.
2. Choose **Review**, look at the card and what it holds, and choose **Save to my credentials**.
3. The Hub collects the credential over OpenID4VCI with your own key, checks it (signature, `sub` is you, `cnf` is your key, status), and stores it in your Vault. It appears under **Your credentials**.

## Step 4 — Answer a test request

When the test verifier asks you for proof:

1. Open the request in the Hub (from **Needs you**, or from the `wallet_url` you were sent).
2. The page shows who asks (the verifier's catalog name), why (its `purpose`), the credential that will be used and the details that will leave with their values: for "Confirm that you are over 18", only `age_over_18`.
3. Choose **Just this time** and **Share**. The Hub sends an encrypted, key-bound presentation to the verifier's `response_uri`; the check becomes `verified`.

Choose **Don't share** instead to see a decline: the verifier receives `access_denied` and the check expires.

## Verify the result

- The Hub's activity page (`https://dev.auth.ixo.earth/credentials/activity`) lists the save and the share in plain words.
- The credential's page shows who issued it, when it expires, whether it is revoked and who it was shared with.
- When the test operator revokes your Test Credential, the issuer republishes `test1` at once, verifiers see `revoked` within the list's `ttl` (60 seconds), and the Hub marks the credential as revoked.

## Troubleshooting

### No offer arrives

The worker refuses an offer for a DID that does not exist on devnet (`unknown_subject`), more than 2 waiting offers from one issuer for one person (`too_many_pending`), and offers from a sender you blocked (`blocked`). Check the DID is your devnet `did:ixo:ixo1…`, deal with waiting offers, and unblock the test issuer on the Sharing page if you blocked it.

### The request says "You don't have this yet"

The test verifier accepts only credentials from `did:web:test-issuer.dev.credentials.ixo.earth`. Save a Test Credential first; for "over 18" it must carry `age_over_18`.

## Next steps

- Build your own verifier against devnet: accept `did:web:test-issuer.dev.credentials.ixo.earth` and the `TestCredential` `vct`, and ask your own devnet account for proof. See [Request proof](/guides/dev/credentials/request-proof).
- Build your own issuer: deposit an offer for your own devnet DID and save it in the devnet Hub. See [Issue a credential](/guides/dev/credentials/issue-a-credential).
- Read every endpoint and error code in the [Credentials API reference](/guides/dev/credentials/api-reference).
