curl --request GET \
--url https://api.baselayer.com/issuance/audit_log \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.baselayer.com/issuance/audit_log"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.baselayer.com/issuance/audit_log', 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/audit_log",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"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"
"net/http"
"io"
)
func main() {
url := "https://api.baselayer.com/issuance/audit_log"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.baselayer.com/issuance/audit_log")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.baselayer.com/issuance/audit_log")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body[
{
"seq": 123,
"event": {
"occurred_at": "2023-11-07T05:31:56Z",
"event_type": "issuance",
"jti": "<string>",
"audience": "<string>",
"issued_at": "2023-11-07T05:31:56Z",
"expires_at": "2023-11-07T05:31:56Z",
"signing_kid": "<string>",
"individual_ref": "<string>",
"level": "L2",
"schema_version": 3,
"linked_jti": "<string>",
"business_ref": "<string>",
"disclosed_fields": [],
"disclosure_mode": "CLEARTEXT_AND_HASH",
"preset": "<string>",
"active_keys": [],
"agent_key_thumbprint": "<string>",
"source_environment": "sandbox"
}
}
]{
"type": "resource_not_found",
"code": 1,
"message": "Could not locate the resource for the given URI.",
"metadata": {}
}{
"type": "invalid_audit_log_query",
"code": 6310,
"message": "The audit-log query requires at least one of individual_ref, business_ref, or credential_id to scope the read to your organization's own refs, and event_type (when given) must be one this route exposes.",
"metadata": {}
}Read the calling organization's slice of the audit log
Returns identity registration, credential issuance, and revocation events, scoped to an individual_ref, business_ref, or credential_id your organization already holds — at least one is required. Reads the sequenced log, which the batch sequencer populates asynchronously, so very recent events may lag slightly behind the fast-store freshness path.
curl --request GET \
--url https://api.baselayer.com/issuance/audit_log \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.baselayer.com/issuance/audit_log"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.baselayer.com/issuance/audit_log', 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/audit_log",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"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"
"net/http"
"io"
)
func main() {
url := "https://api.baselayer.com/issuance/audit_log"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.baselayer.com/issuance/audit_log")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.baselayer.com/issuance/audit_log")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body[
{
"seq": 123,
"event": {
"occurred_at": "2023-11-07T05:31:56Z",
"event_type": "issuance",
"jti": "<string>",
"audience": "<string>",
"issued_at": "2023-11-07T05:31:56Z",
"expires_at": "2023-11-07T05:31:56Z",
"signing_kid": "<string>",
"individual_ref": "<string>",
"level": "L2",
"schema_version": 3,
"linked_jti": "<string>",
"business_ref": "<string>",
"disclosed_fields": [],
"disclosure_mode": "CLEARTEXT_AND_HASH",
"preset": "<string>",
"active_keys": [],
"agent_key_thumbprint": "<string>",
"source_environment": "sandbox"
}
}
]{
"type": "resource_not_found",
"code": 1,
"message": "Could not locate the resource for the given URI.",
"metadata": {}
}{
"type": "invalid_audit_log_query",
"code": 6310,
"message": "The audit-log query requires at least one of individual_ref, business_ref, or credential_id to scope the read to your organization's own refs, and event_type (when given) must be one this route exposes.",
"metadata": {}
}Authorizations
Query Parameters
The kinds of event recorded in the tamper-evident audit log.
Consumption dominates by volume — it fires on every agent request to
every merchant.
This diverges deliberately from the original brief's "five event types". Consent was dropped (it went unused), and the two categories that the brief treated as single types each carry genuinely different payloads, so they are split rather than discriminated inside one type:
- registration — a counterparty publishing its disclosure profile is unrelated to a person completing identity verification;
- revocation — one short-lived credential killed by
jti. Nothing withdraws a subject's authority to mint, so this is the only shape.
Because event_type is a VARCHAR column rather than a native Postgres
enum, adding or renaming a member here needs no migration.
issuance, consumption, identity_registration, counterparty_registration, credential_revocation, credential_mint_failed, operator_link_decision, internal_join, acceptance_audiences_changed, acceptance_browser_key_changed Maximum number of records to return in a single page. Must be between 1 and 1000.
1 <= x <= 1000Number of records to skip from the beginning. Use 0 for the first page. Cannot be used with cursor.
x >= 0Opaque pagination cursor token that identifies the position in the result set. Use the cursor from the previous response to get the next page. Cannot be used with offset.
occurred_at: the entry's created_at, when it was recorded in the log, with seq breaking ties. Defaults to occurred_at desc.
What the audit log sorts by.
occurred_at asc or desc, for every key of the sort. Defaults to the field's own: occurred_at desc.
asc, desc Response
Audit-log entries in the requested order.