Skip to main content

aikraft

Privacy-first monitoring for LLM applications. Wrap your Anthropic or OpenAI client and Aikraft tracks latency, token usage, refusals, truncations and errors over time, alerts you when they drift, and keeps your EU AI Act post-market monitoring record up to date.

No prompts, responses or personal data ever leave your infrastructure. Only per-minute aggregates do.

pip install aikraft
import aikraft
from anthropic import Anthropic  # or: from openai import OpenAI

aikraft.init(workspace="<workspace-id>", system="<system-id>")  # API key from AIKRAFT_API_KEY
client = aikraft.wrap(Anthropic())

client.messages.create(model="claude-sonnet-5-5", max_tokens=1024, messages=[...])  # unchanged

Your workspace and system IDs, and a ready-to-paste snippet, are in Aikraft under Monitoring → Set up telemetry. Create an API key with read/write scope in Settings → API keys.

What leaves your infrastructure

For each minute, per model and optional tag, the SDK sends counts only:

Sent Example
Number of calls 128
Latency, input tokens, output tokens, output length: counts per fixed bucket, plus a sum "latency_ms": {"counts": [0, …, 120, 8, 0], "sum": 91234.5}
Stop reasons (fixed vocabulary) {"end_turn": 120, "max_tokens": 5, "refusal": 3}
Call status (fixed vocabulary: ok, rate_limited, timeout, connection_error, auth_error, bad_request, server_error, error) {"ok": 126, "rate_limited": 1, "connection_error": 1}
Optional feedback scores: count and sum {"count": 4, "sum": 3.0}

Never sent: prompts, system prompts, responses, tool inputs or outputs, user or request IDs, or anything else from a single request. Response text is only measured (its length) and immediately discarded. Unknown stop reasons are reported as other, never as raw strings.

A full payload looks like this:

{
  "schema": "aikraft.llm.v1",
  "batch_id": "3f0c…",
  "sdk": {"name": "aikraft-python", "version": "0.2.0"},
  "windows": [{
    "start": "2026-10-08T14:00:00+00:00", "end": "2026-10-08T14:01:00+00:00",
    "model": "claude-sonnet-5-5", "tag": "support-bot", "calls": 128,
    "histograms": {"latency_ms": {"counts": [...], "sum": 91234.5}, "output_tokens": {"counts": [...], "sum": 18003}},
    "categories": {"stop_reason": {"end_turn": 120, "max_tokens": 5, "refusal": 3}, "status": {"ok": 126, "rate_limited": 2}}
  }]
}

Supported clients

aikraft.wrap() works with the sync and async clients of:

  • Anthropic: messages.create() (including stream=True) and messages.stream()
  • OpenAI: chat.completions.create(), responses.create() (including stream=True) and their .stream() helpers

It patches the client instance you pass, so other clients are untouched, and returns the same client. Return values and exceptions are exactly what the underlying SDK gives you. Failed calls are counted by status and the original exception is re-raised.

For OpenAI chat streaming, token counts are only available if you request them with stream_options={"include_usage": True}. Without it, latency, length and stop reasons are still tracked.

Tags

Group calls by feature or endpoint:

with aikraft.tag("support-bot"):
    client.messages.create(...)

Tags are context-local, so they're safe across threads and asyncio tasks, and must match [A-Za-z0-9_.-]{1,64}.

Feedback

aikraft.feedback(1.0, model="claude-sonnet-5-5", tag="support-bot")  # e.g. 1.0 thumbs up, 0.0 down

Only the count and sum per minute are sent, never which response they belong to.

Configuration

Option Environment variable Default
api_key= AIKRAFT_API_KEY (required)
endpoint= AIKRAFT_ENDPOINT https://api.aikraft.eu
enabled=False AIKRAFT_DISABLED=1 enabled
flush_interval= 60 seconds
debug=True AIKRAFT_DEBUG=1 off
dry_run=True AIKRAFT_DRY_RUN=1 off

Without an API key, or when disabled, init() logs a warning and everything becomes a no-op. Your app keeps working. Logs go to the aikraft logger.

Seeing exactly what is sent

debug prints every payload before it is sent, and the server's reply, to stderr (or to wherever your app already routes the aikraft logger). dry_run does the same without sending anything and without needing an API key, which is handy to check the data locally before connecting:

$ AIKRAFT_DRY_RUN=1 python app.py
2026-10-17 22:09:24 aikraft: dry run, not sending batch b03e… (1 windows) to https://api.aikraft.eu/…
{
  "schema": "aikraft.llm.v1",
  …
      "categories": {"status": {"connection_error": 1}}
}

The API key is never logged. In the Aikraft app, the Telemetry tab also lists what was received.

Behaviour you can rely on

  • Never breaks your app. Monitoring errors are logged, not raised. If Aikraft is unreachable, data is retried and, if it can't be delivered, dropped.
  • No double counting. Every payload carries a batch_id; retries reuse it and the server ignores repeats.
  • Bounded memory. At most 1000 open windows; beyond that, calls are counted as dropped and logged.
  • Pre-fork servers. gunicorn and celery are fine: each worker process starts its own background thread and buffer.
  • Serverless. Background threads freeze between invocations, so call aikraft.flush() at the end of each handler (AWS Lambda, Cloud Functions…).
  • Shutdown. Buffered data is flushed at interpreter exit. Call aikraft.shutdown() to do it explicitly.

Requirements

Python 3.10+. The only dependency is httpx. anthropic and openai aren't dependencies; the SDK works with whichever version you have installed.

License

Apache-2.0

Metadata

Release files for aikraft 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aikraft 0.2.0
File Size Uploaded Provenance
aikraft-0.2.0.tar.gz 20.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for aikraft 0.2.0
File Interpreter ABI Platform
aikraft-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 43.2 kB

Release files / aikraft-0.2.0.tar.gz

Download URL aikraft-0.2.0.tar.gz
Size 20.2 kB
Tags Source
SHA-256 checksum
How to use checksums
22411f4043e27fb5e5d66e8b8569fedf38360bf4cd6cb035265f9a0ac4dc500b
BLAKE2b-256 checksum
How to use checksums
14ea88ddcfe43ed80dc65eb5fd2f74185c842836bc6057f7557830dc57d7e0dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release files / aikraft-0.2.0-py3-none-any.whl

Download URL aikraft-0.2.0-py3-none-any.whl
Size 23.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0ed5050c483753388d7e90f6eb3cb4e71a7642374553bbe508daee19e3db19e5
BLAKE2b-256 checksum
How to use checksums
35b8bcbbb73d18dd42ddd5920df620e0849587c0b514e5351e0b008c7f758cb3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Security for aikraft 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for aikraft-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page