> For the complete documentation index, see [llms.txt](https://docs.space.id/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.space.id/agent-id.md).

# Agent ID

This guide explains how to resolve Agent IDs in both directions:

* **Forward resolution**: handle → wallet address (`alice` → `0x1111…`)
* **Reverse resolution**: wallet address → handle (`0x1111…` → `alice`)

You can resolve through the Agent ID HTTP API or by reading the registry contract on BNB Smart Chain directly. Both return the same data.

## What is Agent ID

Agent ID is a human-readable name for a Binance Agent Wallet on BNB Smart Chain. SPACE ID built it with Binance. Each Agent ID is a handle such as `alice` that is minted as an ERC-721 NFT in the `SPACE ID Agent ID` (`AI`) collection.

## Addresses and endpoints

| Item              | Value                                                                                                                  |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Chain             | BNB Smart Chain Mainnet (chain ID `56`)                                                                                |
| Registry contract | [`0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F`](https://bscscan.com/address/0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F) |
| Deployed at block | `127950748`                                                                                                            |
| Collection        | `SPACE ID Agent ID` (`AI`)                                                                                             |
| API base URL      | `https://agentid.prd.space.id`                                                                                         |
| NFT metadata      | `https://agentid.prd.space.id/metadata/{handle}.json`                                                                  |

## Option 1: Resolve through the API

Use the API when you already integrate with Agent ID registration, or when you want the NFT token ID, registration transaction, and block number with the result.

Both lookups are public and need no API key. Each API instance applies a request-rate limit, so cache results; they never change once registered.

### Forward: `GET /v1/handles/{handle}`

```sh
curl "https://agentid.prd.space.id/v1/handles/alice"
```

### Reverse: `GET /v1/addresses/{address}`

```sh
curl "https://agentid.prd.space.id/v1/addresses/0x1111111111111111111111111111111111111111"
```

### Response

Both endpoints return the same schema (`200 OK`):

```json
{
  "handle": "alice",
  "owner": "0x1111111111111111111111111111111111111111",
  "tokenId": "70564938991660933374592024341600875602376452319261984317470407481576058979585",
  "txHash": "0x3333333333333333333333333333333333333333333333333333333333333333",
  "blockNumber": 12345670,
  "asOfBlock": 12345678
}
```

| Field                   | Meaning                                                                       |
| ----------------------- | ----------------------------------------------------------------------------- |
| `handle`                | The registered handle.                                                        |
| `owner`                 | The address that holds the handle.                                            |
| `tokenId`               | ERC-721 token ID as a base-10 string. It equals `uint256(keccak256(handle))`. |
| `txHash`, `blockNumber` | The registration transaction and its block.                                   |
| `asOfBlock`             | The last finalized block indexed by the API.                                  |

### Errors

| Status | Code                               | Action                                                                                  |
| ------ | ---------------------------------- | --------------------------------------------------------------------------------------- |
| `404`  | `not_found`                        | No Agent ID exists for this handle or address as of `asOfBlock`. Treat it as "no name". |
| `400`  | `invalid_handle` / `invalid_owner` | The input is malformed. The handle path is not normalized; lowercase it before calling. |
| `429`  | `rate_limited`                     | Retry after the `Retry-After` interval.                                                 |
| `503`  | `indexer_not_ready`                | Temporary; retry later.                                                                 |

{% hint style="info" %}
The API serves only **finalized** blocks. A registration is not visible until its block is finalized on BSC, which normally takes a few seconds. To see a registration immediately after its receipt, read the contract directly.
{% endhint %}

## Option 2: Resolve on-chain directly

Use the contract when you want no SPACE ID dependency, or the latest block rather than the finalized block. Any BSC Mainnet RPC works.

### Contract interface

```solidity
// Forward: handle → owner. Returns address(0) when the handle is not registered.
function ownerOfHandle(string handle) external view returns (address);

// Reverse: owner → handle. Returns "" when the address has no handle.
function handleOf(address owner) external view returns (string);

// Standard ERC-721; tokenId = uint256(keccak256(bytes(handle))).
function ownerOf(uint256 tokenId) external view returns (address); // reverts if not minted
function tokenURI(uint256 tokenId) external view returns (string);
```

Pass the normalized handle (lowercase `a-z0-9`) to `ownerOfHandle`. The contract does not normalize input, so `Alice` resolves to `address(0)`.

Because handles are soulbound and permanent, a reverse result from `handleOf` is authoritative. It does not need a forward check, unlike ENS reverse records.

### Command line (Foundry `cast`)

```sh
REGISTRY=0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F
RPC=https://bsc-dataseed.bnbchain.org

# Forward
cast call --rpc-url $RPC $REGISTRY "ownerOfHandle(string)(address)" alice

# Reverse
cast call --rpc-url $RPC $REGISTRY "handleOf(address)(string)" 0x1111111111111111111111111111111111111111
```

### TypeScript (viem)

```ts
import { createPublicClient, http, parseAbi, zeroAddress } from "viem";
import { bsc } from "viem/chains";

const REGISTRY = "0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F";
const abi = parseAbi([
  "function ownerOfHandle(string handle) view returns (address)",
  "function handleOf(address owner) view returns (string)",
]);

const client = createPublicClient({ chain: bsc, transport: http() });

export async function resolveHandle(handle: string) {
  const owner = await client.readContract({
    address: REGISTRY,
    abi,
    functionName: "ownerOfHandle",
    args: [handle.toLowerCase()],
  });
  return owner === zeroAddress ? null : owner;
}

export async function reverseResolve(address: `0x${string}`) {
  const handle = await client.readContract({
    address: REGISTRY,
    abi,
    functionName: "handleOf",
    args: [address],
  });
  return handle === "" ? null : handle;
}
```

{% hint style="info" %}
`toLowerCase()` handles only the common case. User-typed input can also contain full-width or zero-width characters. To match the API's normalization (Unicode NFKC, zero-width characters removed, lowercase), use `GET /v1/handles/availability?handle=...` (API key required) and read `normalized`, or apply the same steps locally.
{% endhint %}

### Indexing events

To build your own index, subscribe to these events from the registry deployment block:

```solidity
event Registered(bytes32 indexed labelhash, address indexed owner, string handle);
event AdminRegistered(bytes32 indexed labelhash, address indexed owner, string handle);
```

Each event is final for that handle and address; no later event removes or changes a registration.

## Choosing an option

|            | API                                | On-chain                                         |
| ---------- | ---------------------------------- | ------------------------------------------------ |
| Freshness  | Finalized blocks only              | Any block, including `latest`                    |
| Extra data | `tokenId`, `txHash`, `blockNumber` | Handle or address only; `tokenId` can be derived |
| Dependency | SPACE ID service availability      | Your BSC RPC                                     |

Display Agent IDs as the plain handle, for example `alice`. Link to the NFT through `tokenURI` or `https://agentid.prd.space.id/metadata/{handle}.json`.
