API reference

Everything a customer integration can call. Base URL https://aegara.ai, and every /v1 endpoint takes your API key as a bearer token.

Authentication

Your API key comes from the Trace Portal: shown once at registration, rotatable any time under API Keys. Your organization is derived from the key, so requests never need to state it.

curl https://aegara.ai/v1/stats \
  -H "Authorization: Bearer aegara_your_key_here"

Errors and limits

StatusMeaning
400Validation failed. The body lists each failing field path and reason.
401Missing or invalid API key.
402Plan cap reached (for example the Free plan's monthly event cap). The body names the cap and links pricing.
422Content policy violation: the event appeared to contain AI prompt or response content. Send behavioral metadata only.
429Rate limited. Retry after a short backoff.

Ingest events

POST/v1/events

Submit one AI Action Event. Returns 202 once the event is durably queued.

POST/v1/events/batch

Submit up to 500 events in one request as a bare JSON array: [ { ...event }, { ...event } ].

curl -X POST https://aegara.ai/v1/events \
  -H "Authorization: Bearer $AEGARA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "trace_id": "trace-checkout-4821",
    "ai_system_id": "support-agent",
    "ai_model_name": "gpt-4o",
    "capability_invoked": "chat.completions",
    "primitive_type": "CALL",
    "actor": { "trigger_type": "user", "user_id": "u-9214", "system_id": null },
    "resources_accessed": [ { "resource_type": "record", "resource_id": "acct-..." } ],
    "fields_accessed": ["plan_name", "renewal_date"],
    "fields_not_accessed": ["payment_method", "tax_id"],
    "systems_contacted": [ { "system_id": "billing-api", "direction": "outbound", "protocol": "https" } ],
    "actions_taken": ["lookup_account"],
    "outputs_generated": [ { "output_type": "ai_response" } ],
    "memory_activity": { "memory_written": false, "memory_read": false, "memory_keys": [] },
    "explicit_negatives": ["No payment data was read"],
    "risk_signals": { "data_sensitivity": "internal", "sensitive_domains": [], "potential_external_exposure": false },
    "schema_version": "1.0.0",
    "environment": "production"
  }'

Event schema

The six behavior primitives: READ, TRANSFORM, WRITE, CALL, STORE, ROUTE. Sensitivity levels: public, internal, confidential, restricted. Sensitive domains: finance, hr, customer_data, intellectual_property, legal, health, credentials, security.

FieldRequiredNotes
trace_idyesGroups the steps of one workflow.
ai_system_idyesYour identifier for the AI system acting.
ai_model_nameyesModel behind the action.
capability_invokedyesWhat was called, for example chat.completions or a tool name.
primitive_typeyesOne of the six primitives.
actoryestrigger_type (user, automation, agent), plus user_id or system_id.
purpose, narrative_summarynever sendWritten by Aegara from the fields below, for example CALL via chat.completions by support-agent. An event that sends either is rejected, because free text is where content slips in.
resources_accessed, fields_accessed, systems_contacted, actions_taken, outputs_generatedyesMay be empty arrays. Field names only, never values. Identify a resource by resource_type and resource_id; a resource_name is rejected.
fields_not_accessed, explicit_negativesyesWhat the AI provably did not touch. This is what makes "prove the AI never read X" a query.
memory_activityyesWhether the AI read or wrote persistent memory.
risk_signalsyesYour initial sensitivity assessment; Sense refines it.
schema_version, environmentyes"1.0.0"; production, staging, or development.
metricsnoMeasurements of the call as whole numbers: latency_ms, input_tokens, output_tokens, total_tokens, message_count. Any other key is rejected. Aegara states them in the summary it writes.
parent_event_id, timestamp, available_toolsnoChain linkage, client timestamp, granted-tool surface.
edgenoVerdicts from edge value inspection. Strictly validated; unknown keys reject the event.

Query events

GET/v1/events
ParamNotes
trace_id, ai_system_id, user_idExact-match filters.
primitive_type, data_sensitivity, environmentEnum filters as above.
from, toISO 8601 timestamp range.
limit, offsetDefault 100, maximum 1000.

Traces and stats

GET/v1/traces/:traceId

Reconstructs a full multi-step workflow in order.

GET/v1/stats

Aggregate counts by primitive, sensitivity, and system.

GET/v1/integrations

Per-AI-system rollup: totals, first and last seen, unique users, primitive and sensitivity breakdowns, and edge_seen, whether that system has sent edge inspection verdicts.

GET/v1/users/summary

Per-user activity rollup.

Sense

Sense infers sensitivity from behavioral metadata across five content-free layers, joined by optional Layer 0 verdicts computed in your environment.

GET/v1/sense/insights
GET/v1/sense/insights/counts
GET/v1/events/:event_id/sense

Per-event reasoning: each signal names its layer, the pattern that matched, and the inferred sensitivity and domain.

POST/v1/events/:event_id/sense/feedback
POST/v1/events/:event_id/sense/override

Tell Sense it got one wrong, or set the classification explicitly. Overrides are append-only with full history.

Discovery

Every new ai_system_id that appears for your organization is registered and can be triaged.

GET/v1/discovery/systems
POST/v1/discovery/systems/:ai_system_id/acknowledge
POST/v1/discovery/systems/:ai_system_id/allowlist
POST/v1/discovery/systems/:ai_system_id/block

Blocked systems are refused at ingestion.

Policies

Real-time rules evaluated against every event as it ingests.

GET/v1/policies
POST/v1/policies
GET/v1/policies/:id
PUT/v1/policies/:id
DELETE/v1/policies/:id
curl -X POST https://aegara.ai/v1/policies \
  -H "Authorization: Bearer $AEGARA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "External exposure of confidential data",
    "enabled": true,
    "severity": "critical",
    "conditions": [
      { "field": "data_sensitivity", "operator": "equals", "value": "confidential" },
      { "field": "potential_external_exposure", "operator": "is_true" }
    ],
    "webhook_url": "https://example.com/hooks/aegara"
  }'
PropertyValues
conditions[].fieldprimitive_type, data_sensitivity, sensitive_domains, potential_external_exposure, ai_system_id, trigger_type, environment
conditions[].operatorequals, not_equals, contains, is_true, is_false
severityinfo, warning, critical
enabledRequired boolean. All conditions must match for the rule to fire.

Webhook delivery

When a rule with a webhook_url fires, Aegara POSTs the alert with three delivery attempts and backoff. Each request carries X-Aegara-Delivery-Id and, when a signing secret exists, X-Aegara-Signature: an HMAC-SHA256 of the raw body with your per-policy secret, returned once at policy creation. Verify the signature before trusting the payload.

Alerts

GET/v1/alerts
GET/v1/alerts/counts
POST/v1/alerts/:id/ack

System-managed alerts (first-seen discovery, edge inspection policy notices) appear here beside your own rules' alerts.

API keys

GET/v1/keys
POST/v1/keys
DELETE/v1/keys/:keyId

Keys are listed masked and can be created and revoked per integration.

SDK

npm install @aegara/sdk. One wrap call instruments OpenAI, Anthropic, Gemini, Bedrock, Cohere, and Mistral clients via auto-detection, and a LangChain callback handler covers 30-plus providers. Full usage lives in the package README.

import { Aegara } from "@aegara/sdk";
const aegara = new Aegara({ apiKey: process.env.AEGARA_API_KEY });
const openai = aegara.wrap(new OpenAI({ apiKey: "sk-..." }), {
  ai_system_id: "support-agent",
  org_id: "org-...",
});

Edge value inspection

Requires @aegara/sdk 0.6.0 or later. Structured values (tool call arguments and tool results) are classified inside your environment by deterministic detectors, and only verdicts cross the wire: a field's key path, the detector that fired, a sensitivity, a domain, and counts. Never a value, a substring, a length, or a hash. This runs on every integration path; nothing needs enabling.

Every result lists the detectors that ran, so "nothing matched" says what was checked. A call with no structured value to read says no_values. An event with no edge at all means the sender never ran the inspector.