> ## Documentation Index
> Fetch the complete documentation index at: https://docs.natural.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> When building application code, use `@naturalpay/sdk` for TypeScript or `naturalpay` for Python.
> When operating Natural directly for a user, use the payments MCP at `https://mcp.natural.com`.
> When searching Natural documentation, use the docs MCP at `https://docs.natural.com/mcp`.
> Use the Natural CLI for terminal and CI automation.
> Use REST only for unsupported languages or when the user explicitly requests raw HTTP.
> Start integration development and testing in the sandbox. Do not use production unless the user explicitly requests it.
> For sandbox requests that require `customerPartyId`, list customers first. Reuse only the intended fixture; otherwise create a customer.
> REST and SDK amounts use integer minor units. Payments MCP amounts use decimal strings with a required currency code.

# Create an agent

> Create an agent and get back its agent ID

Create an agent (`agt_*`) to have the money it moves attributed to it, then give it a key.

<Snippet file="shared/prerequisites.mdx" />

<Snippet file="shared/mcp-callout.mdx" />

## Create the agent

Create an agent with [`POST /agents`](/api-reference/agents/create-agent).

<CodeGroup>
  ```python Python theme={null}
  import uuid
  from naturalpay import Natural
  from naturalpay.agents import CreateAgentsRequestLimits

  client = Natural()
  agent = client.agents.create(
      name="Procurement Agent",
      description="Buys supplies",
      limits=CreateAgentsRequestLimits(per_transaction=100_000),
      idempotency_key=str(uuid.uuid4()),
  )

  agent_id = agent.data.id
  ```

  ```typescript TypeScript theme={null}
  import Natural from "@naturalpay/sdk";

  const client = new Natural();
  const agent = await client.agents.create({
    name: "Procurement Agent",
    description: "Buys supplies",
    limits: { perTransaction: 100_000 },
    idempotencyKey: crypto.randomUUID(),
  });

  const agentId = agent.data.id;
  ```

  ```bash CLI theme={null}
  natural agents create --json '{
    "name": "Procurement Agent",
    "description": "Buys supplies",
    "limits": { "perTransaction": 100000 }
  }' --idempotency-key "$(uuidgen)"
  ```

  ```text MCP theme={null}
  Create an agent called "Procurement Agent" for buying supplies, with a $1,000 per-transaction limit.
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.natural.com/agents \
    -H "Authorization: Bearer $NATURAL_API_KEY" \
    -H "Idempotency-Key: $(uuidgen)" \
    -H "Content-Type: application/json" \
    -d '{
      "data": {
        "attributes": {
          "name": "Procurement Agent",
          "description": "Buys supplies",
          "limits": { "perTransaction": 100000 }
        }
      }
    }'
  ```
</CodeGroup>

`name` is up to 32 characters and `description` up to 100. `limits` takes `perTransaction`, `perDay`, and `perMonth` in integer cents. Pass `walletId` to choose the wallet the agent spends from; omit it and Natural attaches your default wallet. Natural derives the agent's handle slug from its name; to claim a specific `slug`, see [Claim a handle](/guides/agents/handles).

The response carries the agent's ID (`agt_*`). Attribution comes from the agent's key, not from a request field; issue a key next.

<Snippet file="api-examples/agents.create.response.mdx" />

## Issue a key

Creating an agent returns its ID, not a credential. Issue a key next so your runtime can authenticate as that agent with `ak_ntl_*`. Over the API you call [`POST /agent-keys`](/api-reference/agent-keys/create-agent-key) next; the dashboard does both steps for you.

<CodeGroup>
  ```python Python theme={null}
  key = client.agent_keys.create(
      data={
          "attributes": {},
          "relationships": {
              "agent": {"data": {"type": "agent", "id": agent_id}},
          },
      },
  )
  print(key.data.attributes.agent_key)
  ```

  ```typescript TypeScript theme={null}
  const key = await client.agentKeys.create({
    data: {
      attributes: {},
      relationships: {
        agent: { data: { type: "agent", id: agentId } },
      },
    },
  });
  console.log(key.data.attributes.agentKey);
  ```

  ```bash CLI theme={null}
  natural agent-keys create --agent-id agt_019cd1798d637a4da75dce386343931d
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.natural.com/agent-keys \
    -H "Authorization: Bearer $NATURAL_USER_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "data": {
        "attributes": {},
        "relationships": {
          "agent": {
            "data": { "type": "agent", "id": "agt_019cd1798d637a4da75dce386343931d" }
          }
        }
      }
    }'
  ```
</CodeGroup>

The response carries the full secret in `agentKey`:

<Snippet file="api-examples/agentKeys.create.response.mdx" />

Issue keys from a user session only, not from a party API key; `$NATURAL_USER_TOKEN` in the cURL example is that session credential, the same one `natural login` stores for the CLI. The full secret is returned once, so store it in your secrets manager immediately. Afterward you can see only its prefix.

To list, rotate, or revoke keys on an existing agent, see [Manage your agents](/guides/agents/manage-agents#manage-agent-keys). For how agents, keys, and limits fit together, read the [Agents overview](/guides/concepts/agents).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.