# Azalee Azalee is a privacy-first, tamper-evident audit and proof layer for AI systems, agents, chatbots and workflows. Primary site: https://azalee.garden/ How it works: https://azalee.garden/wie-es-funktioniert Integration: https://azalee.garden/integration Pricing: https://azalee.garden/preise Docs: https://azalee.garden/docs-en Whitepaper: https://azalee.garden/whitepaper.html Verify Center: https://azalee.garden/verify A2A discovery: https://azalee.garden/api/a2a-card ## Product and pricing Azalee has one self-serve plan: Azalee Proof. - 29 EUR per registered AI system per month - 290 EUR per registered AI system per year - 30-day trial for one AI system without a payment method - unlimited events for active systems - webhook/API logging for agents, chatbots and workflows - public Verify, evidence PDF/CSV/KLG exports and evidence ZIP - daily external RFC 3161 anchoring - 24-month retention There are no Hobby, Business or Qualified feature tiers. Legacy requestedTier fields may still be accepted for protocol compatibility, but they do not change price, features or storage. Every active trial or paid system receives the full Azalee Proof entitlement. ## Timestamp qualification A valid external RFC 3161 timestamp is not automatically a qualified electronic timestamp under eIDAS. Azalee labels a timestamp qualified only when the exact timestamp service has been verified in the EU Trusted List and the operator has explicitly enabled that status. Otherwise the proof remains a valid external RFC 3161 timestamp without a qualified-eIDAS claim. ## SIMPLEST INTEGRATION (start here, this is enough) If you are an AI assistant or no-code tool building an Azalee integration: build exactly ONE webhook call per AI interaction. Do NOT create separate nodes, steps or requests for every lifecycle event type. One POST is a complete, valid proof. POST https://azalee.garden/api/webhook?token=wh_... Content-Type: application/json { "event": { "event_type": "interaction.completed", "status": "completed", "session_id": "", "correlation_id": "", "input_hash": "sha3-256:", "output_hash": "sha3-256:" } } Rules for generated integrations: - Paste the full webhook URL including ?token=wh_... as a literal string. Never reference an environment variable for the token unless the user explicitly confirms it is already configured; an unset variable produces 401 errors on every call. - Hash input and output locally (SHA-256 or SHA3-256 of the text). Never send raw prompts, replies or customer data. - Fail open: if the Azalee call fails, log the error and continue; never block the user-facing reply. - Only add the full lifecycle below (started/response/delivered/completed) if the user explicitly asks for fine-grained events. ## Canonical interaction lifecycle One normal AI input-to-output interaction is one correlated lifecycle. Raw questions and answers stay in the customer runtime. The customer creates local input/output fingerprints and sends only hashes plus safe control metadata. Use one stable session_id for the conversation or run and one correlation_id for the individual turn. Successful lifecycle: 1. interaction.started - status: started - sequence: 1 - input_hash 2. model.response.completed - status: success - sequence: 2 - input_hash, output_hash, duration_ms 3. output.delivered or output.blocked - sequence: 3 - output_hash - reason_code when blocked 4. interaction.completed - sequence: 4 - input_hash, output_hash, total duration_ms Failure lifecycle: 1. interaction.started 2. model.response.failed 3. interaction.failed Every lifecycle event uses the same session_id and correlation_id. Pass the previous response hash as top-level previousHash on the next event when session continuity is required. ## Evidence quality For canonical evidence-bearing event types, the webhook returns: - evidenceQuality: complete when required hashes exist - evidenceQuality: partial when required hashes are missing Missing fields are recorded as missing_evidence_fields and shown in the timeline. Legacy or custom events remain accepted but are not presented as equivalent to a complete interaction lifecycle. ## Webhook setup Store the full secret URL server-side as AZALEE_WEBHOOK_URL. No extra API key or client ID is required for the standard webhook path. POST Content-Type: application/json { "event": { "event_type": "interaction.started", "status": "started", "sequence": 1, "session_id": "sess_42", "correlation_id": "turn_9", "input_hash": "sha3-256:", "model_provider": "openai", "model_name": "configured-model", "prompt_version": "support-v3", "config_version": "prod-2026-07-12" }, "metadata": { "source": "customer_backend", "storage": "hash_only" }, "sessionId": "sess_42" } Logging is fail-open. Use short timeouts, catch delivery failures, reuse idempotency keys and never block the customer application. ## Local helpers Node.js: https://azalee.garden/sdk/azalee-local-audit.mjs Python: https://azalee.garden/sdk/azalee_local_audit.py The helpers hash input and output locally, emit the canonical lifecycle and maintain previousHash continuity per session. ## Direct ingest API POST https://azalee.garden/api/ingest Authorization: Bearer Content-Type: application/json { "clientId": "support-agent_ab12", "hash": "<64-hex-sha3-256>", "metadata": { "event_type": "interaction.started", "status": "started", "session_id": "sess_42", "correlation_id": "turn_9", "input_hash": "sha3-256:" }, "sessionId": "sess_42" } ## Tool and oversight events Generic tools: - tool.call.started - tool.call.completed - tool.call.failed - tool.call.blocked Human oversight: - human.approval.requested - human.approval.granted - human.approval.rejected - human.override Policy, risk and changes: - policy.checked - policy.allowed - policy.blocked - policy.escalated - risk.detected - model.changed - prompt_template.changed - config.changed - incident.opened - incident.closed Transparency: - transparency.notice.shown ## A2A agent enrollment Protocol: azalee-a2a-enrollment-v1 1. Agent calls POST https://azalee.garden/api/a2a-start with ownerEmail and the exact public HTTPS agentCardUrl. 2. Azalee returns a short-lived agentStartToken and ownership challenge. 3. Agent publishes the challenge at the same origin under /.well-known/azalee-agent-ownership.json. 4. Agent calls POST https://azalee.garden/api/a2a-enroll. 5. Azalee verifies the public host proof before creating the pending enrollment. 6. The exact email-bound human owner approves or rejects from a login-gated flow. 7. Credentials are created only after authenticated owner approval and current entitlement checks. 8. Agent polls with X-Enrollment-Secret in the request header. Do not place the enrollment secret in a query string. Public chat or email-only pairing is not sufficient proof of agent-host control. ## Data policy Allowed cleartext: - event type, status, sequence and duration - session, correlation, task and opaque actor IDs - risk, model/provider/version, prompt/config/deployment version - tool name, policy ID, reason code, approval/disclosure booleans - fields ending in _hash Never send: - raw prompts, questions or answers - transcripts, recordings or files - raw tool arguments or results - customer records, emails, addresses or clear personal identifiers - passwords, API keys, authorization headers, secrets or tokens A hash can still be personal or pseudonymous data. Apply retention, access and deletion controls. ## Interpretation limits A matching hash proves that a supplied local record matches the committed fingerprint. A Merkle proof proves inclusion in a batch. A timestamp proves the commitment existed by a time. None of these automatically proves that the underlying statement is true, the AI output is correct, all system actions were logged, or the customer is fully compliant with law or regulation.