Authorization code flow
Use this when the claims must come from an authenticated user at your identity provider instead of from your request body. LutraID acts as the authorization server; the holder signs in before the wallet may fetch the credential.
Create an offer
Request
curl "$LUTRAID_API/v1/organizations/$ORG/issuers/$ISSUER/create-authorization-code-offer" \
-H "X-API-Key: $LUTRAID_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $UNIQUE_RETRY_KEY" \
-d '{
"issuanceProfileId": "8f1b…",
"credentialOfferMode": "auto",
"attributeReference": "your-opaque-reference"
}'
{
"credentialOfferId": "…",
"historyId": "…",
"credentialOffer": "openid-credential-offer://?credential_offer_uri=https%3A%2F%2F…",
"deliveryMode": "direct",
"recipientEmail": null,
"deliveryStatus": "…",
"expiresAt": "2026-09-10T12:00:00.000Z"
}
- Name
issuanceProfileId- Type
- uuid
- Description
Required. Must reference a profile configured with an upstream OIDC identity provider and an attribute provider — ask the operator if you get a
404.
- Name
attributeReference- Type
- string
- Description
Optional opaque reference forwarded to the organization's configured attribute provider once the holder has logged in.
- Name
credentialOfferMode- Type
- string
- Description
auto(recommended),by_valueorby_reference.
There is no data and no userPinRequired on this endpoint — the claims are resolved at login time from the upstream provider configured on the issuance profile.
Retrying safely
Idempotency-Key (8–200 characters, ^[A-Za-z0-9._~:-]+$) is optional but recommended for retries:
| Replay | Result |
|---|---|
| Same key, same request body | Returns the original offer as 200 |
| Same key, a different request body | 409 |
Success on first creation is 201.
Which flow to pick
| Pre-authorized code | Authorization code | |
|---|---|---|
| Claims come from | your request body | the holder's login |
| Holder proves identity | transaction code, out of band | at your IdP |
| Status endpoint | yes | no |
What LutraID handles
Pushed authorization requests, the authorize and callback endpoints, PKCE, and the exchange with the upstream OIDC provider all run inside LutraID. Your only call is the one above.
Errors: 400, 404 (issuer or issuance profile not found), 409 (idempotency key conflict), 422 — see Errors.