BUILD · QUICKSTART · ISSUE
What issuing requires, in the order it actually happens.
Issuing a credential is four steps, and they run in a fixed order because each one
needs the answer from the one before it. Two of the four are open reads any machine can
run right now. Two need a real issuer relationship and a real wallet, and this page says
so rather than pretending a curl line could stand in for either.
The wire, drawn.
A wallet never guesses what an issuer offers. It asks first, in the open, before anyone is asked for anything.
The four steps
-
01
Discover what this issuer can issue
An open read, no key required. It names the credential format, the claims, and how many configurations exist — one, today.
witnessed against the live cell/.well-known/openid-credential-issuercurl -s https://id.orbis.id/.well-known/openid-credential-issuerReached on 2026-08-30. The full response, with the schema it describes, is on the credential-types page. -
02
Discover how to get a token
A second open read. It names the grant a wallet uses to redeem a credential offer — the pre-authorized-code grant, and nothing that asks a browser to hold a secret.
witnessed against the live cell/.well-known/oauth-authorization-servercurl -s https://id.orbis.id/.well-known/oauth-authorization-serverReached on 2026-08-30. -
03
Exchange a pre-authorized code for a credential
Not witnessed here. A code only exists once an issuer relationship exists, and handing one out is not a self-service action today — the same limit the credential-types page names for adding a second credential type. This step is real and tested in the platform's own suite; it is described, not printed as a command, because no reader of this page has been handed a code to redeem.
-
04
A wallet stores it, bound to a device key
The credential that comes back names the holder's public key in its
cnfclaim. From that point the credential is only useful on the device that holds the matching private key. Not witnessed here either — see the wallet quickstart for what a wallet does with what it receives.
Sandbox and production are not the same tenant wearing a label
Before you issue anything, know which plane your tenant is on — a reader checks this the
same way a verifier does, from two fields inside the signature itself, not from a name
someone typed. A production tenant's identity resolves as
did:web:<host>:t:<slug>; a sandbox tenant's resolves as
did:web:<host>:sandbox:t:<slug>, and every credential it issues
carries a matching vct segment. The two shapes are disjoint by construction —
there is no slug that lands a production tenant in the sandbox path or lets a sandbox
tenant escape it — and the production verify path refuses a sandbox credential by a named
reason, sandbox-credential, rather than a silent reject.
A slug prefix and a display-name marker still exist alongside this — the convention an older platform relied on — but neither is what a verifier's decision runs on any more. Bookkeeping can be misread or renamed; a field inside a signed credential cannot be edited without invalidating the signature. This is one place this build's own engineering goes further than the naming convention the harvested developer documentation describes.
What is real here.
Discovery is real and answers today. The exchange that follows it is implemented and tested, but not witnessable from this page — it needs an issuer relationship and a wallet that neither this page nor its reader holds.
- PLANNED A wallet a person installs from an app store. wallet-native You cannot hold a credential on a phone you own. Everything a person would do with a proof waits behind this.
The register holds 17 live · 2 partial · 2 planned · 5 not yet.
5 of the 6 capabilities this page depends on have no row in the register yet, so this page will not print a state for them. They are named rather than dropped, because a slice that silently shortens itself is the same defect as a claim with no receipt.
- vc-issuance
- oauth-metadata
- issuance-flow
- selective-disclosure
- sandbox-separation
The register route serves, but it carries no row for these yet. List what it does carry:
curl -s https://id.orbis.id/api/site/register | jq -r '.entries[].slug' Straight answers
- Can I get a credential just by running the two commands above?
- No. They tell you what is on offer and how a token is granted — they do not grant you one.
- Is step 3 real, or aspirational?
- Real. It is implemented and covered by its own test suite. It is simply not something an anonymous reader of this page can trigger.
- Do I need to write my own wallet to test issuance?
- To see it end to end, yes, or use one that already speaks OpenID4VCI. There is no browser demo on this page standing in for that.
- Can a sandbox credential ever verify as production?
- No. The two planes use disjoint identifier shapes, and the production verify path refuses a sandbox credential by name.
Do not trust us. Check us.