Skip to main content
European CommissionEBSI European Blockchain

URL Encoding guidelines

The following URL Encoding definitions are used for the protocol related to OID4VP, OID4VCI and SIOPv2
Last updated on

The codec is designed for URI and URL components, as well as HTTP Request and Response payloads with the Content-Type of application/x-www-form-urlencoded.

Codec baseline

The baseline encoding method is Percent Encoding with adaptations for application/x-www-form-urlencoded. Decoding follows the same process in reverse.

For application/x-www-form-urlencoded, spaces ' ' are encoded as plus signns '+', newlines are encoded as '%0D%0A', and all characters except unreserved characters must be percent-encoded with in their UTF-8 representation.

Hierarchical and primitive values

Hierarchical data structures must be encoded into a single key=value pair. This applies to all top-level values containing a data structure. The encoding involves representing a JSON object or array as a UTF-8 string.

Primitive values are encoded directly without converting to JSON.

Examples

Authorisation Request as JSON Object
{
response_type: "code",
scope: "openid",
client_id: "did:key:z2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9KbsEYvdrjxMjQ4tpnje9BDBTzuNDP3knn6qLZErzd4bJ5go2CChoPjd5GAH3zpFJP5fuwSk66U5Pq6EhF4nKnHzDnznEP8fX99nZGgwbAh1o7Gj1X52Tdhf7U4KTk66xsA5r",
authorization_details: [{
type: "openid_credential",
format:"jwt_vc",
types:[
"VerifiableCredential",
"VerifiableAttestation",
"CTWalletInTime"
]
}],
redirect_uri: "openid:",
nonce: "glkFFoisdfEui43",
code_challenge: "YjI0ZTQ4NTBhMzJmMmZhNjZkZDFkYzVhNzlhNGMyZDdjZDlkMTM4YTY4NjcyMTA5M2Q2OWQ3YjNjOGJlZDBlMSAgLQo=",
code_challenge_method: "S256",
client_metadata: {
vp_formats_supported: {
jwt_vp: {
alg: ["ES256"]
},
jwt_vc: {
alg: ["ES256"]
}
},
response_types_supported: [
"vp_token",
"id_token"
],
authorization_endpoint: "openid:"
}
};
Authorisation Request as URL Encoded
response_type=code
&scope=openid
&client_id=did%3Akey%3Az2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9KbsEYvdrjxMjQ4tpnje9BDBTzuNDP3knn6qLZErzd4bJ5go2CChoPjd5GAH3zpFJP5fuwSk66U5Pq6EhF4nKnHzDnznEP8fX99nZGgwbAh1o7Gj1X52Tdhf7U4KTk66xsA5r
&authorization_details=%5B%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22jwt_vc%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22VerifiableAttestation%22%2C%22CTWalletInTime%22%5D%7D%5D
&redirect_uri=openid%3A
&nonce=glkFFoisdfEui43
&code_challenge=YjI0ZTQ4NTBhMzJmMmZhNjZkZDFkYzVhNzlhNGMyZDdjZDlkMTM4YTY4NjcyMTA5M2Q2OWQ3YjNjOGJlZDBlMSAgLQo%3D
&code_challenge_method=S256
&client_metadata=%7B%22vp_formats_supported%22%3A%7B%22jwt_vp%22%3A%7B%22alg%22%3A%5B%22ES256%22%5D%7D%2C%22jwt_vc%22%3A%7B%22alg%22%3A%5B%22ES256%22%5D%7D%7D%2C%22response_types_supported%22%3A%5B%22vp_token%22%2C%22id_token%22%5D%2C%22authorization_endpoint%22%3A%22openid%3A%22%7D

Encoding objects, arrays and primitives

Javascript Object
{
obj: {
a: 1,
b: 2
},
arr: [ 1, 2, 3 ],
a: 1,
b: '2',
c: ' '
}
URL Encoded
obj=%7B%22a%22%3A1%2C%22b%22%3A2%7D
&arr=%5B1%2C2%2C3%5D
&a=1
&b=2
&c=+

Javascript example

The URLSearchParams API can be used for application/x-www-form-urlencoded. All top-level data structures must be JSON stringified in UTF-8 before encoding.

function jsonStringifyNotPrimitive([key, value]) {
if (value == null) {
// filter out null and undefined values
return null;
}
if (typeof value === "object") {
// this includes arrays
return [key, JSON.stringify(value)];
}
return [key, value];
}

function encodeObject(o) {
return new URLSearchParams(
Object.fromEntries(
Object.entries(o).map(jsonStringifyNotPrimitive).filter(Boolean),
),
).toString();
}

This function jsonStringifyNotPrimitive ensures that objects and arrays are JSON stringified, while primitive values are encoded directly. The encodeObject function then creates a URL-encoded string suitable for use in HTTP requests.