> **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.

# Providers

A provider tells Amp where to get a chain's data: an RPC endpoint's URL, its credentials, and how hard to use it. A
[raw dataset](/datasets/raw-datasets) only says what to extract, like Ethereum mainnet's blocks, and Amp extracts it
through a provider of the same kind and network. So you can change endpoints, add more, or keep keys secret without
changing any dataset, and many datasets can share a provider.

Providers are for running Amp yourself. On a hosted Amp, its operators manage them.

## Kinds

Each provider has a kind, which says what it connects to:

| Kind                                                                             | Connects to                                                                          |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| [`evm-rpc`](/providers/evm-rpc)                                                  | An Ethereum or EVM-compatible JSON-RPC endpoint                                      |
| [`solana`](/providers/solana)                                                    | A Solana RPC endpoint, and the Old Faithful archive for history                      |
| [`tempo`](/providers/tempo)                                                      | A Tempo JSON-RPC endpoint                                                            |
| [`bittensor`](/providers/bittensor)                                              | A Bittensor (Subtensor) JSON-RPC endpoint                                            |
| [`bitcoin-rpc`](/providers/bitcoin-rpc)                                          | A Bitcoin Core JSON-RPC endpoint                                                     |
| [`eth-beacon`](/providers/eth-beacon)                                            | An Ethereum Beacon API endpoint                                                      |
| [`stellar`](/providers/stellar)                                                  | A Stellar RPC endpoint                                                               |
| [`phaser`](/providers/phaser)                                                    | A Phaser bridge, over Arrow Flight                                                   |
| [`static`](/providers/static)                                                    | A directory or bucket of CSV files, for [static datasets](/datasets/static-datasets) |
| [ADBC](/managing-amp/pipelines/destinations) (`adbc-postgres`, `adbc-snowflake`) | A database that Amp [exports](/managing-amp/pipelines) datasets to                   |

## Prerequisites

* A running Amp you can manage, like one in [solo mode](/running-amp/solo-mode).
* [`ampctl`](/clis/ampctl), which installs with Amp.
* An endpoint for the chain you want, like an RPC URL from a node provider or your own node.

## Configure a provider

A provider's configuration is a TOML file. `kind` says what it connects to, `network` which network it serves, and
the other fields depend on the kind:

```toml [mainnet.toml]
kind = "evm-rpc"
network = "mainnet"
url = "${RPC_URL}"
rate_limit_per_minute = 600
```

`network` must match the `network` of the datasets that use the provider, like `mainnet`, `base`, or
`solana-mainnet`: lowercase letters, digits, and hyphens. Static providers have no network.

Each kind's page explains its fields, and the [Provider Configuration Reference](/providers/configuration-reference)
lists every field of every kind, with its type and default.

## Environment variables

Keep URLs with keys and other secrets out of the configuration: write `${VAR_NAME}` instead, and Amp replaces it with
the environment variable's value.

```toml
url = "https://eth-mainnet.example.com/v2/${RPC_KEY}"
auth_token = "${RPC_TOKEN}"
```

Variables work anywhere in a string value, and only there: numbers and booleans can't use them. `ampd` replaces the
variables, not `ampctl`, and only when a job starts using the provider. So:

* Set the variables in the environment `ampd` runs in: of the worker that runs the extraction job, in
  [distributed mode](/running-amp/distributed-mode). Setting them in your terminal, where you run `ampctl`, isn't
  enough.
* The stored configuration keeps the reference, not the value: `ampctl provider inspect` shows `${RPC_KEY}`.
* After changing a variable, restart `ampd`, then restart the jobs that use the provider.

When a variable isn't set, `ampd` logs `environment variable substitution failed for provider, skipping`, and ignores
the provider. A job with no other provider for its kind and network then fails with
`No provider found for kind 'evm-rpc' and network 'mainnet'`.

## Register a provider

Register the file under a name:

```bash
ampctl provider register mainnet_rpc ./mainnet.toml
```

* The name is how you manage the provider: lowercase letters, digits, and underscores, starting with a letter or an
  underscore, like `mainnet_rpc`. Datasets don't refer to it.
* The file can also be in object storage: `s3://`, `gs://`, or `az://` URLs work, with the storage's credentials in
  your environment.
* Registering a name again replaces its configuration. Jobs use the new one the next time they start.

The Admin API's `POST /providers` does the same, with the configuration as JSON and the name in it:

```bash
curl -X POST http://localhost:1610/providers \
  -H 'content-type: application/json' \
  -d '{"name": "mainnet_rpc", "kind": "evm-rpc", "network": "mainnet", "url": "${RPC_URL}", "rate_limit_per_minute": 600}'
```

### Provider files

Amp stores each provider you register as a TOML file in its providers directory, named after the provider:
`providers_dir` in its [configuration](/running-amp/configuration), or `.amp/providers/` in solo mode. It also reads
the files you put there yourself: a file's name, without `.toml`, is the provider's name. Amp re-reads the directory
each time a raw dataset's job starts, so a changed chain provider applies at the next job start. `ampctl provider list`
and static providers use the copy Amp last read: restart `ampd` to be sure they see your change.

## How datasets find their provider

When a job starts extracting a raw dataset, Amp gathers every provider whose `kind` and `network` match the dataset's.
With several, the job spreads its requests over all of them: more to those that answer faster, fewer to those that
fail. That's how you add capacity, or a backup endpoint: register another provider for the same network. Their names
don't set a priority.

To use a single provider, name it when you deploy:

```bash
ampctl dataset deploy acme/eth_mainnet@1.0.0 --provider mainnet_rpc
```

Amp picks providers when a job starts. A provider you register or change while a job runs is used when the job next
starts.

## List, inspect, and remove providers

:::terminal
```bash
ampctl provider list
```

```
Providers:
  labels (static)
  mainnet_rpc (evm-rpc)
```
:::

:::terminal
```bash
ampctl provider inspect mainnet_rpc
```

```
{
  "name": "mainnet_rpc",
  "kind": "evm-rpc",
  "network": "mainnet",
  "url": "${RPC_URL}",
  "rate_limit_per_minute": 600
}
```
:::

```bash
ampctl provider remove mainnet_rpc
```

[Managing Providers](/managing-amp/providers) covers these commands and their Admin API endpoints in detail, and
[`ampctl provider`](/clis/ampctl/provider) lists their flags.

## Errors

### `invalid character 'B' in provider name 'Base-RPC'`

Provider names take lowercase letters, digits, and underscores only. Use `base_rpc`.

### `No provider found for kind 'evm-rpc' and network 'mainnet'`

A job found no usable provider for its dataset. Check that one is registered with exactly the dataset's kind and
network (`ampctl provider list`), and that the environment variables its configuration uses are set where `ampd` runs
(see [Environment variables](/providers#environment-variables)).
