curl --request POST \
--url https://api.baselayer.com/issuance/credentials/preview \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"audience": "<string>",
"individual_ref": "<string>",
"type": "INDIVIDUAL",
"format": "dc+sd-jwt",
"level": "L3",
"ttl_seconds": 1,
"disclosed_fields": [
"<string>"
],
"disclosure_mode": "CLEARTEXT_AND_HASH",
"agent_key": {
"x": "<string>",
"kty": "OKP",
"crv": "Ed25519",
"kid": "<string>"
}
}
'import requests
url = "https://api.baselayer.com/issuance/credentials/preview"
payload = {
"audience": "<string>",
"individual_ref": "<string>",
"type": "INDIVIDUAL",
"format": "dc+sd-jwt",
"level": "L3",
"ttl_seconds": 1,
"disclosed_fields": ["<string>"],
"disclosure_mode": "CLEARTEXT_AND_HASH",
"agent_key": {
"x": "<string>",
"kty": "OKP",
"crv": "Ed25519",
"kid": "<string>"
}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
audience: '<string>',
individual_ref: '<string>',
type: 'INDIVIDUAL',
format: 'dc+sd-jwt',
level: 'L3',
ttl_seconds: 1,
disclosed_fields: ['<string>'],
disclosure_mode: 'CLEARTEXT_AND_HASH',
agent_key: {x: '<string>', kty: 'OKP', crv: 'Ed25519', kid: '<string>'}
})
};
fetch('https://api.baselayer.com/issuance/credentials/preview', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.baselayer.com/issuance/credentials/preview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'audience' => '<string>',
'individual_ref' => '<string>',
'type' => 'INDIVIDUAL',
'format' => 'dc+sd-jwt',
'level' => 'L3',
'ttl_seconds' => 1,
'disclosed_fields' => [
'<string>'
],
'disclosure_mode' => 'CLEARTEXT_AND_HASH',
'agent_key' => [
'x' => '<string>',
'kty' => 'OKP',
'crv' => 'Ed25519',
'kid' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.baselayer.com/issuance/credentials/preview"
payload := strings.NewReader("{\n \"audience\": \"<string>\",\n \"individual_ref\": \"<string>\",\n \"type\": \"INDIVIDUAL\",\n \"format\": \"dc+sd-jwt\",\n \"level\": \"L3\",\n \"ttl_seconds\": 1,\n \"disclosed_fields\": [\n \"<string>\"\n ],\n \"disclosure_mode\": \"CLEARTEXT_AND_HASH\",\n \"agent_key\": {\n \"x\": \"<string>\",\n \"kty\": \"OKP\",\n \"crv\": \"Ed25519\",\n \"kid\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.baselayer.com/issuance/credentials/preview")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"audience\": \"<string>\",\n \"individual_ref\": \"<string>\",\n \"type\": \"INDIVIDUAL\",\n \"format\": \"dc+sd-jwt\",\n \"level\": \"L3\",\n \"ttl_seconds\": 1,\n \"disclosed_fields\": [\n \"<string>\"\n ],\n \"disclosure_mode\": \"CLEARTEXT_AND_HASH\",\n \"agent_key\": {\n \"x\": \"<string>\",\n \"kty\": \"OKP\",\n \"crv\": \"Ed25519\",\n \"kid\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.baselayer.com/issuance/credentials/preview")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"audience\": \"<string>\",\n \"individual_ref\": \"<string>\",\n \"type\": \"INDIVIDUAL\",\n \"format\": \"dc+sd-jwt\",\n \"level\": \"L3\",\n \"ttl_seconds\": 1,\n \"disclosed_fields\": [\n \"<string>\"\n ],\n \"disclosure_mode\": \"CLEARTEXT_AND_HASH\",\n \"agent_key\": {\n \"x\": \"<string>\",\n \"kty\": \"OKP\",\n \"crv\": \"Ed25519\",\n \"kid\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"environment": "sandbox",
"ttl_capped": true,
"credentials": [
{
"role": "subject",
"disclosed": [
{
"path": "<string>",
"value": "<unknown>",
"hashed": true
}
],
"missing_paths": [
"<string>"
],
"expires_at": "2023-11-07T05:31:56Z",
"active_keys": [
"<string>"
],
"authorization": {
"status": "verified",
"basis": "evidence",
"confirmed_at": "2023-11-07T05:31:56Z"
}
}
]
}{
"type": "resource_not_found",
"code": 1,
"message": "Could not locate the resource for the given URI.",
"metadata": {}
}{
"type": "credential_snapshot_not_current",
"code": 6301,
"message": "The subject's verified-identity snapshot is superseded or expired; re-verify before minting.",
"metadata": {}
}{
"type": "invalid_credential_mint_payload",
"code": 6303,
"message": "The credential mint payload failed validation.",
"metadata": {}
}Preview what an L3 mint would disclose
Takes the mint body and returns the exact leaves an L3 mint with the same body would disclose, and the requested paths with nothing on file, one entry per credential the mint would produce. A business preview also returns the operator authorization the credential always carries. Runs the mint’s validation and refusals; signs, stores and allocates nothing.
curl --request POST \
--url https://api.baselayer.com/issuance/credentials/preview \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"audience": "<string>",
"individual_ref": "<string>",
"type": "INDIVIDUAL",
"format": "dc+sd-jwt",
"level": "L3",
"ttl_seconds": 1,
"disclosed_fields": [
"<string>"
],
"disclosure_mode": "CLEARTEXT_AND_HASH",
"agent_key": {
"x": "<string>",
"kty": "OKP",
"crv": "Ed25519",
"kid": "<string>"
}
}
'import requests
url = "https://api.baselayer.com/issuance/credentials/preview"
payload = {
"audience": "<string>",
"individual_ref": "<string>",
"type": "INDIVIDUAL",
"format": "dc+sd-jwt",
"level": "L3",
"ttl_seconds": 1,
"disclosed_fields": ["<string>"],
"disclosure_mode": "CLEARTEXT_AND_HASH",
"agent_key": {
"x": "<string>",
"kty": "OKP",
"crv": "Ed25519",
"kid": "<string>"
}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
audience: '<string>',
individual_ref: '<string>',
type: 'INDIVIDUAL',
format: 'dc+sd-jwt',
level: 'L3',
ttl_seconds: 1,
disclosed_fields: ['<string>'],
disclosure_mode: 'CLEARTEXT_AND_HASH',
agent_key: {x: '<string>', kty: 'OKP', crv: 'Ed25519', kid: '<string>'}
})
};
fetch('https://api.baselayer.com/issuance/credentials/preview', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.baselayer.com/issuance/credentials/preview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'audience' => '<string>',
'individual_ref' => '<string>',
'type' => 'INDIVIDUAL',
'format' => 'dc+sd-jwt',
'level' => 'L3',
'ttl_seconds' => 1,
'disclosed_fields' => [
'<string>'
],
'disclosure_mode' => 'CLEARTEXT_AND_HASH',
'agent_key' => [
'x' => '<string>',
'kty' => 'OKP',
'crv' => 'Ed25519',
'kid' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.baselayer.com/issuance/credentials/preview"
payload := strings.NewReader("{\n \"audience\": \"<string>\",\n \"individual_ref\": \"<string>\",\n \"type\": \"INDIVIDUAL\",\n \"format\": \"dc+sd-jwt\",\n \"level\": \"L3\",\n \"ttl_seconds\": 1,\n \"disclosed_fields\": [\n \"<string>\"\n ],\n \"disclosure_mode\": \"CLEARTEXT_AND_HASH\",\n \"agent_key\": {\n \"x\": \"<string>\",\n \"kty\": \"OKP\",\n \"crv\": \"Ed25519\",\n \"kid\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.baselayer.com/issuance/credentials/preview")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"audience\": \"<string>\",\n \"individual_ref\": \"<string>\",\n \"type\": \"INDIVIDUAL\",\n \"format\": \"dc+sd-jwt\",\n \"level\": \"L3\",\n \"ttl_seconds\": 1,\n \"disclosed_fields\": [\n \"<string>\"\n ],\n \"disclosure_mode\": \"CLEARTEXT_AND_HASH\",\n \"agent_key\": {\n \"x\": \"<string>\",\n \"kty\": \"OKP\",\n \"crv\": \"Ed25519\",\n \"kid\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.baselayer.com/issuance/credentials/preview")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"audience\": \"<string>\",\n \"individual_ref\": \"<string>\",\n \"type\": \"INDIVIDUAL\",\n \"format\": \"dc+sd-jwt\",\n \"level\": \"L3\",\n \"ttl_seconds\": 1,\n \"disclosed_fields\": [\n \"<string>\"\n ],\n \"disclosure_mode\": \"CLEARTEXT_AND_HASH\",\n \"agent_key\": {\n \"x\": \"<string>\",\n \"kty\": \"OKP\",\n \"crv\": \"Ed25519\",\n \"kid\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"environment": "sandbox",
"ttl_capped": true,
"credentials": [
{
"role": "subject",
"disclosed": [
{
"path": "<string>",
"value": "<unknown>",
"hashed": true
}
],
"missing_paths": [
"<string>"
],
"expires_at": "2023-11-07T05:31:56Z",
"active_keys": [
"<string>"
],
"authorization": {
"status": "verified",
"basis": "evidence",
"confirmed_at": "2023-11-07T05:31:56Z"
}
}
]
}{
"type": "resource_not_found",
"code": 1,
"message": "Could not locate the resource for the given URI.",
"metadata": {}
}{
"type": "credential_snapshot_not_current",
"code": 6301,
"message": "The subject's verified-identity snapshot is superseded or expired; re-verify before minting.",
"metadata": {}
}{
"type": "invalid_credential_mint_payload",
"code": 6303,
"message": "The credential mint payload failed validation.",
"metadata": {}
}Authorizations
Body
- IndividualCredentialPreviewRequest (v1)
- BusinessCredentialPreviewRequest (v1)
The individual mint body, so one body previews and then mints.
agent_key is optional and unused; a preview is L3 only.
The counterparty the credential is scoped to: a bare domain (login.example.com), or an https authorization-server identifier (https://login.example.com) kept whole, which derives a different pairwise subject than the bare host. Paths, queries, fragments and non-default ports are refused.
1 - 512Pairwise reference to the verified individual, as issued to the calling organization at verification completion.
1 - 255INDIVIDUAL: the person as themselves.
"INDIVIDUAL"Credential wire format. dc+sd-jwt (media type application/dc+sd-jwt, draft-ietf-oauth-sd-jwt-vc-19 §2.1) is the only format issued.
dc+sd-jwt Credential layer to mint (defaults to L3): L2 (audience-scoped pairwise DID) or L3 (selectively disclosed verified identity).
L2, L3 Maximum credential validity in seconds, capped at supporting evidence expiry. Omitted or null uses the server default (3600 seconds). Must not exceed the configured maximum (86400 seconds by default). Applies to L2 and L3.
x > 0L3 only: the dotted disclosure paths the subject credential should carry, e.g. email or hashes.email. A business mint lists business paths here and the actor credential's paths, e.g. given_name, in actor_disclosed_fields.
64L3 only: disclose a use case's fields instead of listing disclosed_fields; never both. GET /issuance/credentials/presets lists each preset's paths. A preset always shares values in the clear, and B2B presets need a business mint.
consumer_ecommerce, age_gated, consumer_regulated, b2b_ecommerce, b2b_regulated L3 disclosure mode: CLEARTEXT_AND_HASH (default) discloses requested fields as cleartext alongside their recognition hashes; HASH_ONLY discloses only the recognition hashes.
CLEARTEXT_AND_HASH, HASH_ONLY Accepted so a mint body previews unchanged; a preview binds no key.
Show child attributes
Show child attributes
Response
Response
Body of POST /issuance/credentials/preview: what a mint with the same body
would disclose, without signing, storing or allocating anything. The
mint response's shape, with leaves in place of the credential strings.
The environment the mint would run in.
sandbox, production Whether supporting evidence expiry would shorten the requested validity.
The credentials a mint would produce, subject first.
Show child attributes
Show child attributes