> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.ampdb.io/api/mcp` to find what you need.

# ampctl configmap

Status: Unstable.

`ampctl configmap` manages [config maps](/managing-amp/config-maps): configuration documents, like an RPC endpoint and
its rate limits, meant to be shared by several jobs and changed on your own schedule. Amp stores them, but no job reads
them yet: jobs take their settings from their own options and from [providers](/clis/ampctl/provider).

Each config map is a JSON document addressed by a namespace and a name, like `acme/mainnet_rpc`, with a kind that names
the part of Amp meant to read it, like `evm-rpc`. Amp stores the document as you send it and never checks it against
its kind. To learn what goes in a document and how to reference environment variables from it, see
[Config Map Format](/managing-amp/config-maps/format) and [Secrets](/managing-amp/config-maps/secrets).

## Prerequisites

* A running Amp, like the one the [Quickstart](/get-started/quickstart) starts with [solo mode](/running-amp/solo-mode).
* `ampctl`, [installed](/clis/ampctl#install) and [connected to it](/clis/ampctl#connect-to-amp).

Every command also takes the [global flags](/clis/ampctl#global-flags): `--admin-url`, `--auth-token`, and `--json`,
which prints the result as [JSON](/clis/ampctl#json-output).

## Names

Every command addresses a config map by its namespace and its name:

* **Namespace**: lowercase letters, digits, and underscores, like `acme`.
* **Name**: lowercase letters, digits, and underscores, starting with a letter or an underscore, like `mainnet_rpc`.
* **Kind**: any text that isn't empty, like `evm-rpc`.

`inspect`, `update`, and `delete` take them as one argument, `namespace/name`. There's no default namespace, so a name
alone fails:

```
error: invalid value 'mainnet_rpc' for '<NAMESPACE/NAME>': config map reference 'mainnet_rpc' is not a 'namespace/name' pair
```

A config map has no versions. Each write that changes its document or kind gives it a new id, a
[UUIDv7](https://www.rfc-editor.org/rfc/rfc9562#name-uuid-version-7), and discards the previous document. Commands
print that id, so you can tell whether a write changed anything.

When the Admin API requires authentication, each token is granted access to some namespaces. A namespace your token
wasn't granted answers like one that doesn't exist, so commands fail with `namespace 'acme' not found` or
`config map 'acme/mainnet_rpc' not found` whether or not it does. [Solo mode](/running-amp/solo-mode) grants every
namespace.

## `ampctl configmap create`

Creates a config map from a JSON or TOML file.

```
ampctl configmap create [OPTIONS] --namespace NAMESPACE --from-file FILE NAME
```

| Argument / flag           | Type        | Default               | Description                                                                                    |
| ------------------------- | ----------- | --------------------- | ---------------------------------------------------------------------------------------------- |
| `NAME`                    | string      | required              | The config map's [name](/clis/ampctl/configmap#names), like `mainnet_rpc`.                                           |
| `--namespace <NAMESPACE>` | string      | required              | The [namespace](/clis/ampctl/configmap#names) to create it in, like `--namespace acme`.                              |
| `--from-file <FILE>`      | path or URL | required              | The document. See [`--from-file`](/clis/ampctl/configmap#--from-file-file).                                          |
| `--kind <KIND>`           | string      | the file's `kind` key | The [kind](/clis/ampctl/configmap#names), like `--kind evm-rpc`. Required when the file has no top-level `kind` key. |

Its alias is `ampctl configmap register`.

### `--from-file <FILE>`

The file holding the document, which `create` and `update` read.

* **Type**: a local path, or a `file://`, `s3://`, `gs://`, or `az://` URL

* **Format**: chosen by the file's extension: `.json` is read as JSON, and `.toml` as TOML, which `ampctl` converts to
  JSON before sending it. Any other extension fails, whatever the file contains:

  ```
  error: invalid value './tuning.yaml' for '--from-file <FILE>': unsupported config map file extension for ./tuning.yaml: expected .json or .toml
  ```

* **Object storage**: `ampctl` reads the file itself, with the credentials in its environment, like
  `AWS_ACCESS_KEY_ID`, `GOOGLE_APPLICATION_CREDENTIALS`, or `AZURE_STORAGE_ACCOUNT_NAME`.

Amp stores the document as JSON that keeps neither the order of its keys nor duplicate keys, so reading it back doesn't
return your file byte for byte. If the file has a top-level `kind` key, `--kind` defaults to it, and the key stays in
the document.

```toml [mainnet.toml]
kind = "evm-rpc"
network = "mainnet"
url = "https://ethereum-rpc.example.com"
auth_token = "${{ env.MAINNET_RPC_TOKEN }}"
```

:::terminal
```bash
ampctl configmap create mainnet_rpc --namespace acme --from-file ./mainnet.toml
```

```
✓ ConfigMap created
  Name: acme/mainnet_rpc
  Kind: evm-rpc
  Id: 01a18dc6-daf7-7601-b4e2-4160f6e338fa
```
:::

`create` doesn't fail when the name already exists: it replaces that config map's document, like
[`update`](/clis/ampctl/configmap#ampctl-configmap-update), and says so. An identical document keeps its id:

```
✓ ConfigMap updated (the name was already bound)
  Name: acme/mainnet_rpc
  Kind: evm-rpc
  Id: 01a18dc6-daf7-7601-b4e2-4160f6e338fa
```

With `--json`, `outcome` is `created` or `updated`:

```json
{
  "id": "01a18dc6-daf7-7601-b4e2-4160f6e338fa",
  "namespace": "acme",
  "name": "mainnet_rpc",
  "kind": "evm-rpc",
  "outcome": "updated"
}
```

A JSON file usually has no `kind` key, so pass `--kind`:

```json [tuning.json]
{
  "batch_size": 500,
  "flush_interval_secs": 10
}
```

```bash
ampctl configmap create export_tuning --namespace acme --kind export-settings --from-file ./tuning.json
```

Without it, `create` fails:

```
✗ failed to load config map document
  → --kind is required because the file has no top-level string `kind` key
```

A name with other characters fails before anything is sent.

## `ampctl configmap inspect`

Prints a config map: its id, namespace, name, kind, and document.

```
ampctl configmap inspect [OPTIONS] NAMESPACE/NAME
```

| Argument         | Type   | Default  | Description                                                   |
| ---------------- | ------ | -------- | ------------------------------------------------------------- |
| `NAMESPACE/NAME` | string | required | The config map, like `acme/mainnet_rpc`. See [Names](/clis/ampctl/configmap#names). |

Its alias is `ampctl configmap get`.

:::terminal
```bash
ampctl configmap inspect acme/mainnet_rpc
```

```
Id:        01a18dc7-117e-7033-8114-d1adf1962d99
Namespace: acme
Name:      mainnet_rpc
Kind:      evm-rpc
Data:
{
  "url": "https://ethereum-rpc.example.com",
  "kind": "evm-rpc",
  "network": "mainnet",
  "auth_token": "${{ env.MAINNET_RPC_TOKEN }}"
}
```
:::

The document is printed as it's stored. `${{ env.NAME }}` references stay as written, and nothing is hidden: a password
stored as a literal value is printed. Keep secrets in references, as [Secrets](/managing-amp/config-maps/secrets)
explains.

With `--json`, the document is an object under `data`, so `jq .data` extracts it, to save it or create the config map
somewhere else:

:::terminal
```bash
ampctl configmap inspect acme/mainnet_rpc --json
```

```json
{
  "id": "01a18dc7-117e-7033-8114-d1adf1962d99",
  "namespace": "acme",
  "name": "mainnet_rpc",
  "kind": "evm-rpc",
  "data": {
    "url": "https://ethereum-rpc.example.com",
    "kind": "evm-rpc",
    "network": "mainnet",
    "auth_token": "${{ env.MAINNET_RPC_TOKEN }}"
  }
}
```
:::

```bash
ampctl configmap inspect acme/mainnet_rpc --json | jq .data > mainnet.json
```

A name that doesn't exist fails, with exit code 1.

## `ampctl configmap list`

Lists the config maps of a namespace, sorted by name, with their kinds and ids.

```
ampctl configmap list [OPTIONS] --namespace NAMESPACE
```

| Flag                      | Type   | Default  | Description                                                                   |
| ------------------------- | ------ | -------- | ----------------------------------------------------------------------------- |
| `--namespace <NAMESPACE>` | string | required | The [namespace](/clis/ampctl/configmap#names) to list, like `--namespace acme`. There's no default. |

Its alias is `ampctl configmap ls`.

:::terminal
```bash
ampctl configmap list --namespace acme
```

```
ConfigMaps in namespace 'acme':
  export_tuning  export-settings  01a18dc7-11a7-7ca2-9b8f-aeb60717c782
  mainnet_rpc    evm-rpc          01a18dc7-117e-7033-8114-d1adf1962d99
```
:::

A listing never includes the documents, which can hold credentials. Read one with
[`ampctl configmap inspect`](/clis/ampctl/configmap#ampctl-configmap-inspect). With `--json`, each config map also has its namespace, and when
when it was created and last changed. `created_by` and `updated_by` are always `null` at v0.0.42, since Amp doesn't
record who made a change yet:

:::terminal
```bash
ampctl configmap list --namespace acme --json
```

```json
{
  "configmaps": [
    {
      "id": "01a18dc7-11a7-7ca2-9b8f-aeb60717c782",
      "namespace": "acme",
      "name": "export_tuning",
      "kind": "export-settings",
      "created_at": "2026-10-30T17:05:03.506681+00:00",
      "created_by": null,
      "updated_at": "2026-10-30T17:05:03.506681+00:00",
      "updated_by": null
    },
    {
      "id": "01a18dc7-117e-7033-8114-d1adf1962d99",
      "namespace": "acme",
      "name": "mainnet_rpc",
      "kind": "evm-rpc",
      "created_at": "2026-10-30T17:05:03.466012+00:00",
      "created_by": null,
      "updated_at": "2026-10-30T17:05:03.466012+00:00",
      "updated_by": null
    }
  ]
}
```
:::

```bash
ampctl configmap list --namespace acme --json | jq -r '.configmaps[].name'
```

A namespace with no config maps isn't an error. `list` prints `No ConfigMaps found in namespace 'staging'`, or
`{"configmaps":[]}` with `--json`, and exits with code 0.

## `ampctl configmap update`

Replaces the document of a config map that exists, from a JSON or TOML file.

```
ampctl configmap update [OPTIONS] --from-file FILE NAMESPACE/NAME
```

| Argument / flag      | Type        | Default               | Description                                                                                                                        |
| -------------------- | ----------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `NAMESPACE/NAME`     | string      | required              | The config map, like `acme/mainnet_rpc`. It must exist.                                                                            |
| `--from-file <FILE>` | path or URL | required              | The new document, read like [`create`'s](/clis/ampctl/configmap#--from-file-file).                                                                       |
| `--kind <KIND>`      | string      | the file's `kind` key | The [kind](/clis/ampctl/configmap#names), like `--kind evm-rpc`. It can differ from the current one. Required when the file has no top-level `kind` key. |

The new document replaces the old one whole: nothing is merged, so the file must hold every field.

:::terminal
```bash
ampctl configmap update acme/mainnet_rpc --from-file ./mainnet.toml
```

```
✓ ConfigMap updated
  Name: acme/mainnet_rpc
  Kind: evm-rpc
  Id: 01a18dc6-f2d5-77c3-b0b7-4d9a3303700b
```
:::

A document and kind identical to the current ones change nothing, and keep the id:

```
✓ ConfigMap unchanged (the document was equivalent)
  Name: acme/mainnet_rpc
  Kind: evm-rpc
  Id: 01a18dc6-f2d5-77c3-b0b7-4d9a3303700b
```

With `--json`, `outcome` is `replaced` or `unchanged`, and `previous_id` is the id the config map had before:

:::terminal
```bash
ampctl configmap update acme/mainnet_rpc --from-file ./mainnet.toml --json
```

```json
{
  "id": "01a18dc7-117e-7033-8114-d1adf1962d99",
  "previous_id": "01a18dc6-f2d5-77c3-b0b7-4d9a3303700b",
  "namespace": "acme",
  "name": "mainnet_rpc",
  "kind": "evm-rpc",
  "outcome": "replaced"
}
```
:::

`update` never creates a config map. For a name that doesn't exist, it fails with exit code 1; use
[`create`](/clis/ampctl/configmap#ampctl-configmap-create) instead.

`update` reads the config map's id, then writes only if it still has that id. If something else changes or deletes
the config map in between, nothing is written and `update` fails with
`config map 'acme/mainnet_rpc' changed or was deleted during the update; inspect it and retry`. Inspect it, then run
the update again.

## `ampctl configmap delete`

Deletes a config map.

```
ampctl configmap delete [OPTIONS] NAMESPACE/NAME
```

| Argument / flag  | Type   | Default  | Description                                      |
| ---------------- | ------ | -------- | ------------------------------------------------ |
| `NAMESPACE/NAME` | string | required | The config map, like `acme/export_tuning`.       |
| `-f`, `--force`  | flag   | off      | Deletes without asking first. Use it in scripts. |

Its alias is `ampctl configmap rm`.

Amp keeps no copy. To keep the document, save it first with [`inspect --json`](/clis/ampctl/configmap#ampctl-configmap-inspect). The
confirmation warns about jobs that load the config map, but no job loads config maps in this release.

Without `--force`, `delete` asks first. Any answer but `y` or `yes` deletes nothing, and exits with code 0. So does a
script without `--force`, since there's no answer to read.

```bash
ampctl configmap delete acme/export_tuning
```

Deleting a config map that doesn't exist succeeds too, so you can run it again safely. With `--json`, it prints the
namespace and name:

:::terminal
```bash
ampctl configmap delete acme/export_tuning --force --json
```

```json
{ "namespace": "acme", "name": "export_tuning" }
```
:::
