Customer developer docs

Vault API reference

Reference the customer-facing endpoints for clearance, polling, policy registration, settings, reviews, and verification.

Vault API reference

Vault is the customer-facing Ledgix API. Use it directly when you are not relying on one of the SDKs, or when you need to automate tenant settings, review, reports, or drift operations from your own systems.

Authentication

Send your tenant API key on every authenticated request:

text
X-Vault-API-Key: sk_prod_example

Unauthenticated endpoints:

  • GET /health
  • GET /.well-known/jwks.json
  • GET /reports/shared/{token} and GET /reports/shared/{token}/artifacts/{format}

Admin operator endpoints require a Bearer token or X-Admin-API-Key and live under /admin/.... They are not part of the customer surface documented here.

Endpoint map

FieldTypeRequiredDescription
POST /request-clearanceDecisionYesRequest approval before a sensitive action runs.
GET /clearance-status/{requestID}DecisionNoPoll a request that is still processing or waiting on review.
POST /consume-tokenDecisionNoVerify and burn an A-JWT at the tool boundary. Returns 409 on replay.
POST /register-policyPolicyNoRegister a compact structured policy over HTTP.
GET /review-settingsSettingsNoRead the current minimum confidence threshold.
PUT /review-settingsSettingsNoUpdate the threshold used for manual review routing.
GET /notification-settingsSettingsNoRead current email and Slack notification settings.
PUT /notification-settingsSettingsNoUpdate email and Slack notification settings.
GET /reviewsReviewNoList current review items for your tenant.
POST /reviews/{requestID}/decisionReviewNoApprove or deny a paused request.
GET /report-settingsReportsNoRead the compliance report configuration.
PUT /report-settingsReportsNoUpdate the compliance report configuration.
GET /reportsReportsNoList compliance reports for the tenant.
POST /reportsReportsNoGenerate a new compliance report.
GET /reports/{reportID}ReportsNoRetrieve a single report record.
GET /reports/{reportID}/artifacts/{format}ReportsNoDownload a report artifact (pdf, json, etc).
POST /reports/{reportID}/shareReportsNoMint a signed share token for external reviewers.
GET /drift/settingsDriftNoRead drift detection configuration.
PUT /drift/settingsDriftNoUpdate drift detection configuration.
GET /drift/summaryDriftNoCurrent drift risk summary across agents.
GET /drift/eventsDriftNoList drift detection events.
POST /drift/agents/{agentID}/lockdownDriftNoLock down an agent so further clearance requests fail closed.
DELETE /drift/agents/{agentID}/lockdownDriftNoRelease an agent lockdown.
GET /.well-known/jwks.jsonVerificationNoFetch the Ed25519 public keys used to verify A-JWTs.
GET /ledgerVerificationNoList recent request records.
GET /ledger/verifyVerificationNoRun a full Merkle verification pass over the ledger.
GET /ledger/verification-summaryVerificationNoCompact verification status: anchor state, key versions, last-verified timestamp.
GET /ledger/checkpointsVerificationNoList sealed Merkle checkpoints.
GET /ledger/manifestsVerificationNoAlias for checkpoints — returns the same manifest stream.
GET /ledger/proof/inclusionVerificationNoInclusion proof for a single ledger entry.
GET /ledger/proof/consistencyVerificationNoConsistency proof between two checkpoints.
GET /ledger/proof/bundleVerificationNoCombined proof bundle for one request.

Request clearance

Request body

FieldTypeRequiredDescription
tool_namestringYesThe exact action you want Ledgix to approve.
tool_argsobjectYesThe exact arguments that will be used if the action executes.
agent_idstringYesYour agent or service identity.
session_idstringNoOptional workflow or session grouping ID.
context.policy_idstringNoOptional policy hint if you want to reference a specific policy.
text
POST /request-clearance HTTP/1.1
Host: vault.example.com
Content-Type: application/json
X-Vault-API-Key: sk_prod_example
 
{
  "tool_name": "create_stripe_payment",
  "tool_args": {
    "amount": 249.99,
    "currency": "USD",
    "customer_id": "cus_123",
    "payment_method_id": "pm_123",
    "order_event_id": "ord_evt_2048",
    "reasoning": "Charge matches a completed order event."
  },
  "agent_id": "payments-agent",
  "session_id": "checkout-42",
  "context": {
    "policy_id": "payments-prod"
  }
}

Response body

FieldTypeRequiredDescription
statusstringYesOne of processing, approved, denied, or pending_review.
approvedbooleanYesWhether the request is currently approved.
requires_manual_reviewbooleanYesTrue when the request is waiting on a human reviewer.
tokenstring | nullYesApproval token for approved requests. Null for denied or pending-review responses.
reasonstringYesHuman-readable explanation of the current decision.
request_idstringYesStable ID for tracing, polling, review, and proof lookup.
confidencenumberYesCurrent confidence score for the request.
minimum_confidence_scorenumberYesThe threshold currently applied to your tenant.

Polling request status

Use this endpoint when a request is still processing or pending_review.

text
GET /clearance-status/8ee2d480-4e23-49c5-9869-a0247e806e1c HTTP/1.1
Host: vault.example.com
X-Vault-API-Key: sk_prod_example

The response shape matches POST /request-clearance.

Consuming the A-JWT at the tool boundary

Call /consume-token from the service that actually performs the protected action (or from the tool-gateway binary placed in front of it). Vault verifies the Ed25519 signature, checks iss / aud / exp, and burns the jti so the token cannot be replayed.

text
POST /consume-token HTTP/1.1
Host: vault.example.com
Content-Type: application/json
X-Vault-API-Key: sk_prod_example
 
{
  "token": "eyJhbGciOiJFZERTQSIsImtpZCI6InZhdWx0LWtleS0wMDEifQ..."
}

Response:

FieldTypeRequiredDescription
validbooleanYesTrue if the token verified and had not been consumed before.
jtistringYesThe unique token ID that was burned.
tool_namestringYesThe tool the token was minted for.
agent_idstringYesAgent identity recorded in the token.
policy_idstringYesPolicy the request was evaluated against.
session_idstringNoSession grouping ID, if provided at request time.

A replay returns HTTP 409 Conflict. Treat this as a hard fail — do not execute the protected action.

Registering structured policies

Use this endpoint when your application already stores a compact rule set.

text
POST /register-policy HTTP/1.1
Host: vault.example.com
Content-Type: application/json
X-Vault-API-Key: sk_prod_example
 
{
  "policy_id": "payments-prod",
  "description": "Controls automated payment creation",
  "rules": [
    "Payments must be tied to a valid order event.",
    "Automated payments above $1000 require manual review.",
    "Payment methods must use tokenized identifiers."
  ],
  "tools": ["create_stripe_payment"]
}

Review settings

Read the threshold

text
GET /review-settings HTTP/1.1
Host: vault.example.com
X-Vault-API-Key: sk_prod_example

Update the threshold

text
PUT /review-settings HTTP/1.1
Host: vault.example.com
Content-Type: application/json
X-Vault-API-Key: sk_prod_example
 
{
  "minimum_confidence_score": 0.9
}

Notification settings

Read current settings

text
GET /notification-settings HTTP/1.1
Host: vault.example.com
X-Vault-API-Key: sk_prod_example

Update current settings

text
PUT /notification-settings HTTP/1.1
Host: vault.example.com
Content-Type: application/json
X-Vault-API-Key: sk_prod_example
 
{
  "email_enabled": true,
  "email_recipients": "ops@example.com,security@example.com",
  "slack_enabled": true,
  "slack_webhook_url": "https://hooks.slack.com/services/..."
}

Review queue

List review items

text
GET /reviews?status=pending_review&limit=100 HTTP/1.1
Host: vault.example.com
X-Vault-API-Key: sk_prod_example

Finalize a request

text
POST /reviews/8ee2d480-4e23-49c5-9869-a0247e806e1c/decision HTTP/1.1
Host: vault.example.com
Content-Type: application/json
X-Vault-API-Key: sk_prod_example
 
{
  "approved": false,
  "review_reason": "Order event could not be validated.",
  "reviewer_email": "operator@example.com"
}

Compliance reports

Vault can generate SOX 404 compliance reports on demand and share them with external reviewers via signed tokens.

text
GET  /report-settings
PUT  /report-settings
GET  /reports
POST /reports
GET  /reports/{reportID}
GET  /reports/{reportID}/artifacts/{format}
POST /reports/{reportID}/share

The format path component accepts the artifact format configured for that report (typically pdf or json). POST /reports/{reportID}/share returns an opaque token that can be exchanged at the public GET /reports/shared/{token} endpoint without an API key.

Drift detection

Drift monitors per-agent behavior and can fail-close a specific agent if its pattern diverges from the approved baseline.

text
GET    /drift/settings
PUT    /drift/settings
GET    /drift/summary
GET    /drift/events
POST   /drift/agents/{agentID}/lockdown
DELETE /drift/agents/{agentID}/lockdown

A locked-down agent causes POST /request-clearance to deny without evaluating the policy. Release the lock only after human review.

Ledger and verification

Use these when your team wants to audit history or independently verify the cryptographic chain:

  • GET /ledger — encrypted ledger entries for your tenant
  • GET /ledger/verify — recompute and verify the Merkle tree end-to-end
  • GET /ledger/verification-summary — compact status (latest checkpoint, anchor state, key versions)
  • GET /ledger/checkpoints (alias GET /ledger/manifests) — sealed Merkle checkpoints
  • GET /ledger/proof/inclusion?request_id=... — inclusion proof for one request
  • GET /ledger/proof/consistency?from=...&to=... — consistency proof between checkpoints
  • GET /ledger/proof/bundle?request_id=... — combined per-request proof bundle
  • GET /.well-known/jwks.json — Ed25519 public keys for A-JWT verification

Error handling

The most important customer-facing failure modes are:

  • 401 Unauthorized when the API key is missing, deleted, or wrong for the environment
  • 400 Bad Request when the payload is malformed or required fields are missing
  • 409 Conflict on /consume-token when the JWT has already been burned — do not retry
  • pending_review when the request needs a human reviewer before it can continue

Treat pending_review as workflow, not as an exception case that should be retried blindly.