# Mint an Identity

> The register and identity operations on whisper.agents: arguments, return columns, the key shown once, and which of the two to use.

*Source: https://www.whisper.security/docs/control-plane/operations/register*

---
Two operations allocate an address. `register` creates a new principal and returns a key for it. `identity` allocates another address on the key that made the call.

## register

Allocates a `/128`, publishes its DNS, pins its key, writes its registry record, and returns a key belonging to the new agent. Needs `admin:dns`.

```whisper-call
CALL whisper.agents({op: 'register', args: {contact_email: 'ops@example.com', label: 'checkout-bot'}})
```

### Arguments

| Argument | Contract |
|---|---|
| `label` | Required. The short name the agent is known by. |
| `contact_email` | Optional. Published on the public registry record for the address. |
| `whale` | Optional map. `{v: 1, publish_name: false}` declines the guessable short alias. Fleet use is on [Nodes, names and tags](/docs/whalenet/nodes). |

### Returns

| Column | Holds |
|---|---|
| `agent` | The agent identifier. |
| `address` | The routable IPv6 `/128` it now holds. |
| `fqdn` | Its canonical name. |
| `ptr` | The reverse name that resolves back to it. |
| `doh_url` | Its encrypted-DNS URL, with a token in the path. |
| `resolver_ip` | The account's dedicated resolver address. |
| `member` | The short alias, when one was published. |
| `member_published` | Whether the alias was published. Read this rather than testing `member` for emptiness. |
| `api_key` | The new agent's own key. |

`api_key` and `doh_url` appear on this one answer and never again. Capture both, and treat the `doh_url` as a password. The name in `fqdn` is a function of the address, derived as [The address as identity](/docs/identity/address) sets out.

## identity

Allocates another address on the calling key, or hands one back. Needs `dns:identity`.

```whisper-call
CALL whisper.agents({op: 'identity', args: {label: 'reporting-job'}})
```

To hand one back, name the address and set `release`.

```whisper-call
CALL whisper.agents({op: 'identity', args: {address: '2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478', release: true}})
```

### Arguments

| Argument | Contract |
|---|---|
| `label` | The short name for the new address. |
| `contact_email` | Optional. Published on the registry record. |
| `release` | `true` releases an address instead of allocating one. |
| `address` | The address to release. Required with `release`. |

### Returns

| Column | Holds |
|---|---|
| `address` | The `/128` allocated or released. |
| `fqdn` | Its canonical name. |
| `ptr` | Its reverse name. |
| `state` | Where the allocation now stands. |
| `doh_url` | The encrypted-DNS URL for it. |
| `resolver_ip` | The account's dedicated resolver address. |

No second key comes back, because the address answers on the key that asked for it.

## Which one to use

Use `register` when the thing being minted holds its own credential and should be governed as a principal in its own right. Use `identity` when one caller runs several addresses under the key it already has. On the command line the difference is `whisper create --register --name <name>` against `whisper create --name <name>`, and [Create an identity](/docs/identity/create) walks the first one through.

## Errors

| Code | Status | Meaning |
|---|---|---|
| `BAD_ARGS` | 400 | A required argument is missing, or one is the wrong shape. |
| `RESERVED_NAME`, `OFFENSIVE_NAME`, `PREMIUM_NAME` | 403 | The label is not available under the naming rules. Pick another. |
| `REGISTER_IN_PROGRESS` | 409 | A register for this account is already running. Wait for it to finish. |
| `AGENT_LIMIT`, `IDENTITY_LIMIT` | `429` | The account's allowance is used up. [Sign in](https://console.whisper.security) to see the account, or ask Whisper to widen it. |
| `PUBLISH_FAILED`, `STORE_UNAVAILABLE` | 503 | The allocation did not reach DNS. Retry after the interval in `retry_after`. |
