Issue a credential
One call turns an issuance profile plus claim data into a credential offer URI. Render it as a QR code or a link; the wallet does the rest.
Create an offer
Editions: SaaS · Self-hosted · Public
curl "$LUTRAID_API/v1/organizations/$ORG/issuers/$ISSUER/create-credential-offer" \
-H "X-API-Key: $LUTRAID_KEY" \
-H "Content-Type: application/json" \
-d '{
"issuanceProfileId": "8f1b…",
"userPinRequired": true,
"credentialOfferMode": "auto",
"data": [
{ "documentTypeId": "pid-sd-jwt", "credentialSubject": { "given_name": "Ana", "family_name": "Novak" } }
]
}'
{
"credentialOfferId": "3c9e…",
"credentialOffer": "openid-credential-offer://?credential_offer_uri=https%3A%2F%2F…",
"transactionCode": "418302"
}
- Name
issuanceProfileId- Type
- uuid
- Description
Required. The issuance profile assigned to this issuer; it decides formats, policies and grant type.
- Name
data- Type
- array
- Description
Required. One entry per document type:
documentTypeIdplus itscredentialSubjectclaims.
- Name
userPinRequired- Type
- boolean
- Description
Returns a
transactionCode. The holder types it into the wallet, which sends it astx_codeto the token endpoint.
- Name
credentialOfferMode- Type
- string
- Description
auto(recommended),by_valueorby_reference.
credentialOffer is an openid-credential-offer:// deep link. There is no QR endpoint — render the string yourself.
Offer modes
| Mode | Behaviour |
|---|---|
auto | By value while the encoded offer stays under 1000 characters, by reference above it |
by_value | Always inline — fails if the offer is too large |
by_reference | Always a credential_offer_uri the wallet fetches |
Use auto unless you have a wallet that cannot dereference credential_offer_uri.
Bulk offers
Editions: SaaS · Self-hosted
Same issuance profile, many recipients. Each entries[] item needs id, recipientEmail and data; the response is an array echoing id and recipientEmail alongside credentialOffer and transactionCode.
Next
The holder's wallet now exchanges the pre-authorized code at the token endpoint and fetches the credential. Watch it with issuance status, or switch to the authorization code flow when claims must come from a login instead of your request body.