# Configure gas sponsorship

This guide explains how to configure the Gas Station Service to automatically fund transaction fees for your accounts.

## Overview

The Gas Station Service eliminates the need for end-user accounts to hold native tokens (ETH) for gas fees on Ethereum and EVM-compatible chains. You configure **sponsorship relationships** that define which accounts receive automatic fee funding and which **sponsor accounts** provide those funds.

All API endpoints use the base URL `https://{gateway}/v1`, where `{gateway}` is your Ripple Custody API gateway hostname (for example, `custody.example.com`).

Terminology
| Term | Description |
|  --- | --- |
| **Gas station** | An account configured to sponsor transaction fees for other accounts |
| **Sponsor account** | Same as gas station—the account that provides funds for fees |
| **Sponsored account** | An account that receives automatic fee funding from a gas station |
| **`accountId`** | In core sponsor endpoints (`/sponsor`), refers to the gas station account |
| **`entityId`** | In sponsorship management endpoints (`/sponsored-accounts`, `/sponsored-domains`), refers to the gas station account |


## Quick start

Get your first sponsored transaction working in under 5 minutes:

**1. Verify prerequisites**

Complete these setup steps first:

- [Deploy Gas Station Service](/products/custody/v1.34/deployment/reference/gas-station) (on-premise) or contact your administrator (SaaS)
- [Configure a bot user](/products/custody/v1.34/api/environment/user/bot-user) with auto-approval policies
- Fund a sponsor account with native tokens (ETH or other EVM chain native tokens)


**2. Create a gas station (sponsor account)**


```bash
curl -X POST "https://{gateway}/v1/domain/{domainId}/account/{accountId}/sponsor" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "account",
    "accountIds": ["account-to-sponsor-uuid"],
    "includeSubDomains": false,
    "alertLimit": []
  }'
```

**3. Test it**

Create a transaction from the sponsored account (even with zero native token balance). The Gas Station automatically:

1. Detects the pending transaction
2. Transfers the required fee from the sponsor account
3. Allows the transaction to proceed


If the transaction completes successfully, gas sponsorship is working. If it remains in "Preparing" status, see [Troubleshooting](#troubleshooting) below.

## Prerequisites

Before configuring gas sponsorship, ensure you have completed the following setup steps:

1. **Gas Station Service deployed** — For on-premise deployments, see [Gas Station reference](/products/custody/v1.34/deployment/reference/gas-station). SaaS deployments are managed by Ripple.
2. **Bot user configured** — See [Configure bot users](/products/custody/v1.34/api/environment/user/bot-user) for setup instructions.
3. **Sponsor account funded** — The account designated as the gas station must have sufficient native tokens (ETH or other EVM chain native tokens)
4. **API access** — A valid JSON web token. See [Obtain a JSON web token](/products/custody/v1.34/api/get-started/jwt).


## Configure a gas station account

A gas station account (sponsor) can fund specific accounts or entire domains. Use the same endpoint with different `type` values.

### Create account-level sponsorship

Designate specific accounts to receive gas funding:


```bash
curl -X POST "https://{gateway}/v1/domain/{domainId}/account/{accountId}/sponsor" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "account",
    "accountIds": ["account-uuid-1", "account-uuid-2"],
    "includeSubDomains": false,
    "alertLimit": [
      {
        "tickerId": "eth-ticker-uuid",
        "amount": "1.0"
      }
    ]
  }'
```

| Parameter | Type | Required | Description |
|  --- | --- | --- | --- |
| `domainId` | string | Yes | The domain containing the gas station account |
| `accountId` | string | Yes | The gas station account that funds gas fees |
| `type` | string | Yes | Sponsorship type: `account` or `domain` |
| `accountIds` | array | No | Account UUIDs to sponsor (for `type: "account"`) |
| `includeSubDomains` | boolean | Yes | Extend sponsorship to child domains (for `type: "domain"`) |
| `alertLimit` | array | Yes | Low-balance alert thresholds |


### Response (201 Created)


```json
{
  "id": "sponsor-config-uuid",
  "status": "created",
  "createdAt": "2024-01-15T10:30:00Z"
}
```

### Create domain-level sponsorship

Fund all accounts within a domain (and optionally its subdomains):


```bash
curl -X POST "https://{gateway}/v1/domain/{domainId}/account/{accountId}/sponsor" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "domain",
    "includeSubDomains": true,
    "alertLimit": [
      {
        "tickerId": "eth-ticker-uuid",
        "amount": "5.0"
      }
    ]
  }'
```

If an account has both account-level and domain-level sponsorship configured, the account-level sponsor takes precedence.

## Update sponsorship configuration

Modify an existing sponsorship using the PUT endpoint:


```bash
curl -X PUT "https://{gateway}/v1/domain/{domainId}/account/{accountId}/sponsor" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "account",
    "accountIds": ["account-uuid-1", "account-uuid-2"],
    "includeSubDomains": false,
    "alertLimit": [
      {
        "tickerId": "eth-ticker-uuid",
        "amount": "2.0"
      }
    ]
  }'
```

### Response (200 OK)

Returns the full sponsor configuration:


```json
{
  "type": "account",
  "accountIds": ["account-uuid-1", "account-uuid-2"],
  "includeSubDomains": false,
  "alertLimit": [
    {
      "tickerId": "eth-ticker-uuid",
      "amount": "2.0"
    }
  ],
  "balanceStatus": [
    {
      "tickerId": "eth-ticker-uuid",
      "tickerSymbol": "ETH",
      "threshold": "2.0",
      "currentBalance": "5.5",
      "status": "healthy"
    }
  ],
  "criticalCount": 0
}
```

## Remove sponsorship

Delete sponsorship configuration when it's no longer needed:


```bash
curl -X DELETE "https://{gateway}/v1/domain/{domainId}/account/{accountId}/sponsor" \
  -H "Authorization: Bearer {token}"
```

After removing sponsorship, the account must have sufficient native tokens to pay its own transaction fees.

## Set up low-balance alerts

Configure alerts to receive notifications before sponsor accounts run out of funds. Use the `alertLimit` array when creating or updating sponsorship:


```json
{
  "alertLimit": [
    {
      "tickerId": "eth-ticker-uuid",
      "amount": "1.0"
    },
    {
      "tickerId": "matic-ticker-uuid",
      "amount": "50.0"
    }
  ]
}
```

When a sponsor account's balance drops below the specified threshold, the Gas Station sends an alert through the Ripple Custody notification system.

## View sponsorship audit events

Retrieve a log of all sponsorship-related actions for compliance and debugging:


```bash
curl -X GET "https://{gateway}/v1/domain/{domainId}/sponsor/events?limit=100" \
  -H "Authorization: Bearer {token}"
```

### Query parameters

| Parameter | Type | Required | Description |
|  --- | --- | --- | --- |
| `accountId` | string | No | Filter events for a specific account |
| `startDate` | ISO 8601 | No | Filter events from this date (inclusive) |
| `endDate` | ISO 8601 | No | Filter events until this date (inclusive) |
| `eventType` | string | No | Filter by event type (`CREATE`, `UPDATE`, `DELETE`) |
| `limit` | integer | No | Maximum events to return (default: 100, max: 1000) |
| `startingAfter` | string | No | Cursor for pagination—ID of the last event from previous page |


### Response


```json
{
  "items": [
    {
      "id": "event-uuid",
      "eventType": "CREATE",
      "accountId": "sponsor-account-uuid",
      "domainId": "domain-uuid",
      "payload": {
        "type": "domain",
        "accountIds": [],
        "includeSubDomains": true,
        "alertLimit": [
          {
            "tickerId": "eth-ticker-uuid",
            "amount": "1.0"
          }
        ]
      },
      "timestamp": "2024-01-15T10:30:00Z"
    }
  ],
  "count": 1,
  "currentStartingAfter": "event-uuid",
  "nextStartingAfter": null
}
```

| Event type | Description |
|  --- | --- |
| `CREATE` | New sponsorship configured |
| `UPDATE` | Sponsorship settings modified |
| `DELETE` | Sponsorship removed |


## Manage sponsored accounts and domains

After creating a gas station, you can manage which accounts and domains it sponsors using dedicated endpoints.

### List sponsorable accounts

View accounts that can be added to a gas station's sponsorship:


```bash
curl -X GET "https://{gateway}/v1/domain/{domainId}/account/{entityId}/sponsorable-accounts?page=0&pageSize=50" \
  -H "Authorization: Bearer {token}"
```

#### Response


```json
{
  "items": [
    {
      "accountId": "account-uuid",
      "name": "Trading Account",
      "lineage": {
        "domainId": "parent-domain-uuid",
        "domain": "Parent Domain",
        "subdomainId": "subdomain-uuid",
        "subdomain": "Sub Domain"
      },
      "ledgers": [
        {"id": "ledger-uuid", "alias": "Ethereum"}
      ],
      "sponsorshipStatus": "not_sponsored"
    }
  ],
  "total": 100,
  "page": 0,
  "pageSize": 50,
  "availableLedgers": [
    {"id": "ledger-uuid", "alias": "Ethereum"}
  ]
}
```

The `sponsorshipStatus` field indicates:

- `not_sponsored` — Available to sponsor
- `sponsored` — Already sponsored by this gas station
- `sponsored_by_other` — Sponsored by a different gas station


### Add accounts to sponsorship


```bash
curl -X POST "https://{gateway}/v1/domain/{domainId}/account/{entityId}/sponsored-accounts" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "accounts": [
      {"accountId": "account-uuid-1", "domainId": "domain-uuid-1"},
      {"accountId": "account-uuid-2", "domainId": "domain-uuid-2"}
    ]
  }'
```

### Remove accounts from sponsorship


```bash
curl -X DELETE "https://{gateway}/v1/domain/{domainId}/account/{entityId}/sponsored-accounts" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "accounts": [
      {"accountId": "account-uuid-1", "domainId": "domain-uuid-1"}
    ]
  }'
```

### List sponsorable domains

View domains that can be added to a gas station's sponsorship:


```bash
curl -X GET "https://{gateway}/v1/domain/{domainId}/account/{entityId}/sponsorable-domains?page=0&limit=20" \
  -H "Authorization: Bearer {token}"
```

**Query parameters**:

- `status` (optional): Filter by `sponsored`, `not_sponsored`, or `sponsored_by_other`
- `search` (optional): Search by domain name
- `limit` (optional): Number of results per page (default: 20)
- `page` (optional): Page number, 0-indexed (default: 0)


**Response** (200 OK):


```json
{
  "items": [
    {
      "domainId": "domain-uuid-1",
      "name": "Trading Desk A",
      "ledgers": [
        {"ledgerId": "ethereum", "name": "Ethereum"}
      ],
      "sponsorshipStatus": "not_sponsored",
      "accountIds": ["account-uuid-1", "account-uuid-2"],
      "children": []
    },
    {
      "domainId": "domain-uuid-2",
      "name": "Retail Division",
      "ledgers": [
        {"ledgerId": "polygon", "name": "Polygon"}
      ],
      "sponsorshipStatus": "sponsored_by_other",
      "sponsorshipDetails": {
        "sponsorAccountId": "other-gas-station-uuid",
        "sponsorAccountName": "Main Gas Station"
      },
      "accountIds": [],
      "children": [
        {
          "domainId": "subdomain-uuid-1",
          "name": "Retail - US",
          "ledgers": [],
          "sponsorshipStatus": "not_sponsored",
          "accountIds": ["account-uuid-3"],
          "children": []
        }
      ]
    }
  ],
  "total": 2,
  "page": 0,
  "pageSize": 20,
  "availableLedgers": [
    {"ledgerId": "ethereum", "name": "Ethereum"},
    {"ledgerId": "polygon", "name": "Polygon"},
    {"ledgerId": "avalanche", "name": "Avalanche"}
  ]
}
```

### Add domains to sponsorship


```bash
curl -X POST "https://{gateway}/v1/domain/{domainId}/account/{entityId}/sponsored-domains" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "domains": [
      {"domainId": "domain-uuid-1"},
      {"domainId": "domain-uuid-2"}
    ]
  }'
```

**Response** (201 Created):


```json
{
  "success": true,
  "count": 2
}
```

### Remove domains from sponsorship


```bash
curl -X DELETE "https://{gateway}/v1/domain/{domainId}/account/{entityId}/sponsored-domains" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "domains": [
      {"domainId": "domain-uuid-1"}
    ]
  }'
```

## List gas stations and sponsored entities

### List all gas stations in a domain


```bash
curl -X GET "https://{gateway}/v1/domain/{domainId}/sponsors" \
  -H "Authorization: Bearer {token}"
```

#### Response


```json
{
  "items": ["gas-station-account-uuid-1", "gas-station-account-uuid-2"]
}
```

### List accounts with sponsorship status

View all accounts in a domain and whether they're currently sponsored:


```bash
curl -X GET "https://{gateway}/v1/domain/{domainId}/sponsors/sponsored-accounts?limit=50&sortBy=alias&sortOrder=asc" \
  -H "Authorization: Bearer {token}"
```

**Query parameters**:

- `limit` (optional): Maximum items per page, 1-100 (default: 20)
- `startingAfter` (optional): Cursor for pagination—returns items after this ID
- `sortBy` (optional): Field to sort by (default: `alias`)
- `sortOrder` (optional): Sort direction, `asc` or `desc` (default: `asc`)


**Response** (200 OK):


```json
{
  "items": [
    {
      "id": "account-uuid-1",
      "alias": "user-wallet-1",
      "isSponsored": true,
      "path": ["root-domain", "sub-domain"]
    },
    {
      "id": "account-uuid-2",
      "alias": "user-wallet-2",
      "isSponsored": false,
      "path": ["root-domain", "sub-domain"]
    }
  ],
  "count": 2,
  "currentStartingAfter": "account-uuid-0",
  "nextStartingAfter": "account-uuid-2"
}
```

### List sub-domains with sponsorship status

View all sub-domains in a domain and whether they're currently sponsored:


```bash
curl -X GET "https://{gateway}/v1/domain/{domainId}/sponsors/sponsored-domains?limit=50&sortBy=alias&sortOrder=asc" \
  -H "Authorization: Bearer {token}"
```

**Query parameters**:

- `limit` (optional): Maximum items per page, 1-100 (default: 20)
- `startingAfter` (optional): Cursor for pagination—returns items after this ID
- `sortBy` (optional): Field to sort by (default: `alias`)
- `sortOrder` (optional): Sort direction, `asc` or `desc` (default: `asc`)


**Response** (200 OK):


```json
{
  "items": [
    {
      "id": "subdomain-uuid-1",
      "alias": "trading-division",
      "isSponsored": true,
      "path": ["root-domain"]
    },
    {
      "id": "subdomain-uuid-2",
      "alias": "retail-division",
      "isSponsored": false,
      "path": ["root-domain"]
    }
  ],
  "count": 2,
  "currentStartingAfter": "subdomain-uuid-0",
  "nextStartingAfter": "subdomain-uuid-2"
}
```

## Troubleshooting

### Transaction stuck in "Preparing" status

The Gas Station hasn't funded the transaction. Check these common causes:

| Symptom | Cause | Solution |
|  --- | --- | --- |
| Transaction waits indefinitely | No sponsorship configured | Verify sponsorship exists for the account or its domain |
| Transaction waits indefinitely | Sponsor account has insufficient balance | Add native tokens to the sponsor account |
| Transaction waits indefinitely | Bot user blocked by policies | Review bot user policies; ensure auto-approval is enabled |
| Transaction waits indefinitely | Gas Station Service not running | Contact your administrator to verify service health |


## Related documentation

| Topic | Description |
|  --- | --- |
| [Gas Station concepts](/products/custody/v1.34/concepts/gas-station) | Understand sponsorship hierarchy and multi-chain support |
| [Gas Station reference](/products/custody/v1.34/deployment/reference/gas-station) | Configuration parameters and deployment options |
| [Configure bot users](/products/custody/v1.34/api/environment/user/bot-user) | Set up bot users for automated operations |