For agents

The fastest Argus integration is the one your agent does. Everything on this site exists in machine-readable form, and the pieces below paste straight into Claude Code, Codex, or any agent with a fetch tool.

Hand it to your agent

Paste this into any coding agent and it has enough to do the whole integration — instrument your app, verify an event lands, and stop to ask you for credentials rather than inventing them:

Integrate this project with Argus (https://argus.town), the cross-provider API spend and rate-limit meter. Fetch https://argus.town/llms-full.txt and follow it: instrument our outbound API calls (prefer @argus/sdk for TypeScript, otherwise the signed ingest POST), then verify by sending one test event and reading it back from the events endpoint. Credentials come from the Argus dashboard under Settings — ask me for ARGUS_SOURCE_ID / ARGUS_SOURCE_SECRET (writing) and ARGUS_API_KEY (reading) if they aren't in the environment.

Claude Code skill

One command installs Argus as a skill — Claude then knows the endpoints, the signing recipe, and the verification loop whenever Argus comes up:

mkdir -p .claude/skills/argus && curl -s https://argus.town/skills/argus.md > .claude/skills/argus/SKILL.md

AGENTS.md / Codex

Appends the full brief to your repo's agent instructions:

curl -s https://argus.town/llms-full.txt >> AGENTS.md

Machine-readable surfaces

argus.town/llms.txt — short orientation, per the llmstxt convention.
argus.town/llms-full.txt — the complete integration brief (also below).
argus.town/skills/argus.md — the Claude Code skill, raw.
api.argus.town/.well-known/mcp.json — MCP server discovery: endpoint, auth scheme, tool list.

The brief itself

# Argus — integration brief for AI agents

Argus (https://argus.town) tracks usage, spend, balances, and rate limits across
the third-party APIs an app pays for (LLMs, data providers, scrapers). You
integrate by streaming telemetry to one endpoint. That is the entire
integration — nothing to install, and nothing to build in the app beyond a
single reporting hook at its egress.

## Credential

One credential, created by a human in the dashboard (Settings → Telemetry
sources): a source_id and a source_secret. The secret signs each telemetry
batch. Read them from env (ARGUS_SOURCE_ID, ARGUS_SOURCE_SECRET); never hardcode.
If you don't have them, stop and ask the operator — there is no unauthenticated
write.

## Send telemetry

POST https://api.argus.town/ingest — body `{"events":[…]}`, headers:
- x-argus-source: <source_id>
- x-argus-timestamp: <epoch ms as string>
- x-argus-signature: hex(HMAC-SHA256(source_secret, timestamp + "." + body))

Timestamps over 5 minutes old are rejected. 202 means accepted. Responses are
enveloped: `{"success":true,…}` or `{"success":false,"error":"…"}`. All fields
are snake_case.

Signing (TypeScript, WebCrypto — zero dependencies):

```ts
const body = JSON.stringify({ events });
const ts = Date.now().toString();
const key = await crypto.subtle.importKey("raw",
  new TextEncoder().encode(SOURCE_SECRET),
  { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
const sig = [...new Uint8Array(await crypto.subtle.sign("HMAC", key,
  new TextEncoder().encode(`${ts}.${body}`)))]
  .map(b => b.toString(16).padStart(2, "0")).join("");
await fetch("https://api.argus.town/ingest", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "x-argus-source": SOURCE_ID,
    "x-argus-timestamp": ts,
    "x-argus-signature": sig,
  },
  body,
});
```

## Event fields

All optional. Include `provider` OR `hostname` so the event can be attributed,
and `id` so retries dedupe.

- id — any unique string (ULID ideal); dedupes retries
- provider — Argus provider id ("openrouter", "anthropic", "pdl", …)
- hostname — the host you called ("api.openrouter.ai"); used when you don't pass provider
- endpoint, method, status, latency_ms — endpoint drives per-operation pricing
- model — for LLMs, the model id; Argus prices its tokens from the catalog
- units — {input_tokens, output_tokens, cached_tokens, reasoning_tokens, requests, records, credits}
- provider_request_id — the provider's request id; enables exact server-side cost enrichment
- cost_usd + cost_provenance ("provider_reported" | "app_reported") — only if you already know the cost
- credits_spent, credits_remaining
- rate_limit — {limit_type: "rpm"|"tpm"|"credits", limit, remaining, reset_at}; or rate_limits (array)
- occurred_at — epoch ms (clamped now±48h)
- metadata — your own string key/values (≤2 KB); never required for pricing
- connection_id — pin the event to one connection when you run several accounts for a provider (id from the dashboard)
- pricing_override — {rates:[{unit, nano_usd_per_unit, sku?}]} — price this event
  from your own rates (a negotiated deal), instead of the catalog

Whole event ≤8 KB serialized. Omit cost_usd and Argus prices the event itself:
for LLMs from model + token units; for everything else from the endpoint you
called + units (requests/records/pages) — you never need to know Argus's SKU
names. Prefer sending the endpoint + units and letting Argus price. Order of
precedence: cost_usd → pricing_override → your dashboard rate card → catalog.

## Best practices

- Report only your calls to paid third-party API providers (LLMs, data /
  enrichment / scraping vendors). Do NOT report payment processors (Stripe),
  your own infra or telemetry (Axiom, Sentry, logging), free/internal endpoints,
  or end-user data flows (mailboxes via Gmail/Graph). Argus can't price those —
  they only add noise.
- Tag each event with the `hostname` you called — Argus maps it to the provider
  and prices it. Pass `provider` directly only if you already know the id.
- Prefer omitting cost_usd — let Argus price from the catalog. Pass
  provider_request_id whenever the provider returns one.
- Fire-and-forget: batch events and flush out of band. Never block, delay, or
  fail a user-facing request on Argus. On Cloudflare Workers, ctx.waitUntil the
  flush; in queue/cron handlers, await it before returning.
- Never copy request bodies or auth headers into events, and never log the
  source_secret.

## Reading your meters (separate from integrating)

You do NOT need any of this to integrate — writing telemetry is the whole job,
and it needs no provider ids (Argus maps hostnames for you). Reading is separate:

Spend, runway, balances, and rate-limit headroom live in the Argus dashboard
(https://argus.town). For agents there is a read-only MCP server at
https://api.argus.town/mcp (bearer an ARGUS_API_KEY from the dashboard) — useful
if you want to verify your own work: after sending a test event, register the MCP
and check list_connections / get_request_costs to confirm it landed, instead of
opening the dashboard. That's optional MCP config, not app code — never add
routes in your app that proxy Argus's read API.