Docs / API reference
HTTP API reference.
What the Python and TypeScript SDKs post on the wire. Production base URL is https://mesedi-api.fly.dev. Local development is http://localhost:8080. If you're using one of the SDKs, you never need this page; it's here for non-Python, non-Node stacks and for self-hosters who want to verify what their agents are sending.
Authentication
Every protected endpoint requires a bearer token. Mint one in the dashboard under API Keys. The raw key is shown once at mint time; we cannot recover it for you later.
Authorization: Bearer mesedi_sk_...Requests without Authorization: Bearer are rejected with 401. Requests with an unrecognized key are rejected with 401. Requests with a project_id in the body that does not match the auth-context project are rejected with 403.
Schema versioning
Every request should include X-Mesedi-Schema-Version: 1. The backend policy:
- Header missing: accepted (assumed current version, soft-mode for bring-up flows and curl smoke tests).
- Header equals
1: accepted. - Header present and not
1: rejected with 400 and a message naming the supported version(s).
When v2 ships, the policy tightens to missing → 400 so unversioned callers surface loudly instead of silently coasting on a stale wire format.
POST /executions
Record the start of an agent execution.
curl -X POST https://mesedi-api.fly.dev/executions \
-H "Authorization: Bearer $MESEDI_API_KEY" \
-H "X-Mesedi-Schema-Version: 1" \
-H "Content-Type: application/json" \
-d '{
"execution_id": "exec-001",
"status": "started",
"sdk_language": "python",
"sdk_version": "0.1.0"
}'
PATCH /executions/{id}
Update an execution. Used by the SDKs to mark completion or crash.
# completed
curl -X PATCH https://mesedi-api.fly.dev/executions/exec-001 \
-H "Authorization: Bearer $MESEDI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "completed",
"duration_ms": 1234,
"total_tokens_in": 50,
"total_tokens_out": 200
}'
# crashed
curl -X PATCH https://mesedi-api.fly.dev/executions/exec-001 \
-H "Authorization: Bearer $MESEDI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "crashed",
"crash_signature": "sha256:abcdef...",
"duration_ms": 412
}'
POST /events
Ship a batch of events for an existing execution. The SDKs batch up to ~100 events every few hundred milliseconds.
curl -X POST https://mesedi-api.fly.dev/events \
-H "Authorization: Bearer $MESEDI_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"event_id": "evt-001",
"execution_id": "exec-001",
"event_type": "llm_call",
"sequence": 1,
"timestamp": "2026-05-24T14:00:00Z",
"payload": {
"model": "claude-opus-4-6",
"tokens_in": 12,
"tokens_out": 80
}
}
]'
Common event_type values: llm_call, tool_call, checkpoint, validator_check.
Rate limiting
Every authenticated request consumes 1 token from a per-project bucket. Defaults: burst capacity 100 tokens, refill 10 tokens/second. A well-behaved SDK (events buffered client-side, flushed in batches) never sees a 429. An infinite-loop agent without backoff hits 429 within ~10 seconds.
Every response (200 and 429 alike) includes:
X-RateLimit-Limit: bucket capacityX-RateLimit-Remaining: tokens left after this requestX-RateLimit-Reset: Unix timestamp when the bucket refills to full
On 429, AWS-style Retry-After: 1 is also set.
Webhook delivery contract
When a failure-class detector fires for the first time in a project (or after a configured cooldown), Mesedi POSTs a JSON payload to each configured webhook URL. See Webhooks in the dashboard to configure URLs.
POST <your webhook url>
Content-Type: application/json
X-Mesedi-Signature: sha256=...
X-Mesedi-Event: failure_group.first_occurrence
{
"event": "failure_group.first_occurrence",
"project_id": "proj_...",
"failure_group": {
"id": "fg_...",
"class": "prompt_injection",
"signature": "...",
"first_seen_at": "2026-05-24T14:00:00Z",
"severity": "high"
},
"playbook_url": "https://mesedi.vercel.app/app/playbooks/prompt_injection"
}
The signature is HMAC-SHA256 of the raw request body keyed by the webhook secret shown to you at create time. Slack and Discord URLs are auto-detected and receive native attachments / embeds; plain URLs get the JSON above.
GET /health
Public, no auth. Used by the status page at mesedi-ai.github.io/status.
curl https://mesedi-api.fly.dev/health
# {"ok":true,"service":"mesedi-backend","version":"...","time":"..."}
What's next?
Failure classes and playbooks explains what each detector is looking for in the telemetry you ship.
Self-hosting guide covers running the Go backend behind your own infrastructure.