FortID LogoFortID

Credential Issuance

Manage the process of creating and issuing verifiable credentials.

Initiate the issuance session with an external wallet using pre-authorized or authorization code flow.

POST
/control/issuer/{issuerId}/initiate

This API is intended to be called when attempting to initiate an issuance session with an external wallet (holder) via the pre-authorized code or authorization_code variants of an OpenID for Verifiable Credential Issuance protocol.

To do so, the caller should essentially:

  1. Provide the credential data that should be issued. This is done by providing a credentialData object in the request.
  2. Configure the protocol details. This is done by providing a protocolConfig object in the request.

Additionally, if the Issuer is configured as such, the status of the credential will be added to the end of this Issuer's status list. It will have a default value of 0 (VALID).

Credential Data

Providing a credentialData object is required when initiating an issuance session. Within this object, the caller should specify the credentialConfigurationId of the credential as well as the set of claims that are about to be issued.

More precisely, the credentialData object should consist of:

  • credentialConfigurationId — the unique identifier of the credential configuration that the to-be-issued credential adheres to. The provided credentialConfigurationId must have already been assigned to the issuer that is issuing the credential (i.e. served on the appropriate metadata endpoints).
  • claims — an object containing credential claims that will be issued and that adhere to the provided credential configuration and its underlying credential format and schema. The Authorization Code Flow allows partial definition of claims, while remaining claims can be set on /protocol/oid4vci/issuer/{issuerId}/credential endpoint through JWT Access Token using data provided by Authorization Server.

All fields expecting byte array values must be encoded in Base64.

Protocol Configuration

Specifying the protocolConfig object allows the user to define low-level issuance protocol details. Providing this object is optional and, if omitted, the Issuer Service will default to protocol configuration interoperable with EUDI Android Reference implementation.

Currently, the user can define the following protocol details:

  • grant_type — defining the flavour of the OAuth2.0 Grant Type in the context of the pre-authorized code flow. This value can either be "PreAuthorizedCode" or "PreAuthorizedCodeWithoutTxCode". If omitted, the Issuer Service will default to "PreAuthorizedCode".

In the authorization code flow, this value must be an AuthorizationCode object that includes an issuer_state parameter, although issuer_state is optional in the specification. The Wallet retrieves it and forwards its value to the Authorization Server. Issuer owner can insert JSON inside issuer_state using issuer_state_payload and use it on Authorization Server for additional checks. The Issuer Service expects issuer_state as part of JWT Access Token on /protocol/oid4vci/issuer/{issuerId}/credential endpoint.

Response

Based on the provided credential data and protocol configuration, the Issuer Service will create a new issuance session, prepare the corresponding Credential Offer data and serve it on an appropriate Protocol API endpoint.

In the response, the caller will obtain the following:

  • sessionId — representing the unique identifier of the newly-created issuance session.
  • credentialOfferUri — a string instructing the external wallet to obtain the Credential Offer by reference. The caller must communicate this string (e.g. via a QR code) to the wallet.
  • statusPointer (optional) — a pointer to the status of the credential that is to be issued.

Once the wallet obtains the Credential Offer, the remainder of the issuance protocol is done directly between the Issuer Service and the wallet through the appropriate Protocol APIs. The Authorization Code Flow also involves Authorization Server defined through /control/issuer/{issuerId}/add-schema endpoint.

The caller can gain additional information about the issuance session status through the /control/issuer/{issuerId}/get-session-status/{sessionId} endpoint.

Path Parameters

issuerId*string

An ID of the Credential Issuer for the protocol session that is being initiated.

Header Parameters

X-API-KEY*string

API key for authenticating requests to the Issuer Service.

Request Body

application/json

credentialData*

An object defining the claims that ought to be issued as well as the credential configuration they adhere to.

protocolConfig?

Object defining low-level issuance protocol details

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://eis.fortid.com/control/issuer/fortid_issuer/initiate" \  -H "X-API-KEY: HCLN4ZKnWYJAfyNkDnQ57gEAHuejD6MN" \  -H "Content-Type: application/json" \  -d '{    "credentialData": {      "credentialConfigurationId": "eu.europa.ec.eudi.pid_mdoc",      "claims": {        "eu.europa.ec.eudi.pid.1": {          "birth_date": "1980-05-23",          "place_of_birth": "DE",          "expiry_date": "2026-05-23T12:12:12Z",          "family_name": "Doe",          "given_name": "John",          "issuance_date": "2024-05-23T12:12:12Z",          "issuing_authority": "DE",          "issuing_country": "DE",          "nationality": [            "FR"          ],          "resident_city": "Rome",          "resident_country": "IT",          "resident_postal_code": "00100",          "resident_street": "123 via Appia",          "sex": 5        }      }    }  }'
{
  "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",
  "authCodeOrPreAuth": {
    "grant_type": "urn:ietf:params:oauth:grant-type:pre-authorized_code",
    "pre-authorized_code": "string",
    "tx_code": "string"
  },
  "credentialOfferUri": "openid-credential-offer%3A%2F%2F%3Fcredential_offer_uri%3Dhttps%3A%2F%2Feis.fortid.com%2Fprotocol%2Foid4vci%2Fissuer%2Fmup%2Fcredential-offer%2F36dcdb3e-35bd-4362-bf67-472efa0cf744",
  "statusPointer": {
    "statusListId": "72e8b5a7-e190-4751-827d-dfc014e833bc",
    "statusListIndex": 0
  }
}
{
  "message": "Missing mandatory field `birth_date`"
}
Empty
Empty
{
  "message": "Issuer not found"
}
{
  "message": "string"
}