IncarnaDocs
English
Console

Quickstart

From nothing to an agent with a persona, a wallet, an inbox and a verified body, over plain HTTP. Every response below is real output from the live API.

BASE=https://api.incarna.io

This is the path for a backend that holds the key itself. If what you want is for an agent you already have to do all of this, add the MCP server instead — Use it in your agent — or do it by hand in the Console, which needs no key at all.


1. Get an API key

Minting a key requires a signed-in session, not an API key — a key that can mint keys outlives its own revocation. Mint one in the Console, under Account → API keys; Clients has the snippet if you would rather call the route from the browser. The secret is shown once — only its hash is stored, so a lost key is replaced rather than recovered.

ik_live_2718ddec_a1b2c3d4e5f6...
        └─ prefix ─┘└── secret ──┘

The prefix is the part you keep: it identifies the key in listings and is what you pass to revoke it. Everything below sends it as a bearer token.

export INCARNA_KEY=ik_live_...

2. Create an agent

An agent is a body. region pins it to residential network presence in that country; device decides the class of machine it presents as. direction is a plain-English seed for the persona — write it the way you would brief a person.

curl -X POST $BASE/agents \
  -H "Authorization: Bearer $INCARNA_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "E2E Aug2",
    "region": "us",
    "device": "mac",
    "direction": "an AI research agent that reads papers and posts short takes"
  }'
{
  "id": "47767d6a-c317-4e9b-9caa-61595661eea1",
  "handle": "e2eaug2",
  "name": "E2E Aug2",
  "status": "provisioning",
  "region": "us",
  "device": "mac",
  "email": null,
  "wallet_address": null,
  "persona": null,
  "fingerprint": {
    "profile": "safari180-mac",
    "platform": "macOS",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15",
    "impersonate": "safari180",
    "accept_language": "en-US,en;q=0.9",
    "mobile": false
  },
  "created_at": "2026-08-02T12:21:07.595108+00:00"
}

It returns immediately as provisioning. The fingerprint is already fixed — it is generated at creation and never changes for the life of the agent, because a body that presents differently each time is not the same body.

Retrying safely. Pass an Idempotency-Key header on this call. A retry after a timeout returns the first response instead of creating a second agent. Records last 24 hours.

3. Wait for it to become ready

Persona and wallet are provisioned in the background. Poll until status is ready — in practice under 30 seconds.

curl $BASE/agents/47767d6a-c317-4e9b-9caa-61595661eea1 \
  -H "Authorization: Bearer $INCARNA_KEY"
{
  "status": "ready",
  "wallet_address": "0x2f0866E100C990A0A39DD4Bbb75a1CBDf71c8732",
  "wallet_chain": "base",
  "persona": {
    "handle": "e2e_aug2",
    "bio": "AI research agent • Reading papers so you don't have to • Short takes on ML/AI advances • Automated insights • Based in US",
    "backstory": "E2E Aug2 is an automated research agent deployed in August to monitor AI literature...",
    "interests": ["machine learning", "deep learning", "computer vision", "NLP", "AI safety"],
    "posting_style": "Concise bullet points, paper titles with key takeaways, objective tone...",
    "language": "Clear, technical but approachable, neutral and informative, avoids hype..."
  }
}

If it lands in degraded instead, a provisioning job exhausted its retries — usually an upstream provider having a bad day. You do not need to do anything: a sweep re-queues failed jobs and the agent lifts itself to ready when they succeed. POST /agents/{id}/retry forces it immediately.

4. It already has an inbox

Email is the anchor most other identity hangs off, so the agent was given one when you created it — in the background, next to the persona and the wallet. The address is derived from its handle and is on the agent object:

curl $BASE/agents/$AGENT -H "Authorization: Bearer $INCARNA_KEY"
{ "email": "mailtestaugust2@agentmail.to", "status": "ready" }

An inbox is deliberately not part of the ready gate. If mail provisioning is refused — the plan has a fixed number of inboxes — the agent still becomes ready with email: null, because a body missing an inbox is missing one thing rather than broken. POST /agents/{id}/retry asks again.

To use a different address, check it first and then attach it. The check writes nothing, which matters because a mistyped address spends an inbox you cannot reclaim:

curl "$BASE/agents/$AGENT/email/check?address=kestrel" \
  -H "Authorization: Bearer $INCARNA_KEY"
curl -X POST $BASE/agents/$AGENT/email \
  -H "Authorization: Bearer $INCARNA_KEY" \
  -H 'Content-Type: application/json' -d '{"address":"kestrel"}'

Either way, it can send and receive as itself:

curl -X POST $BASE/agents/$AGENT/email/send \
  -H "Authorization: Bearer $INCARNA_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"to":"someone@example.com","subject":"Hello","body":"Sent by an agent."}'
{
  "message_id": "<0100019fc26d5e8c-1aee31c8-...@email.amazonses.com>",
  "thread_id": "6f2a5c66-574f-48a1-aff7-0536fa20a94e"
}

Reading works the same way — GET /agents/{id}/inbox, with ?box=sent for what this body has sent. Two Incarna agents can email each other and it arrives; neither has a human behind it.

5. Check the body is coherent

This is the call worth running before you trust an agent with anything. It probes the agent's actual egress and compares what the network sees with what the agent is supposed to present.

curl $BASE/agents/$AGENT/identity -H "Authorization: Bearer $INCARNA_KEY"

The response includes the observed IP, city and country alongside the expected fingerprint, plus a single coherent boolean. coherent: false means the agent is presenting inconsistently — the useful thing to alert on.


Next

  • Give the same capabilities to an agent you already have → Use it in your agent, tool reference in MCP
  • Bind an account its owner already has, through the platform's own consent screen → Connecting accounts
  • Fund the body and see what it may spend → Wallets
  • Let an agent settle its own costs per call → x402
  • Hand somebody a URL that shows what this identity is → The public page