v2.2

API Reference

The lakefrontai REST API lets you ingest AI agent events, generate Visa CE 3.0 chargeback packets, manage disputes, and run behavioral fingerprinting and cryptographic attestation. All endpoints return JSON. All requests must include an API key.

Quickstart

Get from zero to your first evidence event in under 5 minutes.

1. Get an API key

Create a key in the dashboard under Admin → API Keys. Keys are prefixed lf_.

2. Send your first event

curl -X POST https://api.lakefrontai.com/events \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "event_id":        "evt_001",
    "session_id":      "ses_abc123",
    "mandate_id":      "man_xyz789",
    "agent_id":        "agent_checkout_v2",
    "sequence_number": 1,
    "category":        "payment",
    "method":          "stripe.charge",
    "status":          "success",
    "initiated_at":    1718000000000,
    "data": {
      "amount":   4999,
      "currency": "usd",
      "customer": "cus_abc"
    }
  }'
bash

Response

{
  "ok": true,
  "event_id": "evt_001",
  "chain_hash": "sha256:a3f9e1c2..."
}
json

3. Export a Visa CE 3.0 packet

curl -X POST https://api.lakefrontai.com/disputes/dsp_001/packet \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

{
  "case_reference": "dsp_001",
  "status": "open",
  "prior_undisputed_transactions": [...],
  "evidence_events": [...],
  "chain_valid": true,
  "generated_at": "2026-06-20T10:00:00.000Z"
}
json

Authentication

Every request (except GET /health and POST /auth/login) requires a Bearer API key in the Authorization header.

Authorization: Bearer lf_your_api_key
bash
POST/auth/login

Exchange email + password for a session token (for dashboard use). Not needed for API key auth.

emailstringrequired

Email address of the dashboard user.

passwordstringrequired

Account password.

curl -X POST https://api.lakefrontai.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{ "email": "you@example.com", "password": "s3cret" }'
bash

Response

{
  "token": "eyJhbGc...",
  "user": {
    "id": "usr_001",
    "email": "you@example.com",
    "role": "admin"
  }
}
json

Event ingestion

Events are the core primitive. Each event represents a single AI agent action and is linked into a SHA-256 hash chain. Any post-hoc modification breaks the chain.

POST/eventsAPI key

Ingest a single evidence event.

event_idstringrequired

Globally unique ID for this event. Use UUID v4 or a deterministic hash.

session_idstringrequired

Groups events from the same user session.

mandate_idstringrequired

The agent mandate / task ID this event belongs to.

agent_idstringrequired

Identifier of the AI agent that performed the action.

sequence_numbernumberrequired

Monotonically increasing integer within a session. Gaps are flagged.

categorystringrequired

Event category: payment | auth | data | tool | decision.

methodstringrequired

The specific API or action called, e.g. stripe.charge.

statusstringrequired

success | failure | pending.

initiated_atnumberrequired

Unix millisecond timestamp when the agent initiated the action.

dataobjectrequired

Arbitrary JSON payload — the evidence body. PII is automatically redacted.

x-attestation-tokenheaderoptional

Required if the agent has Layer 3 credentials registered. Pass the token returned by POST /attestation/verify.

curl -X POST https://api.lakefrontai.com/events \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -H "x-attestation-token: at_abc..." \
  -d '{
    "event_id":        "evt_stripe_charge_001",
    "session_id":      "ses_user_42_checkout",
    "mandate_id":      "man_purchase_flow_v3",
    "agent_id":        "agent_checkout_v2",
    "sequence_number": 3,
    "category":        "payment",
    "method":          "stripe.charge",
    "status":          "success",
    "initiated_at":    1718000000000,
    "data": {
      "amount":      4999,
      "currency":    "usd",
      "customer_id": "cus_abc",
      "description": "Pro plan subscription"
    }
  }'
bash

Response

{
  "ok": true,
  "event_id": "evt_stripe_charge_001",
  "chain_hash": "sha256:d4e5f6a7b8..."
}
json
POST/events/batchAPI key

Ingest up to 100 events in a single request. More efficient than individual calls.

curl -X POST https://api.lakefrontai.com/events/batch \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "event_id": "evt_001", "session_id": "ses_abc",
        "mandate_id": "man_xyz", "agent_id": "agent_v2",
        "sequence_number": 1, "category": "auth",
        "method": "stripe.customer.retrieve", "status": "success",
        "initiated_at": 1718000000000, "data": { "customer": "cus_abc" }
      },
      {
        "event_id": "evt_002", "session_id": "ses_abc",
        "mandate_id": "man_xyz", "agent_id": "agent_v2",
        "sequence_number": 2, "category": "payment",
        "method": "stripe.charge", "status": "success",
        "initiated_at": 1718000001000, "data": { "amount": 4999 }
      }
    ]
  }'
bash

Response

{
  "ok": true,
  "accepted": 2,
  "rejected": 0
}
json
GET/eventsAPI key

List evidence events with optional filters.

session_idquery stringoptional

Filter by session.

agent_idquery stringoptional

Filter by agent.

limitquery numberoptional

Max results (default 50, max 500).

curl "https://api.lakefrontai.com/events?session_id=ses_abc&limit=20" \
  -H "Authorization: Bearer lf_your_api_key"
bash
GET/events/streamAPI key

Server-Sent Events stream — real-time event feed. Auth via Bearer token in Authorization header.

const es = new EventSource(
  "https://api.lakefrontai.com/events/stream",
  { headers: { Authorization: "Bearer lf_your_api_key" } }
);

es.onmessage = (e) => {
  const event = JSON.parse(e.data);
  console.log(event.method, event.status);
};
js
GET/events/exportAPI key

Export events as a CSV download. Accepts the same query params as GET /events.

curl "https://api.lakefrontai.com/events/export?session_id=ses_abc" \
  -H "Authorization: Bearer lf_your_api_key" \
  -o events.csv
bash

Mandates

A mandate is the authorization contract between a human and an AI agent. Every evidence event must reference a mandate. Mandates carry optional spending limits, per-scope constraints, velocity limits, and an expiry. Once revoked, new events under that mandate are rejected.

POST/mandatesAPI key

Create a new agent mandate.

agent_idstringrequired

The agent this mandate authorizes.

display_namestringrequired

Human-readable name, e.g. "Monthly subscription renewal bot".

authorized_scopesstring[]required

List of permitted action scopes: payment, refund, data_read, data_write, auth, tool, decision.

expires_atstringrequired

ISO 8601 expiry. Must be a future date. Events after expiry are rejected.

issued_bystringrequired

Email or ID of the human who authorized this mandate.

spending_limitnumberoptional

Max cumulative spend in cents (e.g. 100000 = $1,000). Enforced by the budget API.

currencystringoptional

ISO 4217 currency code. Default USD.

constraintsobjectoptional

Per-scope limits — see Budget constraints below.

notesstringoptional

Internal notes.

curl -X POST https://api.lakefrontai.com/mandates \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id":          "agent_checkout_v2",
    "display_name":      "Monthly subscription renewal bot",
    "authorized_scopes": ["payment", "data_read"],
    "spending_limit":    100000,
    "currency":          "USD",
    "expires_at":        "2027-01-01T00:00:00.000Z",
    "issued_by":         "admin@company.com",
    "notes":             "Authorized in board meeting 2026-06-01",
    "constraints": {
      "payment": {
        "max_amount_per_tx":   4999,
        "max_tx_per_day":      10,
        "allowed_currencies":  ["USD", "EUR"],
        "require_mfa":         false
      }
    }
  }'
bash

Response

{
  "id":                "man_7f3a9c",
  "agent_id":          "agent_checkout_v2",
  "display_name":      "Monthly subscription renewal bot",
  "authorized_scopes": ["payment", "data_read"],
  "spending_limit":    100000,
  "currency":          "USD",
  "state":             "active",
  "expires_at":        "2027-01-01T00:00:00.000Z",
  "issued_by":         "admin@company.com",
  "created_at":        "2026-06-22T10:00:00.000Z"
}
json
GET/mandatesAPI key

List all mandates. Pass ?state=active|revoked|expired to filter.

curl "https://api.lakefrontai.com/mandates?state=active" \
  -H "Authorization: Bearer lf_your_api_key"
bash
GET/mandates/:idAPI key

Get a single mandate with its full constraints and budget state.

curl https://api.lakefrontai.com/mandates/man_7f3a9c \
  -H "Authorization: Bearer lf_your_api_key"
bash
PATCH/mandates/:idAPI key

Update a mandate's limits, scopes, or expiry. Cannot update a revoked mandate.

spending_limitnumberoptional

New cumulative spending cap in cents.

expires_atstringoptional

New expiry — must be in the future.

authorized_scopesstring[]optional

Replace the authorized scope list.

constraintsobjectoptional

Replace per-scope constraints.

notesstringoptional

Update notes.

curl -X PATCH https://api.lakefrontai.com/mandates/man_7f3a9c \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "spending_limit": 200000, "expires_at": "2027-06-01T00:00:00.000Z" }'
bash
POST/mandates/:id/revokeAPI key

Permanently revoke a mandate. Subsequent events referencing it will be rejected.

revoked_bystringrequired

Email or ID of the person revoking.

reasonstringoptional

Reason stored in the audit log.

curl -X POST https://api.lakefrontai.com/mandates/man_7f3a9c/revoke \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "revoked_by": "admin@company.com", "reason": "Agent decommissioned" }'
bash

Budget constraints

The constraints object maps each authorized scope to a set of limits. All limits are optional — omit a field to leave it unconstrained.

{
  "payment": {
    "max_amount_per_tx":   4999,       // max single-tx amount in cents
    "max_tx_per_day":      10,          // velocity: transactions per day
    "max_tx_per_month":    50,          // velocity: transactions per month
    "cumulative_limit":    100000,      // lifetime cap in cents
    "allowed_currencies":  ["USD"],     // whitelist; omit for any
    "allowed_merchants":   ["stripe"],  // whitelist of method prefixes
    "require_mfa":         false        // block tx until consent confirmed
  },
  "refund": {
    "max_amount_per_tx":   4999,
    "max_tx_per_day":      5
  }
}
json
GET/mandates/:id/budgetAPI key

Get live budget state — how much has been spent and how many transactions used.

curl https://api.lakefrontai.com/mandates/man_7f3a9c/budget \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

{
  "mandate_id":        "man_7f3a9c",
  "spending_limit":    100000,
  "amount_used":       23400,
  "amount_remaining":  76600,
  "currency":          "USD",
  "tx_today":          3,
  "tx_this_month":     11
}
json
POST/mandates/:id/budget/reserveAPI key

Atomically check and reserve budget for an upcoming transaction. Returns 409 if the mandate would be exceeded.

amountnumberrequired

Amount in cents to reserve.

scopestringrequired

The scope being exercised, e.g. payment.

currencystringoptional

ISO 4217 currency. Defaults to the mandate's currency.

curl -X POST https://api.lakefrontai.com/mandates/man_7f3a9c/budget/reserve \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 4999, "scope": "payment", "currency": "USD" }'
bash

Response

{
  "ok":               true,
  "reservation_id":   "res_001",
  "amount_reserved":  4999,
  "amount_remaining": 71601
}
json

Disputes & Visa CE 3.0 packets

A dispute links a chargeback case to one or more evidence sessions. Once linked, you can export a Visa CE 3.0-compliant evidence packet in one call.

POST/disputesAPI key

Open a new dispute case.

session_idstringrequired

The session whose events support this dispute.

case_referencestringrequired

Your internal case reference or the chargeback ID from your payment processor.

reason_codestringoptional

Visa/Mastercard reason code, e.g. 10.4.

notesstringoptional

Internal notes for your team.

curl -X POST https://api.lakefrontai.com/disputes \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id":     "ses_user_42_checkout",
    "case_reference": "CB-2026-00441",
    "reason_code":    "10.4",
    "notes":          "Customer claims they did not authorise the $49.99 charge"
  }'
bash

Response

{
  "id": "dsp_7f3a9c",
  "session_id": "ses_user_42_checkout",
  "case_reference": "CB-2026-00441",
  "status": "open",
  "created_at": "2026-06-20T10:00:00.000Z"
}
json
GET/disputesAPI key

List all disputes for your org.

curl https://api.lakefrontai.com/disputes \
  -H "Authorization: Bearer lf_your_api_key"
bash
PATCH/disputes/:idAPI key

Update a dispute's status or notes.

statusstringoptional

open | won | lost | closed.

notesstringoptional

Updated notes.

curl -X PATCH https://api.lakefrontai.com/disputes/dsp_7f3a9c \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "status": "won", "notes": "Visa accepted our CE 3.0 packet" }'
bash
POST/disputes/:id/packetAPI key

Generate a Visa CE 3.0-compliant evidence packet for this dispute. Returns a JSON structure ready to attach to your chargeback response.

curl -X POST https://api.lakefrontai.com/disputes/dsp_7f3a9c/packet \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

{
  "case_reference": "CB-2026-00441",
  "status": "open",
  "prior_undisputed_transactions": [
    {
      "transaction_id": "ch_prev1",
      "amount": 4999,
      "currency": "usd",
      "date": "2026-05-01T00:00:00.000Z",
      "description": "Pro plan - May"
    }
  ],
  "evidence_events": [
    {
      "event_id": "evt_stripe_charge_001",
      "method": "stripe.charge",
      "status": "success",
      "initiated_at": 1718000000000,
      "chain_hash": "sha256:d4e5f6..."
    }
  ],
  "chain_valid": true,
  "generated_at": "2026-06-20T10:01:00.000Z"
}
json

Dispute scoring

The scoring engine evaluates each dispute and returns a recommendation — fight or refund — with an evidence score (0–100) and a deflection strategy. It weighs consent presence, chain integrity, prior transaction history, mandate validity, and chargeback ratio governance.

Scoring signals

Consent artifact present+25 pts
Hash chain intact+20 pts
Prior undisputed txns+15 pts
Mandate active & valid+15 pts
Behavioral fingerprint enrolled+10 pts
Attestation token verified+10 pts
Dispute ratio under threshold+5 pts
GET/disputes/:id/scoreAPI key

Compute the fight-vs-refund score for a dispute. Cached for 5 minutes.

curl https://api.lakefrontai.com/disputes/dsp_7f3a9c/score \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

{
  "dispute_id":          "dsp_7f3a9c",
  "recommendation":      "fight",
  "evidence_score":      82,
  "deflection_strategy": "submit_ce30_packet",
  "signals": {
    "consent_present":      true,
    "chain_valid":          true,
    "prior_tx_count":       3,
    "mandate_valid":        true,
    "fingerprint_enrolled": true,
    "attestation_verified": false,
    "ratio_ok":             true
  },
  "fight_threshold":     60,
  "computed_at":         "2026-06-22T10:00:00.000Z"
}
json

Deflection strategies

StrategyWhen usedAction
submit_ce30_packetScore ≥ 60Export CE 3.0 packet and respond to chargeback
proactive_refundScore < 60Issue refund before chargeback escalates
request_more_evidenceScore 50–59Gather additional session evidence before deciding
escalate_to_humanConsent mismatchFlag for manual review due to consent anomaly
GET/disputes/ratioAPI key

Your org's current chargeback ratio and governance thresholds (Visa: warn at 0.65%, block at 1.0%).

curl https://api.lakefrontai.com/disputes/ratio \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

{
  "ratio":              0.0042,
  "dispute_count":      12,
  "transaction_count":  2857,
  "warn_threshold":     0.0065,
  "block_threshold":    0.01,
  "status":             "ok"
}
json

Reason-code taxonomy

Traditional card disputes ask “did the cardholder make this purchase?” Agentic disputes decompose into a chain of authorization questions. lakefrontai maps every dispute onto a proprietary taxonomy with 5 families and 13 codes — each attacks a specific link in the mandate/evidence chain and is defended by a specific slice of evidence. Standard Visa and Mastercard codes are automatically normalized to internal codes on ingest.

AAAuthority absent / invalid

No mandate existed, or it had expired or been revoked when the agent acted.

ASScope / constraint breach

Agent acted outside its granted scopes, over the spending limit, or exceeded velocity.

AIAgent identity / evidence integrity

Impersonation, tampered evidence log, or replay of a valid historical action.

ACPrincipal / consumer claim

Cardholder repudiates authorization, claims malfunction, or merchandise not received.

ADDelegation chain

A sub-agent acted without its own delegated mandate.

All reason codes

CodeFamilyClaimKey evidence fields
AA-01AANo mandate ever existed for this agentmandate.issued_by, consent.terms_hash, mandate.created_at
AA-02AAMandate had expired when it actedmandate.expires_at, event.initiated_at
AA-03AAMandate was revoked before this actionmandate.revoked_at, chain.sequence
AS-01ASAgent acted outside its granted scopemandate.authorized_scopes, event.category
AS-02ASOver amount / wrong merchant / wrong currencymandate.constraints, event.toolArgs
AS-03ASAgent transacted more than permitted (velocity)mandate.constraints.velocityMax, budget.ledger
AI-01AIThat was not our agent (impersonation)mandate.agent_id, attestation
AI-02AIThe evidence log was altered after the factchain.previousHash, chain.integrity
AI-03AIA valid old action was replayedevent.event_id, chain.sequence
AC-01ACI never authorized this agent at allconsent.signature, consent.auth_method, consent.principal_email
AC-02ACThe agent malfunctioned / hallucinated the orderevent.preAction.context, constraint.conformance
AC-03ACNot received / not as describedevent.postAction.result, fulfillment
AD-01ADA sub-agent acted without a delegated mandatemandate.consent_id, delegation.chain

Network code mapping

When you pass a standard Visa or Mastercard reason_code to POST /disputes, it is automatically normalized to the internal taxonomy. Unknown codes are stored as-is without classification.

Network codeNetwork descriptionMaps to
10.4Visa — Fraud, card-absent environmentAC-01
13.1Visa — Merchandise / services not receivedAC-03
13.3Visa — Not as described / defective merchandiseAC-03
12.5Visa — Incorrect amountAS-02
11.3Visa — No authorizationAA-01
4837Mastercard — No cardholder authorizationAC-01
4853Mastercard — Cardholder dispute, not as describedAC-03
4834Mastercard — Point-of-interaction errorAS-02

Agent fingerprinting

Behavioral fingerprinting builds a baseline profile of each agent across three layers: Layer 1 (timing, error rate, API diversity), Layer 2 (coefficient of variation, retry rate, burst coefficient, payload size, session rhythm), and Layer 3 (cryptographic attestation). Drift from baseline is scored 0–100.

GET/fingerprintsAPI key

List all agent fingerprint profiles for your org.

curl https://api.lakefrontai.com/fingerprints \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

[
  {
    "agent_id":           "agent_checkout_v2",
    "status":             "enrolled",
    "drift_score":        12.4,
    "timing_p50":         142.3,
    "timing_p95":         890.1,
    "error_rate":         0.02,
    "scope_utilization":  0.68,
    "cv_timing":          0.31,
    "retry_rate":         0.04,
    "burst_coefficient":  1.12,
    "registry_status":    "approved",
    "attestation_status": "verified",
    "last_attested_at":   "2026-06-20T09:00:00.000Z",
    "enrolled_at":        "2026-06-01T00:00:00.000Z"
  }
]
json
GET/fingerprints/:agentIdAPI key

Get the full fingerprint profile for a specific agent, including similar agents and the API transition matrix.

curl https://api.lakefrontai.com/fingerprints/agent_checkout_v2 \
  -H "Authorization: Bearer lf_your_api_key"
bash
POST/fingerprints/:agentId/resetAPI key

Reset an agent's fingerprint back to the enrolling state. Useful after a legitimate agent update.

curl -X POST https://api.lakefrontai.com/fingerprints/agent_checkout_v2/reset \
  -H "Authorization: Bearer lf_your_api_key"
bash
POST/fingerprints/backfillAPI key

Trigger fingerprint computation for all agents that have evidence events but haven't completed enrollment.

curl -X POST https://api.lakefrontai.com/fingerprints/backfill \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

{
  "triggered": 3,
  "agent_ids": ["agent_checkout_v2", "agent_refund_bot", "agent_kyc"]
}
json

Fingerprint registry

The registry is agent-native MFA: once an agent enrolls, an admin approves its behavioral profile as the canonical identity. Future events are checked against the approved profile. Violations set registry_status = "challenged" even if the API key is valid.

GET/registryAPI key

List all fingerprint registry entries (pending, approved, revoked).

curl https://api.lakefrontai.com/registry \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

[
  {
    "id":           "reg_001",
    "agent_id":     "agent_checkout_v2",
    "status":       "approved",
    "profile_hash": "sha256:a1b2c3...",
    "version":      2,
    "reviewed_by":  "admin@company.com",
    "reviewed_at":  "2026-06-10T09:00:00.000Z"
  }
]
json
POST/registry/:id/approveAPI key

Approve a pending registry entry. The agent's current behavioral profile becomes the canonical baseline.

notesstringoptional

Optional reviewer notes.

curl -X POST https://api.lakefrontai.com/registry/reg_001/approve \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "notes": "Verified with eng team — legitimate v2 deployment" }'
bash
POST/registry/:id/revokeAPI key

Revoke an approved registry entry. The agent will be marked challenged on next event.

reasonstringoptional

Reason for revocation (stored in audit log).

curl -X POST https://api.lakefrontai.com/registry/reg_001/revoke \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Suspected compromise — pending investigation" }'
bash

Layer 3 — Cryptographic attestation

Layer 3 uses Ed25519 challenge-response to cryptographically prove an agent's identity at startup. A verified agent receives a 1-hour token which it includes on every event batch. Without a valid token, event ingestion is blocked for credentialed agents.

Full attestation flow

  1. 1Admin registers agent's Ed25519 public key via POST /attestation/credentials
  2. 2Agent calls POST /attestation/challenge → receives nonce + message to sign
  3. 3Agent signs message with its private key (Ed25519)
  4. 4Agent calls POST /attestation/verify with signature + runtime metadata
  5. 5Server verifies signature, image digest, SBOM hash, runtime → issues 1-hour token
  6. 6Agent includes token in x-attestation-token header on every POST /events call
POST/attestation/credentialsAPI key

Register an Ed25519 public key and optional allowlists for an agent. Replaces any existing credentials for that agent.

agent_idstringrequired

Agent to register credentials for.

public_key_pemstringrequired

Ed25519 public key in PEM format.

allowed_image_digestsstring[]optional

Allowlist of sha256: container image digests.

allowed_sbom_hashesstring[]optional

Allowlist of sha256: SBOM hashes.

baseline_runtimeobjectoptional

Expected runtime: { platform, arch, node_version }.

require_image_digestbooleanoptional

If true, block events if digest missing or not in allowlist. Default false.

require_sbom_hashbooleanoptional

If true, block if SBOM hash missing or not in allowlist. Default false.

require_runtime_matchbooleanoptional

If true, block if runtime doesn't match baseline. Default false.

curl -X POST https://api.lakefrontai.com/attestation/credentials \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agent_checkout_v2",
    "public_key_pem": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA...\n-----END PUBLIC KEY-----",
    "allowed_image_digests": [
      "sha256:abc123def456..."
    ],
    "allowed_sbom_hashes": [
      "sha256:def456abc123..."
    ],
    "baseline_runtime": {
      "platform":     "linux",
      "arch":         "x64",
      "node_version": "v20.11.0"
    },
    "require_image_digest":  true,
    "require_sbom_hash":     false,
    "require_runtime_match": true
  }'
bash

Response

{
  "id":         "cred_001",
  "agent_id":   "agent_checkout_v2",
  "algorithm":  "ed25519",
  "created_at": "2026-06-20T10:00:00.000Z"
}
json
POST/attestation/challengeAPI key

Issue a one-time nonce for the agent to sign. The challenge expires after 5 minutes.

agent_idstringrequired

The agent requesting a challenge. Must have registered credentials.

curl -X POST https://api.lakefrontai.com/attestation/challenge \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "agent_id": "agent_checkout_v2" }'
bash

Response

{
  "challenge_id": "ch_9f3a2b",
  "nonce":        "a7f3e1c2d4b5...",
  "message":      "lakefront-attest:agent_checkout_v2:ch_9f3a2b:a7f3e1c2d4b5...",
  "expires_at":   "2026-06-20T10:05:00.000Z"
}
json

Signing the challenge (Node.js)

import { createSign } from "crypto";
import { readFileSync } from "fs";

const privateKey = readFileSync("./agent_private.pem");
const message    = "lakefront-attest:agent_checkout_v2:ch_9f3a2b:a7f3e1c2d4b5...";

const sign = createSign("ed25519");
sign.update(message);
const signature = sign.sign(privateKey, "hex");

console.log(signature); // pass this to POST /attestation/verify
js

Signing the challenge (Python)

from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import load_pem_private_key

with open("agent_private.pem", "rb") as f:
    private_key = load_pem_private_key(f.read(), password=None)

message   = b"lakefront-attest:agent_checkout_v2:ch_9f3a2b:a7f3e1c2d4b5..."
signature = private_key.sign(message).hex()

print(signature)  # pass to POST /attestation/verify
python
POST/attestation/verifyAPI key

Submit the signed challenge + runtime metadata. Returns a 1-hour attestation token on success.

agent_idstringrequired

Must match the agent that requested the challenge.

challenge_idstringrequired

The challenge_id from POST /attestation/challenge.

signaturestringrequired

Hex-encoded Ed25519 signature of the challenge message.

runtimeobjectrequired

Runtime metadata: platform, arch, and optionally image_digest, sbom_hash, node_version.

curl -X POST https://api.lakefrontai.com/attestation/verify \
  -H "Authorization: Bearer lf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id":     "agent_checkout_v2",
    "challenge_id": "ch_9f3a2b",
    "signature":    "3b6a9f...",
    "runtime": {
      "platform":     "linux",
      "arch":         "x64",
      "node_version": "v20.11.0",
      "image_digest": "sha256:abc123def456...",
      "sbom_hash":    "sha256:def456abc123..."
    }
  }'
bash

Response

{
  "verified":       true,
  "token":          "at_7f9c3b2a...",
  "valid_until":    "2026-06-20T11:00:00.000Z",
  "checks_passed":  ["signature", "image_digest", "runtime_metadata"],
  "checks_failed":  []
}
json

Complete agent startup example (Node.js)

import { createSign } from "crypto";
import { readFileSync } from "fs";
import os from "os";

const API_KEY    = process.env.LF_API_KEY;
const AGENT_ID   = "agent_checkout_v2";
const BASE_URL   = "https://api.lakefrontai.com";
const privateKey = readFileSync("./agent_private.pem");

async function attest(): Promise<string> {
  // 1. Get challenge
  const ch = await fetch(`${BASE_URL}/attestation/challenge`, {
    method:  "POST",
    headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" },
    body:    JSON.stringify({ agent_id: AGENT_ID }),
  }).then(r => r.json());

  // 2. Sign the message
  const sign = createSign("ed25519");
  sign.update(ch.message);
  const signature = sign.sign(privateKey, "hex");

  // 3. Verify and get token
  const result = await fetch(`${BASE_URL}/attestation/verify`, {
    method:  "POST",
    headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" },
    body:    JSON.stringify({
      agent_id:     AGENT_ID,
      challenge_id: ch.challenge_id,
      signature,
      runtime: {
        platform:     os.platform(),
        arch:         os.arch(),
        node_version: process.version,
        image_digest: process.env.IMAGE_DIGEST,
      },
    }),
  }).then(r => r.json());

  if (!result.verified) throw new Error(`Attestation failed: ${result.failure_reason}`);
  return result.token;
}

// 4. Use token on every event
const token = await attest();

await fetch(`${BASE_URL}/events`, {
  method:  "POST",
  headers: {
    "Authorization":        `Bearer ${API_KEY}`,
    "Content-Type":         "application/json",
    "x-attestation-token":  token,
  },
  body: JSON.stringify({ /* event payload */ }),
});
js
GET/attestation/credentialsAPI key

List all registered agent credentials with their current attestation status.

DELETE/attestation/credentials/:agentIdAPI key

Revoke credentials for an agent. The agent will be blocked from submitting events until re-registered.

GET/attestation/recordsAPI key

Audit log of all attestation attempts. Pass ?agent_id= to filter.

curl "https://api.lakefrontai.com/attestation/records?agent_id=agent_checkout_v2" \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

[
  {
    "id":              "ar_001",
    "agent_id":        "agent_checkout_v2",
    "result":          "verified",
    "checks_passed":   ["signature", "image_digest", "runtime_metadata"],
    "checks_failed":   [],
    "runtime_snapshot": { "platform": "linux", "arch": "x64", "node_version": "v20.11.0" },
    "attested_at":     "2026-06-20T09:00:00.000Z"
  }
]
json

Stripe webhooks

Point your Stripe webhook to POST /webhooks/stripe. lakefrontai auto-creates or updates dispute records on charge.dispute.created,charge.refunded, and related events.

POST/webhooks/stripe

Stripe webhook receiver. HMAC-SHA256 verified. Set your Stripe webhook secret as STRIPE_WEBHOOK_SECRET in env.

# In Stripe Dashboard → Developers → Webhooks → Add endpoint:
# URL: https://api.lakefrontai.com/webhooks/stripe
# Events: charge.dispute.created, charge.dispute.updated,
#          charge.refunded, payment_intent.succeeded

# Set the signing secret in your environment:
STRIPE_WEBHOOK_SECRET=whsec_your_secret
bash

When a charge.refunded event arrives, lakefrontai automatically matches it to an existing dispute by charge ID and records the refund amount, refund ID, and timestamp. If no matching dispute exists, one is auto-created.

Compliance & stats

GET/complianceAPI key

NIST AI RMF 1.1 compliance summary across all four functions: GOVERN, MAP, MEASURE, MANAGE.

curl https://api.lakefrontai.com/compliance \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

{
  "govern":  { "score": 92, "issues": [] },
  "map":     { "score": 88, "issues": ["2 agents missing mandate definitions"] },
  "measure": { "score": 95, "issues": [] },
  "manage":  { "score": 79, "issues": ["3 open disputes unresolved > 30 days"] }
}
json
GET/statsAPI key

High-level event and dispute statistics for your org.

GET/agentsAPI key

List all agents that have submitted at least one event, with event counts and last-seen timestamps.

GET/sessionsAPI key

List all sessions with event counts and time ranges.

GET/timeseriesAPI key

Event volume time series. Pass ?interval=hour|day|week.

curl "https://api.lakefrontai.com/timeseries?interval=day" \
  -H "Authorization: Bearer lf_your_api_key"
bash

Response

[
  { "date": "2026-06-18", "count": 1243 },
  { "date": "2026-06-19", "count": 2018 },
  { "date": "2026-06-20", "count":  847 }
]
json

Errors & rate limits

All errors return a JSON body with an error field and, for validation errors, a details array.

StatusMeaningCommon cause
400Bad requestMissing required field or validation error
401UnauthorizedMissing or invalid API key
403ForbiddenAPI key doesn't have permission for this route
404Not foundResource ID doesn't exist
409ConflictDuplicate event_id or case_reference
413Payload too largeRequest body exceeds 1 MB
429Rate limitedToo many requests — back off and retry
500Internal server errorUnexpected server error
// Example 400 validation error
{
  "error":   "Validation failed",
  "details": [
    "event_id: Required",
    "sequence_number: Expected number, received string"
  ]
}

// Example 401
{
  "error": "Authentication required"
}

// Example 409
{
  "error": "Duplicate event_id: evt_001"
}
json

Rate limits

The API is rate-limited per API key. On limit, you receive a 429 with aRetry-After header. Use POST /events/batch to ingest up to 100 events per call and reduce request volume.

lakefrontai API Reference · v2.2 · © 2026 Lakefront AI