Skip to content

External API — API Keys, Webhooks & Consumer Endpoints

Blueprint prefix: /api/v1 Module: app.output.api

See API Reference for auth, errors, and pagination.

This module covers three concerns:

  • API Keys — long-lived bearer tokens for scripts and integrations to call the Knora API without a user session.
  • Webhooks — outbound HTTP callbacks fired when platform events occur inside an organisation.
  • External consumer endpoints — API-key-authenticated routes for querying and listing knowledge programmatically.

All management endpoints (API keys, webhooks) require JWT auth, admin or manager role, and Growth plan or higher. External consumer endpoints (/external/*) use API key auth only.


API Keys

API keys are prefixed kn_ and generated from a URL-safe 32-byte random component. Knora stores only the SHA-256 hash and an 8-character display prefix — the full key is shown exactly once at creation and cannot be retrieved again.

Keys are scoped to the organisation. A key cannot access data from a different org. Each org may have up to 20 active API keys.

GET /api-keys

List all API keys for the caller's organisation. Key values are never returned — only metadata.

Auth: JWT (admin/manager) | Plan: Growth+

curl https://api.knora.io/api/v1/api-keys \
  -H "Authorization: Bearer $KNORA_JWT"

Response 200 OK

{
  "api_keys": [
    {
      "id": "3f2a1c0e-8b4d-4f6e-9a2b-1c3d5e7f9a0b",
      "name": "Production Sync",
      "prefix": "kn_aB3xYz",
      "is_active": true,
      "created_at": "2025-11-10T09:14:32.000000+00:00",
      "last_used_at": "2026-05-30T17:42:00.000000+00:00",
      "request_count": 8214
    },
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "CI Pipeline",
      "prefix": "kn_mN7pQr",
      "is_active": true,
      "created_at": "2026-01-22T14:00:00.000000+00:00",
      "last_used_at": null,
      "request_count": 0
    }
  ]
}
Field Type Description
id UUID Unique identifier. Used for revocation.
name string Human-readable label set at creation.
prefix string First 8 characters of the raw key. Safe to display.
is_active boolean Whether the key is currently active.
created_at ISO-8601 When the key was created.
last_used_at ISO-8601 or null Most recent authenticated request, or null if never used.
request_count integer Total authenticated requests made with this key.

POST /api-keys

Create a new API key. The full key value is returned exactly once. Store it securely immediately — it cannot be recovered later.

Auth: JWT (admin/manager) | Plan: Growth+

Request body

Field Type Required Constraints
name string Yes 1–80 characters
curl -X POST https://api.knora.io/api/v1/api-keys \
  -H "Authorization: Bearer $KNORA_JWT" \
  -H "Content-Type: application/json" \
  -d '{"name": "Production Sync"}'

Response 201 Created

{
  "id": "3f2a1c0e-8b4d-4f6e-9a2b-1c3d5e7f9a0b",
  "name": "Production Sync",
  "prefix": "kn_aB3xYz",
  "is_active": true,
  "created_at": "2026-05-31T11:00:00.000000+00:00",
  "last_used_at": null,
  "request_count": 0,
  "key": "kn_aB3xYzDefGhiJklMnopQrstUvwxYz0123456789abc"
}

The key field is only present in this creation response. It will never appear again. Treat it like a password.

Errors

HTTP code Cause
400 MISSING_NAME name is absent or empty.
400 NAME_TOO_LONG name exceeds 80 characters.
400 API_KEY_LIMIT_REACHED Org has reached the 20 active API key limit.

GET /api-keys/usage

Aggregate usage statistics for all API keys in the caller's organisation.

Auth: JWT (admin/manager) | Plan: Growth+

requests_today and requests_this_month are reserved fields not yet tracked. They always return null. Use total_requests from individual key objects for usage decisions.

curl https://api.knora.io/api/v1/api-keys/usage \
  -H "Authorization: Bearer $KNORA_JWT"

Response 200 OK

{
  "key_count": 3,
  "total_requests": 15420,
  "requests_today": null,
  "requests_this_month": null,
  "rate_limit_per_minute": 60
}
Field Type Description
key_count integer Total number of API keys in the org (active and revoked).
total_requests integer Sum of request_count across all API keys.
requests_today null Reserved. Not yet tracked.
requests_this_month null Reserved. Not yet tracked.
rate_limit_per_minute integer Platform rate limit per key per minute. Currently 60.

DELETE /api-keys/{key_id}

Soft-revoke an API key. Sets is_active to false — the key record is preserved for audit history but any further requests using it are rejected. This action cannot be undone; create a new key if access needs to be restored.

Auth: JWT (admin/manager) | Plan: Growth+

curl -X DELETE https://api.knora.io/api/v1/api-keys/3f2a1c0e-8b4d-4f6e-9a2b-1c3d5e7f9a0b \
  -H "Authorization: Bearer $KNORA_JWT"

Response 204 No Content — empty body.

Errors

HTTP code Cause
400 INVALID_ID key_id is not a valid UUID.
404 NOT_FOUND No API key with that ID found in the caller's org.

Webhooks

Webhooks let external systems receive real-time notifications when events occur inside a Knora organisation. Each org may have up to 20 webhook endpoints.

Supported Events

Event Fired when
knowledge.created A new knowledge entry is added.
knowledge.updated An existing knowledge entry is modified.
knowledge.deleted A knowledge entry is removed.
member.invited A new member invitation is sent.
member.removed A member is removed from the org.
query.asked A user submits a query to the knowledge base.

Webhook delivery

Knora delivers events as HTTP POST requests to the registered URL. Each delivery includes two signature headers for authenticity verification:

Header Value
X-Knora-Signature sha256=<hmac-hex> — HMAC-SHA256 of the raw request body, keyed with the endpoint's secret.
X-Knora-Event The event type string (e.g. knowledge.created).

To verify a delivery, compute HMAC-SHA256(secret, raw_body) and compare it to the value after sha256=. Reject requests where the signatures do not match.

Only endpoints with is_active: true receive deliveries. Endpoints subscribed to specific events only receive deliveries for those events.


GET /webhooks

List all registered webhook endpoints for the caller's organisation.

Auth: JWT (admin/manager) | Plan: Growth+

curl https://api.knora.io/api/v1/webhooks \
  -H "Authorization: Bearer $KNORA_JWT"

Response 200 OK

{
  "webhooks": [
    {
      "id": "c7e8f9a0-1b2c-3d4e-5f6a-7b8c9d0e1f2a",
      "url": "https://integrations.example.com/knora/events",
      "events": ["knowledge.created", "knowledge.updated", "query.asked"],
      "is_active": true,
      "created_at": "2026-03-15T08:30:00.000000+00:00"
    }
  ]
}
Field Type Description
id UUID Unique identifier. Used for deletion.
url string The HTTPS URL Knora will POST events to.
events string[] Event types this endpoint is subscribed to.
is_active boolean Whether the endpoint is active and receiving deliveries.
created_at ISO-8601 When the endpoint was registered.

POST /webhooks

Register a new webhook endpoint. Returns the HMAC signing secret once — store it securely. The secret is not returned in any subsequent response.

Auth: JWT (admin/manager) | Plan: Growth+

Request body

Field Type Required Constraints
url string Yes https:// only, ≤ 2048 chars, public host (no private/loopback IPs)
events string[] Yes At least one item from the supported events list
curl -X POST https://api.knora.io/api/v1/webhooks \
  -H "Authorization: Bearer $KNORA_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://integrations.example.com/knora/events",
    "events": ["knowledge.created", "knowledge.updated", "query.asked"]
  }'

Response 201 Created

{
  "id": "c7e8f9a0-1b2c-3d4e-5f6a-7b8c9d0e1f2a",
  "url": "https://integrations.example.com/knora/events",
  "events": ["knowledge.created", "knowledge.updated", "query.asked"],
  "is_active": true,
  "created_at": "2026-05-31T11:05:00.000000+00:00",
  "secret": "whs_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4"
}

The secret field is only present in this creation response. Use it to verify the X-Knora-Signature header on incoming deliveries.

Errors

HTTP code Cause
400 MISSING_URL url is absent or empty.
400 INVALID_URL url does not contain a valid hostname.
400 INVALID_URL_SCHEME url does not use https://. Plain http:// is not accepted.
400 URL_TOO_LONG url exceeds 2048 characters.
400 BLOCKED_URL url resolves to a private, loopback, or link-local address (SSRF prevention).
400 MISSING_EVENTS events array is absent or empty.
400 INVALID_EVENTS One or more event types are not in the supported events list.
400 WEBHOOK_LIMIT_REACHED Org has reached the 20 webhook endpoint limit.
409 DUPLICATE_WEBHOOK_URL A webhook with this URL is already registered for the org.

DELETE /webhooks/{webhook_id}

Remove a webhook endpoint. Knora stops delivering events to this URL immediately. The endpoint record is permanently deleted.

Auth: JWT (admin/manager) | Plan: Growth+

curl -X DELETE https://api.knora.io/api/v1/webhooks/c7e8f9a0-1b2c-3d4e-5f6a-7b8c9d0e1f2a \
  -H "Authorization: Bearer $KNORA_JWT"

Response 204 No Content — empty body.

Errors

HTTP code Cause
400 INVALID_ID webhook_id is not a valid UUID.
404 NOT_FOUND No webhook with that ID found in the caller's org.

External Consumer Endpoints

These routes are authenticated with an API key (not a JWT). Pass the key in the Authorization header:

Authorization: Bearer kn_<key>

Rate-limited to 60 requests per minute per key.


GET /external/query

Query the organisation's knowledge base using an API key. Delegates to the core RAG query service and returns an answer with citations.

Auth: API key | Plan: Growth+

Query parameters

Parameter Type Required Description
q string Yes The question or search text.
curl "https://api.knora.io/api/v1/external/query?q=What+is+our+onboarding+process" \
  -H "Authorization: Bearer kn_aB3xYzDefGhiJklMnopQrstUvwxYz0123456789abc"

Response 200 OK

{
  "answer": "The onboarding process involves three phases...",
  "sources": [
    {
      "id": "3f2a1c0e-8b4d-4f6e-9a2b-1c3d5e7f9a0b",
      "title": "Onboarding Guide",
      "excerpt": "Phase 1: Account setup and tool access..."
    }
  ]
}

Errors

HTTP code Cause
400 MISSING_QUERY q parameter is absent or empty.
401 INVALID_API_KEY API key is missing, revoked, or does not match any active key.
429 Rate limit exceeded (60 req/min per key).

GET /external/knowledge

List knowledge entries for the organisation using an API key. Results are paginated via limit and offset.

Auth: API key | Plan: Growth+

Query parameters

Parameter Type Default Constraints Description
limit integer 20 Max 100 Number of entries to return.
offset integer 0 Min 0 Number of entries to skip.
curl "https://api.knora.io/api/v1/external/knowledge?limit=50&offset=0" \
  -H "Authorization: Bearer kn_aB3xYzDefGhiJklMnopQrstUvwxYz0123456789abc"

Response 200 OK

{
  "entries": [
    {
      "id": "3f2a1c0e-8b4d-4f6e-9a2b-1c3d5e7f9a0b",
      "title": "Onboarding Guide",
      "content": "Phase 1: Account setup...",
      "created_at": "2026-01-10T10:00:00.000000+00:00"
    }
  ],
  "total": 142,
  "limit": 50,
  "offset": 0
}
Field Type Description
entries array Knowledge entry objects for the current page.
total integer Total number of entries in the org.
limit integer The effective limit applied to this request.
offset integer The effective offset applied to this request.

Errors

HTTP code Cause
400 INVALID_PARAMS limit or offset are not integers.
401 INVALID_API_KEY API key is missing, revoked, or does not match any active key.
429 Rate limit exceeded (60 req/min per key).

Notes

API key security

  • The full key value (kn_...) is returned once only in the POST /api-keys response and is not stored in plaintext.
  • Knora stores a SHA-256 hash and an 8-character display prefix. The prefix is safe to show in UIs.
  • If a key is lost or compromised, revoke it with DELETE /api-keys/{key_id} and create a replacement.
  • Revoked keys have is_active: false and are preserved in the record for audit purposes.

Plan tiers

Plan API keys Webhooks External endpoints
trial No No No
starter No No No
growth Yes Yes Yes
enterprise Yes Yes Yes