Proxy API
https://api.datafuel.ai
Help centerOpenAPI spec

Residential proxies

Plans of residential traffic: buying and topping them up, generating their proxies and reading their usage.

GET/api/v1/residential/productsscope: api.residential.read

List products

The products on sale, each with your price per GB at each volume. The final price, with discounts, tax and fees, comes from POST /quote.

Requires the api.residential.read scope.

Query
limit
integer
How many results to return, 1–100. Default: 50.
offset
integer
How many results to skip. Default: 0.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/products \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "results": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string",
      "description": "string",
      "max_traffic_gb": 0,
      "tiers": [
        {
          "min_gb": 0,
          "price_per_gb": 0
        }
      ]
    }
  ],
  "count": 0,
  "limit": 0,
  "offset": 0
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
GET/api/v1/residential/products/{product}scope: api.residential.read

Get a product

The product with its prices and every country its proxies can exit in.

Requires the api.residential.read scope.

Path
productREQUIRED
string
The product's id.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/products/{product} \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "name": "string",
  "description": "string",
  "max_traffic_gb": 0,
  "tiers": [
    {
      "min_gb": 0,
      "price_per_gb": 0
    }
  ],
  "countries": [
    {
      "country": "US",
      "continent": "NA"
    }
  ]
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
GET/api/v1/residential/plansscope: api.residential.read

List your plans

The plans you hold, newest first, with the traffic left on each.

Requires the api.residential.read scope.

Query
limit
integer
How many results to return, 1–100. Default: 50.
offset
integer
How many results to skip. Default: 0.
status
string
Only plans in this state.
provisioningactivepast_duesuspendedexpired
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "results": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string",
      "status": "provisioning",
      "traffic": {
        "total_gb": 0,
        "used_gb": 0,
        "remaining_gb": 0,
        "updated_at": "2026-01-01T00:00:00Z"
      },
      "subscription_id": "string",
      "expires_at": "2026-01-01T00:00:00Z",
      "created_at": "2026-01-01T00:00:00Z"
    }
  ],
  "count": 0,
  "limit": 0,
  "offset": 0
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
GET/api/v1/residential/plans/{plan}scope: api.residential.read

Get a plan

The plan with the countries POST /plans/{plan}/proxies accepts. Its username and password come from GET /plans/{plan}/credentials; the usernames and gateways to connect with differ per proxy, so they come from POST /plans/{plan}/proxies.

Requires the api.residential.read scope.

Path
planREQUIRED
string
The plan's id.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan} \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "name": "string",
  "status": "provisioning",
  "traffic": {
    "total_gb": 0,
    "used_gb": 0,
    "remaining_gb": 0,
    "updated_at": "2026-01-01T00:00:00Z"
  },
  "subscription_id": "string",
  "expires_at": "2026-01-01T00:00:00Z",
  "created_at": "2026-01-01T00:00:00Z",
  "countries": [
    {
      "country": "US",
      "continent": "NA"
    }
  ]
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
GET/api/v1/residential/plans/{plan}/locationsscope: api.residential.read

List regions and cities

The region and city codes in one of the plan's countries, for the region and city of POST /plans/{plan}/proxies; at most 200 of each. 409 product_withdrawn once the plan's product is no longer sold.

Requires the api.residential.read scope.

Path
planREQUIRED
string
The plan's id.
Query
countryREQUIRED
string
ISO 3166-1 alpha-2 code of one of the plan's countries.
region
string
Only the cities in this region, by its code from regions.
search
string
Only regions and cities whose name matches, at most 64 characters.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan}/locations \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "country": "US",
  "regions": [
    {
      "code": "california",
      "name": "California"
    }
  ],
  "cities": [
    {
      "code": "california",
      "name": "California"
    }
  ]
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
GET/api/v1/residential/plans/{plan}/usagescope: api.residential.read

Get a plan's usage

The requests and traffic the plan used between from and to, at most 400 days apart, as a series of points with their totals.

Requires the api.residential.read scope.

Path
planREQUIRED
string
The plan's id.
Query
fromREQUIRED
string
The start of the window, RFC 3339.
toREQUIRED
string
The end of the window, RFC 3339; after from.
timezone
string
The IANA time zone to lay the series out in, e.g. Europe/Warsaw.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan}/usage \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "from": "2026-01-01T00:00:00Z",
  "to": "2026-01-01T00:00:00Z",
  "timezone": "Europe/Warsaw",
  "requests": 0,
  "traffic_gb": 0,
  "points": [
    {
      "at": "2026-01-01T00:00:00Z",
      "requests": 0,
      "traffic_gb": 0
    }
  ]
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
POST/api/v1/residential/plans/{plan}/proxiesscope: api.residential.manage

Generate proxies

Builds quantity proxies on the plan, each with the gateway for its country, a username carrying its targeting and session, and the plan's password. Nothing is created or changed, but the answer carries the password, so it needs the manage level. Without country, each proxy exits in a random country of the plan. 409 product_withdrawn once the plan's product is no longer sold.

Requires the api.residential.manage scope.

Path
planREQUIRED
string
The plan's id.
Request body
country
string
ISO 3166-1 alpha-2 code of one of the plan's countries; required with region or city. Without it, each proxy exits in a random country of the plan.
region
string
A region code from GET /plans/{plan}/locations: letters, digits and underscores.
city
string
A city code from GET /plans/{plan}/locations: letters, digits and underscores.
rotation
string
rotating (the default): the exit IP changes between requests; sticky: each proxy keeps its IP for a session.
rotatingsticky
session_minutes
integer
How long a sticky session keeps its IP, in minutes; only with rotation sticky, the provider's default when left out.
quantityREQUIRED
integer
How many proxies to generate.
format
string
json (the default), or txt for one host:port:username:password per line.
jsontxt
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan}/proxies \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer df_live_your_key_here' \
  --data '{
    "country": "US",
    "region": "string",
    "city": "string",
    "rotation": "rotating",
    "session_minutes": 1,
    "quantity": 1,
    "format": "json"
  }'
Response
{
  "proxies": [
    {
      "host": "string",
      "port": 0,
      "username": "string",
      "password": "string",
      "country": "US"
    }
  ]
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
GET/api/v1/residential/plans/{plan}/credentialsscope: api.residential.manage

Get the credentials

The plan's base proxy username and the password of every proxy of the plan. They are secrets, so reading them needs the manage level, and the answer is never cached.

Requires the api.residential.manage scope. Every call is recorded in the account's audit log.

Path
planREQUIRED
string
The plan's id.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan}/credentials \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "username": "string",
  "password": "string"
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
POST/api/v1/residential/plans/{plan}/credentials/resetscope: api.residential.manage

Reset the credentials

Issues a new password for every proxy of the plan at once and answers the credentials with it; proxies using the old one stop working. The username does not change. The answer is never cached.

Requires the api.residential.manage scope. Every call is recorded in the account's audit log.

Path
planREQUIRED
string
The plan's id.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan}/credentials/reset \
  --request POST \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "username": "string",
  "password": "string"
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
GET/api/v1/residential/plans/{plan}/auto-top-upscope: api.residential.read

Get the auto top-up

The plan's auto top-up, null when it has none, and the limits a rule on the plan must respect.

Requires the api.residential.read scope.

Path
planREQUIRED
string
The plan's id.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan}/auto-top-up \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
{
  "rule": {
    "status": "armed",
    "reason": "string",
    "threshold_gb": 0,
    "amount_gb": 0,
    "max_per_day": 0,
    "max_per_month_gb": 0,
    "promo_code": "string",
    "payment": {
      "method": "balance",
      "card_id": "string"
    },
    "last_fired_at": "2026-01-01T00:00:00Z",
    "created_at": "2026-01-01T00:00:00Z",
    "updated_at": "2026-01-01T00:00:00Z"
  },
  "limits": {
    "enabled": false,
    "min_threshold_gb": 0,
    "min_amount_gb": 0,
    "max_amount_gb": 0,
    "max_per_day": 0,
    "max_per_month_gb": 0
  }
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
PUT/api/v1/residential/plans/{plan}/auto-top-upscope: api.residential.purchase

Set the auto top-up

Creates the plan's auto top-up, armed, or replaces the settings of the one it has; paused pauses or re-arms it, and left out keeps its status. Whenever the plan's remaining traffic falls to threshold_gb, amount_gb more is bought and charged without asking to payment (the balance, a saved card from GET /api/v1/payment-methods, or the default card when card_id is left out); the charges do not count towards this key's monthly spending limit, which is why it needs the purchase level. A top-up the card refuses, or one charged to a card that was since removed, fails like one the balance cannot cover. Send every field each time; one left out is cleared, promo_code included, except paused and payment, which the rule keeps. 409 auto_top_up_disabled while auto top-ups are switched off for the service (limits.enabled), auto_top_up_blocked when support turned the rule off, product_withdrawn once the plan's product is no longer sold.

Requires the api.residential.purchase scope.

Path
planREQUIRED
string
The plan's id.
Request body
threshold_gbREQUIRED
integer
Top up when the plan's remaining traffic falls to this many GB or below; at least limits.min_threshold_gb.
amount_gbREQUIRED
integer
How many GB each top-up buys, from limits.min_amount_gb to limits.max_amount_gb.
max_per_day
integer
The most top-ups a day; 0 or left out for limits.max_per_day.
max_per_month_gb
integer
The most GB topped up a month, at least amount_gb; 0 or left out for limits.max_per_month_gb.
promo_code
string
A promo code for every top-up.
paused
boolean | null
true pauses the rule; false re-arms a paused or suspended one. Left out, the rule keeps its status, and a new one starts armed.
payment
object | null
What each top-up is charged to. Left out keeps the rule's payment; a new rule charges the balance.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan}/auto-top-up \
  --request PUT \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer df_live_your_key_here' \
  --data '{
    "threshold_gb": 1,
    "amount_gb": 1,
    "max_per_day": 0,
    "max_per_month_gb": 0,
    "promo_code": "string",
    "paused": false,
    "payment": {
      "method": "balance",
      "card_id": "string"
    }
  }'
Response
{
  "rule": {
    "status": "armed",
    "reason": "string",
    "threshold_gb": 0,
    "amount_gb": 0,
    "max_per_day": 0,
    "max_per_month_gb": 0,
    "promo_code": "string",
    "payment": {
      "method": "balance",
      "card_id": "string"
    },
    "last_fired_at": "2026-01-01T00:00:00Z",
    "created_at": "2026-01-01T00:00:00Z",
    "updated_at": "2026-01-01T00:00:00Z"
  },
  "limits": {
    "enabled": false,
    "min_threshold_gb": 0,
    "min_amount_gb": 0,
    "max_amount_gb": 0,
    "max_per_day": 0,
    "max_per_month_gb": 0
  }
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
DELETE/api/v1/residential/plans/{plan}/auto-top-upscope: api.residential.manage

Remove the auto top-up

Stops topping the plan up automatically. 409 auto_top_up_blocked when support turned the rule off: it can only be removed by support.

Requires the api.residential.manage scope.

Path
planREQUIRED
string
The plan's id.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/plans/{plan}/auto-top-up \
  --request DELETE \
  --header 'Authorization: Bearer df_live_your_key_here'
Response
(empty body)
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
POST/api/v1/residential/quotescope: api.residential.read

Price traffic

What POST /orders with the same body would charge, including discounts, tax and the payment method's fee, or why it cannot be ordered. Nothing is reserved.

Requires the api.residential.read scope.

Request body
product_idREQUIRED
string
A product id from GET /products.
traffic_gbREQUIRED
integer
How many GB of traffic to buy; at most the product's max_traffic_gb.
payment
object | null
The payment method, when its fee should be included.
promo_code
string
A promo code; an invalid one is refused, never silently dropped.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/quote \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer df_live_your_key_here' \
  --data '{
    "product_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "traffic_gb": 1,
    "payment": {
      "method": "balance",
      "card_id": "string"
    },
    "promo_code": "string"
  }'
Response
{
  "purchasable": false,
  "issues": [
    {
      "code": "string",
      "message": "string",
      "field": "string",
      "limit": 0
    }
  ],
  "net": 0,
  "discount": 0,
  "tax": 0,
  "fee": 0,
  "total": 0,
  "currency": "usd"
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
POST/api/v1/residential/ordersscope: api.residential.purchase

Buy traffic

Buys traffic_gb of traffic on a product, charged to the balance or a saved card straight away without asking the customer. You hold at most one plan per product and its id is the product's id: the traffic is added to that plan, or the plan is created by the first order. 201 answers the plan; 202 means it is paid and still being delivered, or the bank asked for 3-D Secure (order.action_url).

Requires the api.residential.purchase scope. Send a unique Idempotency-Key per order; repeating it with the same body answers the first order instead of charging again.

Headers
Idempotency-KeyREQUIRED
string
A unique value per order, sent again only to retry the same order.
Request body
product_idREQUIRED
string
A product id from GET /products.
traffic_gbREQUIRED
integer
How many GB of traffic to buy; at most the product's max_traffic_gb.
paymentREQUIRED
object
promo_code
string
A promo code; an invalid one is refused, never silently dropped.
Request
cURL
curl https://api.datafuel.ai/api/v1/residential/orders \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer df_live_your_key_here' \
  --header 'Idempotency-Key: your-idempotency-key' \
  --data '{
    "product_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "traffic_gb": 1,
    "payment": {
      "method": "balance",
      "card_id": "string"
    },
    "promo_code": "string"
  }'
Response
{
  "order": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "pending",
    "service": "string",
    "product": "string",
    "action": "new",
    "total": 0,
    "currency": "usd",
    "payment": {
      "method": "balance",
      "card_id": "string"
    },
    "plan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "action_url": "https://example.com",
    "error": {
      "code": "insufficient_balance",
      "message": "string"
    },
    "replayed": false,
    "created_at": "2026-01-01T00:00:00Z",
    "paid_at": "2026-01-01T00:00:00Z"
  },
  "plan": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string",
    "status": "provisioning",
    "traffic": {
      "total_gb": 0,
      "used_gb": 0,
      "remaining_gb": 0,
      "updated_at": "2026-01-01T00:00:00Z"
    },
    "subscription_id": "string",
    "expires_at": "2026-01-01T00:00:00Z",
    "created_at": "2026-01-01T00:00:00Z",
    "countries": [
      {
        "country": "US",
        "continent": "NA"
      }
    ]
  }
}
{
  "order": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "pending",
    "service": "string",
    "product": "string",
    "action": "new",
    "total": 0,
    "currency": "usd",
    "payment": {
      "method": "balance",
      "card_id": "string"
    },
    "plan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "action_url": "https://example.com",
    "error": {
      "code": "insufficient_balance",
      "message": "string"
    },
    "replayed": false,
    "created_at": "2026-01-01T00:00:00Z",
    "paid_at": "2026-01-01T00:00:00Z"
  },
  "plan": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string",
    "status": "provisioning",
    "traffic": {
      "total_gb": 0,
      "used_gb": 0,
      "remaining_gb": 0,
      "updated_at": "2026-01-01T00:00:00Z"
    },
    "subscription_id": "string",
    "expires_at": "2026-01-01T00:00:00Z",
    "created_at": "2026-01-01T00:00:00Z",
    "countries": [
      {
        "country": "US",
        "continent": "NA"
      }
    ]
  }
}
{
  "order": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "pending",
    "service": "string",
    "product": "string",
    "action": "new",
    "total": 0,
    "currency": "usd",
    "payment": {
      "method": "balance",
      "card_id": "string"
    },
    "plan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "action_url": "https://example.com",
    "error": {
      "code": "insufficient_balance",
      "message": "string"
    },
    "replayed": false,
    "created_at": "2026-01-01T00:00:00Z",
    "paid_at": "2026-01-01T00:00:00Z"
  },
  "plan": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string",
    "status": "provisioning",
    "traffic": {
      "total_gb": 0,
      "used_gb": 0,
      "remaining_gb": 0,
      "updated_at": "2026-01-01T00:00:00Z"
    },
    "subscription_id": "string",
    "expires_at": "2026-01-01T00:00:00Z",
    "created_at": "2026-01-01T00:00:00Z",
    "countries": [
      {
        "country": "US",
        "continent": "NA"
      }
    ]
  }
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}
{
  "error": "string",
  "message": "string",
  "meta": {}
}