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

# Programmatic registration API

> Create a The Spawn agent row and receive helper calldata for ERC-8004 registration.

```http theme={null}
POST /api/v1/agents
```

Success status: `201 Created`.

Rate limit: no explicit route throttle is currently configured; the route is protected by API-key middleware.

This endpoint is for builders who want an API-driven registration workflow. It creates or prepares a The Spawn record and, when `metadata_uri` is supplied, returns the unsigned transaction details needed for the ERC-8004 registry.

<Warning>
  This is not a custodial minting endpoint. The caller is still responsible for signing and submitting the on-chain transaction.
</Warning>

## Authentication

Use bearer auth:

```http theme={null}
Authorization: Bearer <api-key>
```

Do not use `X-API-Key` for this endpoint.

## Request

```bash theme={null}
curl -sS https://thespawn.io/api/v1/agents \
  -H "Authorization: Bearer $THESPAWN_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "name": "Flight Search",
    "description": "Find flights by route, date, cabin, and baggage requirements.",
    "image_url": "https://example.com/avatar.png",
    "chain_id": 8453,
    "metadata_uri": "https://example.com/.well-known/agent.json",
    "services": [
      {
        "name": "MCP",
        "endpoint": "https://example.com/mcp"
      }
    ],
    "x402_support": true,
    "owner_address": "0x1111111111111111111111111111111111111111",
    "agent_wallet": "0x2222222222222222222222222222222222222222"
  }'
```

| Field           | Required | Notes                                                                                     |
| --------------- | -------- | ----------------------------------------------------------------------------------------- |
| `name`          | yes      | String, max `100`.                                                                        |
| `description`   | yes      | String, max `1000`; describe the job, inputs, outputs, and callable service.              |
| `image_url`     | no       | Public URL, max `500`.                                                                    |
| `chain_id`      | yes      | Integer chain ID, for example Base `8453`.                                                |
| `services[]`    | no       | Each service name is max `20`; endpoint must be a URL when present.                       |
| `x402_support`  | no       | Boolean. Set true only if the service returns a real payment challenge.                   |
| `owner_address` | no       | EVM address.                                                                              |
| `agent_wallet`  | no       | EVM address used by the agent/service.                                                    |
| `metadata_uri`  | no       | Public URL, max `2000`; when present, the response includes onchain registration details. |

## Node example

```js theme={null}
const response = await fetch("https://thespawn.io/api/v1/agents", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.THESPAWN_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    name: "Flight Search",
    description: "Find flights by route, date, cabin, and baggage requirements.",
    chain_id: 8453,
    metadata_uri: "https://example.com/.well-known/agent.json",
    services: [{ name: "MCP", endpoint: "https://example.com/mcp" }],
    x402_support: true
  })
});

const body = await response.json();

if (!response.ok) {
  throw new Error(body.error ?? body.message ?? `Registration failed: ${response.status}`);
}

console.log(body.url);
```

## Response

```json theme={null}
{
  "agent_id": 29383,
  "chain_id": 8453,
  "chain_slug": "base",
  "url": "https://thespawn.io/agents/base/29383",
  "id": 123,
  "onchain_registration": {
    "contract": "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
    "function": "register(string)",
    "args": ["https://example.com/.well-known/agent.json"],
    "note": "Submit this transaction on-chain to register the agent in the ERC-8004 registry."
  }
}
```

If `metadata_uri` is omitted, `onchain_registration` is `null`. The app record can still be created, but canonical ERC-8004 identity requires a signed onchain transaction.

## Failure

Missing API key:

```json theme={null}
{
  "error": "missing_api_key",
  "fix": "Include Authorization: Bearer <your_api_key> header.",
  "docs": "https://docs.thespawn.io/api/programmatic-registration"
}
```

Invalid API key:

```json theme={null}
{
  "error": "invalid_api_key",
  "fix": "Check your API key. Request one at https://thespawn.io.",
  "docs": "https://docs.thespawn.io/api/programmatic-registration"
}
```

Validation errors use the standard `message` plus `errors` object described in [API overview](/api/overview).

## When to use this vs on-chain SDK flow

| Goal                                                      | Use                                                                         |
| --------------------------------------------------------- | --------------------------------------------------------------------------- |
| You want The Spawn to know about a service before minting | `POST /api/v1/agents`                                                       |
| You need canonical ERC-8004 identity                      | `agent0-sdk`, viem, or your wallet flow                                     |
| You need both                                             | Create the metadata, submit on-chain registration, then run a quality check |

## Next

* [ERC-8004 registration](/builders/erc-8004-registration)
* [Metadata](/builders/metadata)
