# Create a Gas Station Policy

For one chain and asset: when a covered wallet is topped up, up to what, how much at most, and never above which gas price.

## Overview

- `chain`: an EVM chain's slug — `ethereum`, `polygon`, `gnosis`, `bsc`, `arbitrum`, `optimism`, `base`, `avalanche`, `celo` or `flowevm`, in any case —, with `isTestnet` for its testnet. Any other: `400` `GAS_STATION_CHAIN_NOT_SUPPORTED`.
- `asset`: `native`, or a token's contract address — all lower or all upper case, or EIP-55 with a valid checksum; never the zero address. A token's `decimals` are read on chain now: `422` `GAS_STATION_ASSET_NOT_A_TOKEN` for an address with no contract or no `decimals()`, `503` `GAS_STATION_CHAIN_UNAVAILABLE` when the chain cannot be read.
- **The limits**, whole numbers of the asset's smallest unit as text, up to 2256 − 1: `target` above `threshold`, `capPerTopUp` above 0, `capPerWalletDay` (any 24 hours) at least `capPerTopUp`, `maxGasPriceWei` above 0 — else `400` `GAS_STATION_INVALID` with `details.field`.
- `coverage`: `custodial` (default), `account` with `accountId` — an account of your tenant, else `404` `GAS_STATION_ACCOUNT_NOT_FOUND` —, or `tag` with `tag`; `accountId` and `tag` only with their coverage. `includeNonCustodial` `true` adds client-side and MPC wallets. Which wallets each covers: [Gas Station](https://docs.aureahub.com/docs/guide-gas-station.md) › Which Wallets a Policy Covers.
- `enabled`: default `true`. A policy of yours, even switched off, stands in place of Aurea's default for its chain, network and asset.
- **One per chain, network and asset**: a second answers `409` `GAS_STATION_POLICY_EXISTS` — change the one you have with [Change a Policy](https://docs.aureahub.com/docs/gas-station-policy-update.md).
- `201` with the policy. Its top-ups are paid by your funding wallet on that chain ([Create a Funding Wallet](https://docs.aureahub.com/docs/gas-station-funding-wallet-create.md)), and only while your tenant is in `station`. A field the body does not have, or a value of the wrong form, answers `400` `GAS_STATION_INVALID` with each problem in `details.errors`.
- For `owner`, `tenantadmin` and `non_signing_admin`, on their own tenant. Written to your audit trail [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md), as `gas_station.policy.created`.

## Endpoint

### `POST /v1/gas-station/policies`

Authentication: bearer token required.

Adds a Gas Station policy for one chain, network and asset.

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `chain` | string | yes | An EVM chain's slug, e.g. `base` |
| `isTestnet` | boolean | no | Its testnet; default `false` |
| `asset` | string | yes | `native`, or a token's contract address |
| `threshold` | string | yes | Below this balance a covered wallet is topped up — smallest unit, as text |
| `target` | string | yes | The balance it is topped up to; above `threshold` |
| `capPerTopUp` | string | yes | At most this much per top-up; above 0 |
| `capPerWalletDay` | string | yes | At most this much per wallet in any 24 hours; at least `capPerTopUp` |
| `maxGasPriceWei` | string | yes | No top-up while the network's gas price is above it, in wei; above 0 |
| `coverage` | string | no | `custodial` (default), `account` or `tag` |
| `accountId` | string (uuid) \| null | no | The account, with `coverage` `account` only |
| `tag` | string \| null | no | The accounts' tag, with `coverage` `tag` only |
| `includeNonCustodial` | boolean | no | Client-side and MPC wallets too; default `false` |
| `enabled` | boolean | no | Default `true` |

**Responses**

`201` Created

```json
{
  "id": "8c3e1f5a-2b7d-4e90-a1c6-3d5f7b9e2a14",
  "scope": "tenant",
  "chain": "base",
  "isTestnet": false,
  "chainId": 8453,
  "asset": "native",
  "decimals": 18,
  "threshold": "200000000000000",
  "target": "1000000000000000",
  "capPerTopUp": "1000000000000000",
  "capPerWalletDay": "2000000000000000",
  "maxGasPriceWei": "5000000000",
  "coverage": "custodial",
  "accountId": null,
  "tag": null,
  "includeNonCustodial": false,
  "enabled": true,
  "createdAt": "2026-10-14T09:20:11.402Z",
  "updatedAt": "2026-10-14T09:20:11.402Z"
}
```

`400` A rule

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "capPerWalletDay must be at least capPerTopUp",
  "details": { "code": "GAS_STATION_INVALID", "field": "capPerWalletDay" }
}
```

`400` Form

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "Invalid request",
  "details": {
    "code": "GAS_STATION_INVALID",
    "errors": ["threshold: must be a whole number of the smallest unit, as text"]
  }
}
```

`409` Exists

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "A Gas Station policy for this chain and asset exists already: change it",
  "details": { "code": "GAS_STATION_POLICY_EXISTS" }
}
```

`422` Not a token

```json
{
  "statusCode": 422,
  "error": "ValidationError",
  "message": "This address holds no token contract on this chain (no code, or no decimals())",
  "details": { "code": "GAS_STATION_ASSET_NOT_A_TOKEN" }
}
```

**Example request**

```bash
curl -X POST https://api.aureahub.com/v1/gas-station/policies \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "chain": "base",
    "asset": "native",
    "threshold": "200000000000000",
    "target": "1000000000000000",
    "capPerTopUp": "1000000000000000",
    "capPerWalletDay": "2000000000000000",
    "maxGasPriceWei": "5000000000"
  }'
```

## By Tenant Id

The same, with your tenant's id, for the same roles; another tenant's id answers `403`.

### `POST /v1/admin/tenants/{id}/gas-station/policies`

Authentication: bearer token required.

Adds a Gas Station policy of the tenant.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes | Your tenant's id |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `chain` | string | yes | An EVM chain's slug, e.g. `base` |
| `isTestnet` | boolean | no | Its testnet; default `false` |
| `asset` | string | yes | `native`, or a token's contract address |
| `threshold` | string | yes | Below this balance a covered wallet is topped up — smallest unit, as text |
| `target` | string | yes | The balance it is topped up to; above `threshold` |
| `capPerTopUp` | string | yes | At most this much per top-up; above 0 |
| `capPerWalletDay` | string | yes | At most this much per wallet in any 24 hours; at least `capPerTopUp` |
| `maxGasPriceWei` | string | yes | No top-up while the network's gas price is above it, in wei; above 0 |
| `coverage` | string | no | `custodial` (default), `account` or `tag` |
| `accountId` | string (uuid) \| null | no | The account, with `coverage` `account` only |
| `tag` | string \| null | no | The accounts' tag, with `coverage` `tag` only |
| `includeNonCustodial` | boolean | no | Client-side and MPC wallets too; default `false` |
| `enabled` | boolean | no | Default `true` |

**Responses**

`403` Another tenant

```json
{ "statusCode": 403, "error": "ForbiddenError", "message": "Admin access required or you can only access your own tenant." }
```

---

Web version: https://docs.aureahub.com/#gas-station-policy-create
