All docs

Docs

Knowledge Lock API

Let your own systems and AI agents read your organisation's locked records, ask questions of them and check work against them.

Guided Orchestration5 min read

The Knowledge Lock API gives your systems and AI agents read access to what your organisation has agreed and locked. An agent can fetch the current version of a record, check it hasn't been changed, answer questions from it, and check a ticket or spec against it before acting.

The API can read and check, but it can't create, change or sign anything. Changes still go through review and sign-off in Knowledge Lock.

Authentication

An owner creates API keys in Knowledge Lock under API. Each key belongs to one organisation and only sees that organisation's records. The key is shown once, when it's created, so store it somewhere safe, such as your secrets manager.

Send the key in the Authorization header of every request:

curl https://app.knowledge-lock.com/api/v1/locks \
  -H "Authorization: Bearer kl_live_your_key_here"

Use a separate key for each agent or system, so you can revoke one without affecting the others. A revoked key stops working straight away.

Endpoints

All endpoints are under https://app.knowledge-lock.com/api/v1 and return JSON.

MethodPathWhat it does
GET/locksYour organisation's current locked records
GET/locks/{lockId}One locked record in full, with its signatures and a verification check
GET/policyYour organisation's current locked policy
POST/locks/{lockId}/askAnswer a question using only that record and your policy
POST/locks/{lockId}/checkFind where a ticket, story or spec departs from that record
GET/exportEvery lock your organisation has, including replaced versions

List current records

curl https://app.knowledge-lock.com/api/v1/locks \
  -H "Authorization: Bearer $KL_API_KEY"
{
  "locks": [
    {
      "lockId": "0x71643a6b6097…",
      "recordId": "4f2c9e1a7b3d5e60",
      "kind": "requirements",
      "title": "Complaints assistant: requirements",
      "version": 1,
      "lockedAt": "2026-10-23T11:30:12.000Z",
      "supersededBy": null,
      "retired": null,
      "claims": [
        { "id": "R1", "statement": "The assistant helps customers log a complaint in plain language." }
      ],
      "url": "https://app.knowledge-lock.com/app/l/0x71643a6b6097…"
    }
  ]
}

Replaced and retired versions are left out. Add ?include=replaced, ?include=retired or ?include=replaced,retired to include them. A replaced version's supersededBy holds the lock that replaced it, and a retired one's retired says who retired it, when and why.

Get one record and verify it

curl https://app.knowledge-lock.com/api/v1/locks/0x71643a6b6097… \
  -H "Authorization: Bearer $KL_API_KEY"

The response contains:

  • lock: the full signed record, including the exact wording, who approved it (name, job title and email), which AI models reviewed it, and the lock's signature
  • verification: the result of checking the record's fingerprint and signature on the server; verification.valid is true if nothing has changed. When people signed with their own passkeys, verification.personalSignatures shows how many signatures there are and how many check out
  • supersededBy: the lock that replaced this one, or null if it's still current
  • retired: null, or retiredAt, retiredBy and reason if an owner has retired the record because it's no longer the source of truth. Retiring covers every version of a record, so this is set on older versions too, with the lockId of the version that was retired

An agent should only act on a record where verification.valid is true, supersededBy is null and retired is null. A retired record still verifies, so you can always show exactly what was agreed.

Personal signatures

When someone signs off with a passkey, their entry in lock.consensus.attestations carries a personalSignature. It holds the passkey's signature over that exact sign-off (the record's fingerprint, their decision and any comment), plus a certificate from Knowledge Lock confirming the passkey belongs to them. verification.valid is only true when every personal signature checks out, so most agents only need that flag. You can also check the signatures yourself with standard WebAuthn verification, without relying on our server.

Ask a question

curl -X POST https://app.knowledge-lock.com/api/v1/locks/0x71643a6b6097…/ask \
  -H "Authorization: Bearer $KL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question": "Can the assistant offer refunds?"}'
{
  "answer": "No. The assistant records the request and a case handler decides on any redress.",
  "citations": ["R2", "P1"],
  "covered": true,
  "model": "claude-sonnet-5-5",
  "provider": "anthropic"
}

covered is false when the locked record doesn't answer the question. In that case your agent shouldn't guess: the gap needs a change to go through review.

Check a ticket or spec

curl -X POST https://app.knowledge-lock.com/api/v1/locks/0x71643a6b6097…/check \
  -H "Authorization: Bearer $KL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"work": "As a customer I can get an instant refund from the assistant."}'
{
  "summary": "The story lets the assistant decide redress, which R2 and P1 reserve for a case handler.",
  "findings": [
    {
      "requirementId": "R2",
      "kind": "departs",
      "excerpt": "get an instant refund from the assistant",
      "detail": "R2 says a case handler decides on any redress."
    }
  ],
  "model": "claude-sonnet-5-5",
  "provider": "anthropic"
}

Ask and check also work on replaced versions, so you can look back at what was agreed at the time. Check supersededBy first if you need the current version. On a retired record they return a 410 with the reason instead.

Each finding is either departs (the work contradicts what was agreed) or not_covered (the work adds something the record doesn't cover).

Export everything

GET /export returns every lock your organisation has, including replaced and retired versions, with each one's verification result. Use it for your own archive or to move your records elsewhere.

Using it from an AI agent

A pattern that works well:

  1. At the start of a task, fetch the record the task depends on with GET /locks/{lockId}, and stop if verification.valid is false, or supersededBy or retired is set.
  2. Give the agent the record's claims as the source of truth, and tell it to cite claim ids.
  3. Before the agent creates a ticket, spec or change, send it to POST /locks/{lockId}/check and stop on any departs finding.
  4. Log the lockId alongside the agent's output, so anyone can see which agreed version it worked from.

Errors and limits

Errors return JSON with an error message and one of these statuses:

StatusMeaning
400The body was missing or not valid JSON, or the question or work text was empty
401The API key is missing, wrong or revoked
404That lock doesn't exist in your organisation
409The record failed verification, so it won't be used
410An owner has retired the record, so it won't be used. The message says who retired it, when and why
429A limit was reached; wait and try again (see Retry-After)

Each key can make up to 1,000 requests an hour, and each organisation up to 10,000 a day across all its keys. Questions and checks also count towards your organisation's AI usage limit. During the pilot, tell us if you need more.