Quickstart.

Eight steps from nothing to a signed, publicly logged verification record. Typical setup is under ten minutes. You'll need an account and an API key from the dashboard.

How it works

  1. Register your database as a read-only system.
  2. Attest: snapshot what data exists for a subject (for example, a user's email).
  3. Delete the data in your own application. BurnLedger is not in the loop.
  4. Verify: BurnLedger re-queries and confirms the data is gone.
  5. A signed verification record is issued and appended to the public transparency log.

1 · Install the SDK

npm install burnledger
pip install burnledger

Published as burnledger on npm and burnledger on PyPI.

2 · Initialize the client

Use the API key from your dashboard (it starts with dp_).

import { BurnLedger } from "burnledger";

const dp = new BurnLedger({
  apiKey: process.env.BURNLEDGER_API_KEY,
  baseUrl: "https://api.burnledger.io",
});
import os
from burnledger import BurnLedger

dp = BurnLedger(
    api_key=os.environ["BURNLEDGER_API_KEY"],
    base_url="https://api.burnledger.io",
)

3 · Register your database

A system is a read-only connection to one of your data stores. Where the engine can report its own privileges — PostgreSQL among them — BurnLedger rejects credentials that have write access.

const system = await dp.registerSystem({
  name: "users-db",
  connectorType: "postgresql",
  dsn: "postgresql://readonly_user:password@db.example.com:5432/myapp?sslmode=verify-full",
  subjectQuery: "SELECT * FROM users WHERE email = $1",
  hashScope: "full",
});

console.log("System registered:", system.id);
system = dp.register_system(
    name="users-db",
    connector_type="postgresql",
    dsn="postgresql://readonly_user:password@db.example.com:5432/myapp?sslmode=verify-full",
    subject_query="SELECT * FROM users WHERE email = $1",
    hash_scope="full",
)

print("System registered:", system.id)

Read-only is enforced, not suggested. Registration fails if write access is detected on the credential — for PostgreSQL that check runs against pg_roles and the engine's own grant tables. Engines that cannot report their privileges require an explicit read_only assertion instead, and refuse to connect without one; each connector guide states which case applies. The subjectQuery uses $1 as the placeholder for the subject identifier; the placeholder syntax varies per connector.

TLS is required. The connection must reach verified TLS (certificate chain and hostname), or the connector is refused and every attestation against the system fails. For PostgreSQL that means ?sslmode=verify-full: omitted, the driver defaults to prefer, which silently falls back to plaintext. Each connector's own requirement is in its guide.

Supported connector types: postgresql, mysql, sqlserver, oracle, mongodb, redis, cassandra, neo4j, hbase, marklogic, elasticsearch, s3, dynamodb, redshift, bigquery, gcs, azure_blob, snowflake, databricks, teradata. Each has a full integration guide.

4 · Run a health check

Confirm BurnLedger can reach your database before creating attestations.

const health = await dp.healthCheck(system.id);
console.log("Status:", health.healthStatus); // "HEALTHY"
health = dp.health_check(system.id)
print("Status:", health.health_status)  # "HEALTHY"

5 · Create an attestation

An attestation is a signed snapshot of what data exists for a subject. Do this before deleting the data.

const attestation = await dp.attest("user@example.com", {
  systemIds: [system.id],
});

console.log("Attestation:", attestation.id);
console.log("Records found:", attestation.systems[0].recordCount);
attestation = dp.attest("user@example.com",
    system_ids=[system.id],
)

print("Attestation:", attestation.id)
print("Records found:", attestation.systems[0].record_count)

6 · Delete the data

Delete the subject's data using your own application logic. BurnLedger does not delete data; it only observes.

// Your application code. BurnLedger is not involved here.
await db.query("DELETE FROM users WHERE email = $1", ["user@example.com"]);
# Your application code. BurnLedger is not involved here.
cursor.execute("DELETE FROM users WHERE email = %s", ("user@example.com",))
conn.commit()

7 · Verify and get the verification record

Verification re-queries your database. If the records are gone, a signed verification record is issued and appended to the public transparency log. If they aren't, no verification record is issued.

const result = await dp.verify(attestation.id, "user@example.com");

if (result.status === "CERTIFIED") {
  console.log("Deletion confirmed!");
  console.log("Certificate:", result.certificate.id);

  // Download the PDF certificate
  await dp.savePdf(result.certificate.id, "./deletion-proof.pdf");
} else {
  console.log("Records still exist — deletion incomplete");
}
result = dp.verify(attestation.id, "user@example.com")

if result.status == "CERTIFIED":
    print("Deletion confirmed!")
    print("Certificate:", result.certificate.id)

    # Download the PDF certificate
    dp.save_pdf(result.certificate.id, "./deletion-proof.pdf")
else:
    print("Records still exist — deletion incomplete")

8 · Verify the verification record offline

Both SDKs include a burnledger CLI for offline verification: Ed25519 signatures, canonical JSON, and the Merkle inclusion proof are checked entirely on your machine, using only the verification record file and the published public keys. See Verify a record for the full third-party story.

# Download the certificate and the published public keys
curl -H "Authorization: Bearer $BURNLEDGER_API_KEY" \
  https://api.burnledger.io/v1/certificates/{id} -o certificate.json
curl https://api.burnledger.io/.well-known/burnledger-keys -o keys.json

# Verify offline
npx burnledger check --cert certificate.json --keys keys.json

# With online revocation check
npx burnledger check --cert certificate.json --keys keys.json \
  --online --api-url https://api.burnledger.io --api-key $BURNLEDGER_API_KEY

With the Python SDK installed, the command is burnledger check … instead of npx burnledger check ….

Optional: webhooks

Register a webhook to get notified when attestations and verification records are created.

const webhook = await dp.registerWebhook({
  url: "https://yourapp.com/webhooks/burnledger",
});

// Save this secret; it's only shown once
console.log("Webhook secret:", webhook.secret);
webhook = dp.register_webhook(
    url="https://yourapp.com/webhooks/burnledger",
)

# Save this secret; it's only shown once
print("Webhook secret:", webhook.secret)

Events you'll receive:

  • attestation.created: snapshot taken
  • attestation.verified: deletion confirmed, verification record issued
  • attestation.failed: records still exist
  • certificate.revoked: verification record was revoked
  • certificate.log_included: added to the transparency log
  • certificate.transparency_failed: inclusion was retried and then abandoned; transparency_status is FAILED and stays there until an operator re-runs inclusion. The record is still signed and verifies offline — it has no inclusion proof.
  • system.health_degraded / system.health_recovered: a registered system stopped answering health checks, or answered again

Deliveries are signed. Verify them with the SDK helper:

import { verifyWebhookSignature } from "burnledger";

const isValid = verifyWebhookSignature(
  webhookSecret,
  request.headers["x-burnledger-timestamp"],
  requestBody,
  request.headers["x-burnledger-signature"],
);
from burnledger import verify_webhook_signature

is_valid = verify_webhook_signature(
    webhook_secret,
    request.headers["X-BurnLedger-Timestamp"],
    request_body,
    request.headers["X-BurnLedger-Signature"],
)

Creating a read-only database user

PostgreSQL

CREATE ROLE burnledger_ro WITH LOGIN PASSWORD 'your_password';
GRANT CONNECT ON DATABASE myapp TO burnledger_ro;
GRANT USAGE ON SCHEMA public TO burnledger_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO burnledger_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO burnledger_ro;

MongoDB

db.createUser({
  user: "burnledger_ro",
  pwd: "your_password",
  roles: [{ role: "read", db: "myapp" }]
})

Environment variables

VariableDescription
BURNLEDGER_API_KEYYour API key (starts with dp_).
BURNLEDGER_API_URLAPI endpoint: https://api.burnledger.io.

Next

Read a verification record field by field in Verification Record anatomy, or hand one to a skeptic along with Verify a record.

© 2026 ProChatFlow LLC Last updated present → absent → proven