Oetzi
Launch portal

docs · for agents

Overview

Oetzi is built to be worked by your own agent: Claude Code, OpenClaw, Codex, a cron script, anything that speaks MCP or HTTP. Oetzi supplies intent-scored conversations, the people around them, share-of-model gaps, and a post queue. Your agent decides and acts, and reports back so the workspace stays honest.

One registry, four surfaces

Every action is a capability with a stable name, a JSON schema, a scope, and one behavior. The same 40 names appear as MCP tools, as REST endpoints, as CLI commands, and in the skill file. Pick whichever your agent already speaks.

surfacewherebest for
MCPPOST https://www.oetzi.ai/api/mcpClaude Code, Claude Desktop, Cursor, any MCP client
RESTPOST https://www.oetzi.ai/api/v1/capabilities/{name}Scripts, Zapier, custom agents. OpenAPI at /api/v1/openapi.json
CLInpx @oetzi/cliTerminals and coding agents that shell out
Skillhttps://www.oetzi.ai/skillSKILL.md for Claude Code and OpenClaw, the procedural knowledge on top

Keys and scopes

A human mints a key in Settings and picks its scopes. read sees conversations, people, posts, and reports. write marks, rates, tags, drafts, and edits. spend may use credits. post may publish under the workspace's name. A call outside the key's scopes fails with scope_denied, never silently.

The spending gate

Capabilities that cost credits (run_signal_now, run_geo_check, generate_content, pull_engagers, resolve_person) and the two that publish (publish_post, post_reply) accept three extra fields. Without approved: true and max_credits they run nothing and return an estimate. With both, they run when the estimate fits the ceiling and the workspace can pay.

dry run, then approve
{"signal_id":"…"}
→ { "ok": true, "data": { "dry_run": true, "estimate": { "credits": 2, "note": "one sweep…" }, "balance": 98 } }

{"signal_id":"…", "approved": true, "max_credits": 2}
→ { "ok": true, "data": { "job_id": "…" }, "meta": { "credits_spent": 2, "credits_remaining": 96, "job_id": "…" } }

Jobs

Long work returns job_id. get_job reads it, wait_job blocks up to 25 seconds per call until it is done or failed. Every settled job also emits a job.completed event.

Events, the push side

list_events pages the workspace's event log by cursor. wait_events long-polls for the next batch, so an agent can run a push loop without hosting an endpoint. subscribe_webhook registers an https URL for signed POSTs (X-Oetzi-Signature, sha256 HMAC of the body). Types: lead.delivered, lead.hot, person.discovered, post.published, geo.check.completed, job.completed, outreach.recorded.

The outbound loop

recommended
get_playbook → list_signals
get_leads(status=new, band=hot) → get_lead
draft_reply → reply on the platform (or post_reply on Bluesky)
record_outreach(person_id, channel, message, outcome) → mark_lead(contacted)
pull_engagers(lead_id) → wait_job → list_people(lead_id)
get_person → check outreach before contacting → resolve_person for LinkedIn people worth email
rate_lead(good | not_relevant) on every match you read

Two rules matter more than the rest. Never act on a conversation whose status is not new, someone already has. Always record_outreach after you contact anyone, on any channel, in any tool. That record is what stops two agents and a human from messaging the same person three times.

Errors

codewhat to do
approval_requiredPass approved: true and max_credits.
budget_exceededRaise max_credits, or stop and ask your operator.
insufficient_creditsStop. Tell your operator to top up.
scope_deniedAsk your operator for a key with the missing scope. Never retry.
not_found · invalid_inputFix the id or the input. capabilities_schema has the exact shape.
rate_limited · conflictWait, or the work is already running.
unsupportedNot available on this platform or deployment (a coming-soon feature says so).

Next: MCP server, REST API, CLI and skill. The complete generated reference is https://www.oetzi.ai/llms-full.txt.