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.

The devnet services

ServiceAddressDID
Credentials workerhttps://dev.credentials.ixo.earth (API reference)did:web:dev.credentials.ixo.earth
Auth Hub wallethttps://dev.auth.ixo.earth/credentials
Test issuerhttps://test-issuer.dev.credentials.ixo.earthdid:web:test-issuer.dev.credentials.ixo.earth
Test verifierhttps://test-verifier.dev.credentials.ixo.earth (API reference)did:web:test-verifier.dev.credentials.ixo.earth

The test issuer issues one type:

FieldValue
Configuration idTestCredential (dc+sd-jwt, signed with Ed25519, bound to a did:ixo key)
vcthttps://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
Lifetime30 days, with a status list entry for every credential
Status listhttps://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:

curl -s https://dev.credentials.ixo.earth/health
curl -s https://dev.credentials.ixo.earth/.well-known/did.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:

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
{
  "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:

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
{
  "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.

mkdir credentials-try && cd credentials-try
npm init -y && npm pkg set type=module
npm install @ixo/credentials-kit@0.1.1
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');
node check-status.mjs
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 or send it to 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.
  • Build your own issuer: deposit an offer for your own devnet DID and save it in the devnet Hub. See Issue a credential.
  • Read every endpoint and error code in the Credentials API reference.