Self-service is a share-link flow: you publish a URL, an end-user opens it on their own device, submits whatever data the form asks for (or proves their identity through DeepID), and lands in your decision queue. You approve, the credential ships to their wallet.
This page walks you through the smallest possible integration — enough to issue your first credential. Detailed semantics, edge cases and full webhook payloads live in the Detailed Reference; a fully-worked, presentation-friendly example is in Walkthrough — City Card.
Two choices in the portal under Credential Definitions:
- Use a System Credential Definition — platform-provided starter shapes (e.g. City Card) you can issue as-is, or clone into your workspace if you want to extend the schema.
- Create your own credential definition from scratch when none of the system shapes fit — declare the claims, their value types, and which are mandatory.
(Official Credential Definitions — Swiss e-ID, driver licences, etc — are issued by the federation and live in the catalog only so you can verify them. You can't issue them yourself.)
You only need the credential definition's id in the next step.
In the portal: Self-Service → New config. Pick:
- Credential Definition — the one from step 1.
- Verification mode —
webhookif your backend decides each request;manualif your team clicks Approve in the portal;automaticfor self-asserted data with no review. - Identification (optional) — if enabled, end-users prove identity through DeepID before the form. DeepID handles the method choice (e-ID, QES, passport-based verification, …) on its side — your config only picks which methods are acceptable. The verified attributes can be mapped onto credential definition claims so the credential is pre-filled — no typing required.
- Credential validity — how long the issued credential's
expclaim lasts (or "never expires").
Provision a service user with the deepcredentials.self-service scope (see Authentication — Service Users) and, if you picked webhook mode, register a webhook endpoint that listens for self_service.request.* events.
Share the slug-URL with your users.
Your backend's job in webhook mode is two HTTP calls per request. The self_service.request.submitted event carries only the request id — fetch the snapshot, then post your decision.
Fetch the snapshot (claims already pre-filled from identification, if any):
- Developmenthttps://api.dev.deepcredentials.swiss/b2b/v1/self-service/requests/{requestId}
- Integrationhttps://api.int.deepcredentials.swiss/b2b/v1/self-service/requests/{requestId}
curl -i -X GET \
'https://api.dev.deepcredentials.swiss/b2b/v1/self-service/requests/{requestId}' \
-H 'Authorization: Bearer <YOUR_JWT_HERE>' \
-H 'X-Environment: beta' \
-H 'X-Org-Id: 497f6eca-6276-4993-bfeb-53cbbbba6f08'Approve. admin_claims is optional — supply any keys you want to fill or override; omit the body entirely for a pass-through approval.
- Developmenthttps://api.dev.deepcredentials.swiss/b2b/v1/self-service/requests/{requestId}/decision
- Integrationhttps://api.int.deepcredentials.swiss/b2b/v1/self-service/requests/{requestId}/decision
curl -i -X POST \
'https://api.dev.deepcredentials.swiss/b2b/v1/self-service/requests/{requestId}/decision' \
-H 'Authorization: Bearer <YOUR_JWT_HERE>' \
-H 'Content-Type: application/json' \
-H 'X-Environment: beta' \
-H 'X-Org-Id: 497f6eca-6276-4993-bfeb-53cbbbba6f08' \
-d '{
"decision": "approve",
"admin_claims": {
"is_employee": true
}
}'manual mode skips this entirely — your team uses Approve/Reject buttons in the portal. automatic mode skips both human and backend.
After approve, the end-user receives the credential offer (deeplink and/or email link), the wallet picks it up, and you get one more webhook — self_service.request.credential_issued — to close the loop.
- Identification pre-fill — claims mapped to identification attributes flow into the snapshot automatically; admins can override at decide time. See Walkthrough — City Card for the full setup and Detailed Reference → Identification mapping for the override rules.
- Manual / automatic modes — see the modes table in the Detailed Reference.
- Rejecting a request — POST
{"decision": "reject", "reason": "..."}instead. The reason is shown to the end-user verbatim. - Idempotency, retries, terminal states, error codes — Detailed Reference.
- Walkthrough — City Card — a concrete end-to-end example, presentation-friendly.
- Detailed Reference — every state, every event, every error code.
- Webhooks — signature verification, event subscriptions, secret rotation.