Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.voight.xyz/llms.txt

Use this file to discover all available pages before exploring further.

The single entry point for agent telemetry. Authenticated via API key.

Endpoint

POST https://voight-production.up.railway.app/v1/events

Headers

Authorization: Bearer vk_YOUR_API_KEY
Content-Type: application/json

Request body

{
  "agentId": "string",
  "timestamp": "string | number (optional)",
  "type": "reasoning | tool | tx | decision | action | error (optional)",
  "input": { "prompt": "string", "context": {} },
  "reasoning": "string (optional)",
  "toolsConsidered": ["string"],
  "toolExecuted": "string (optional)",
  "transaction": "string (optional, Solana signature)",
  "amount": { "token": "string", "value": "number" },
  "outcome": "pending | success | failed (optional)",
  "durationMs": "number (optional)",
  "errorMessage": "string (optional)",
  "model": "string (optional)",
  "metadata": { /* free-form */ }
}
FieldTypeRequiredNotes
agentIdstring (1–120 chars)SometimesRequired unless your API key is pre-bound to an agent. Can be a SNS domain, a CUID, or a free-form label.
timestampISO 8601 string or unix ms numberNoDefaults to server-received time.
typeenumNoDefaults to decision.
inputobjectNo{ prompt, context } shape. Stored verbatim in DB after scrubbing.
reasoningstringNoFree-form human-readable trace.
toolsConsideredstring[]NoAlternative tools the agent rejected.
toolExecutedstringNoName of the tool that ran.
transactionstring or nullNoSolana tx signature.
amountobjectNo{ token, value }. For swaps / transfers / payments.
outcomeenumNoOne of pending, success, failed.
durationMsnon-negative integerNoTool runtime.
errorMessagestringNoWhen outcome: 'failed'.
modelstringNoLLM model used (e.g. claude-opus-4-7).
metadataobjectNoFree-form JSON. Voight reads specific keys (tokensBreakdown, traceId, sessionId, cwd, git, privacyLevel, denial, wakeup) but accepts any custom keys.

Validation

The payload is validated with Zod on the server. Failed validation returns 400 Bad Request with details. Unknown top-level keys are rejected; unknown keys inside metadata are accepted.

Identity resolution

The server resolves agentId to an internal cuid in this order:
  1. CUID match — if agentId matches /^c[a-z0-9]{24}$/, look up by primary key directly. Fastest path. Used by SDK 0.3.4+ after the first event populates .voight-agent-id.
  2. snsName match — for SNS domains like trading-bot.sol.
  3. displayName match — for renamed agents.
  4. Create new — if nothing matched, create a new Agent row.
The response always includes the resolved cuid as agentId, regardless of what you sent. Persist it locally to skip resolution on subsequent calls.

Response

202 Accepted

{
  "id": "evt_clz3...",
  "accepted": true,
  "agentId": "cmoq...",
  "eventId": "evt_clz3..."
}
agentId in the response is the resolved cuid. eventId is the new event’s id.

400 Bad Request

{
  "error": "validation_failed",
  "details": [
    {
      "path": ["amount", "value"],
      "message": "Expected number, received string"
    }
  ]
}

401 Unauthorized

{
  "error": "unauthorized",
  "reason": "missing_bearer | invalid_key | revoked_key"
}

410 Gone

{
  "error": "agent_deleted"
}
The agent has been soft-deleted from the dashboard. Ingestion is blocked. Subsequent requests for the same agentId will also return 410. The SDK can react by surfacing a warning to the user.

429 Too Many Requests

{
  "error": "rate_limited"
}
Headers include Retry-After. The SDK respects this automatically with exponential backoff.

500 / 502 / 503

Backend error. Retry with backoff. The SDK does this automatically; for direct HTTP callers, implement reasonable retries.

Side effects

When an event is accepted, the server also:
  • Updates agent.lastSeenAt to now (fire-and-forget)
  • Lazy-backfills agent.framework if the event has metadata.tool and the field was null
  • May trigger anomaly evaluation if this event crosses an alert threshold (next scheduler tick at most 5 minutes later)
  • Stores a contentHash (SHA-256 of the normalised payload) for future on-chain anchoring (mint flow ships in v1.0)

Pre-bound vs free API keys

When you create an API key in the dashboard:
  • Default: not bound to an agent. Caller specifies agentId per event.
  • Bound to an agent: caller can omit agentId; the server uses the bound one. Useful for autonomous bots where the key is dedicated.
Bound keys can’t be used to ingest events for other agents — Voight rejects mismatched agentId values.

Idempotency

Ingestion is not idempotent by default. Each call creates a new row. If you need dedup (e.g. retrying after timeout), generate a stable metadata.dedupKey on your side and reconcile downstream.

Rate limits

TierEvents / monthBurst limit
Free10,00060 events / minute
Pro300,000600 events / minute
EnterpriseUnlimitedCustom
Burst limits are enforced today; monthly quotas ship server-side in v1.0 alongside Stripe billing.

Next

GET /v1/agents

Public agent listing for the Explorer.

/v1/me/*

Authenticated dashboard endpoints.