Static Residential API: Quotes, Purchases, and Operation Status
Purchase static residential proxies using quotes and idempotency keys, and handle asynchronous status, refunds, and uncertain outcomes.
Static residential purchases have three stages: request a quote, submit an operation, and track its result. A quote does not buy proxies. Submitting an order creates a real purchase operation and can debit the account, so review the location, quantity, business name, and total first.
1. Endpoints and scopes
Use the business API host and send Api-Token: YOUR_API_KEY on every request.
| Method and path | Scope | Purpose |
|---|---|---|
POST /api/user/v1/static-residential/quotes | static:inventory:read | Obtain a quote |
POST /api/user/v1/static-residential/orders | static:purchase | Submit a purchase operation |
GET /api/user/v1/static-residential/operations/{operation_no} | static:purchase | Read operation status |
POST requests use Content-Type: application/json. Reading delivered IPs also requires static:ip:read. A legacy key that can read inventory is not necessarily authorized to purchase.
2. Request a quote
Choose valid values from the countries, cities/inventory, and business-name endpoints before submitting:
| JSON field | Required | Description |
|---|---|---|
country_code | Yes | Two-letter country code |
city_name | Yes | Exact city name from inventory; do not translate or correct it |
quantity | Yes | Positive integer; the default service cap is 20, subject to the deployed limit |
duration_days | No | Defaults to 30; currently only 30 days are supported |
business_name | No | Defaults to other, which must still exist in the current business-name list |
protocol | No | http, socks5, or both; defaults to both |
Replace COUNTRY_CODE, CITY_NAME, and BUSINESS_NAME with returned values. The client does not choose the purchase price.
curl --silent --show-error --max-time 30 \
"$DFIP_API_BASE/api/user/v1/static-residential/quotes" \
-H "Api-Token: $DFIP_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"country_code":"COUNTRY_CODE","city_name":"CITY_NAME","quantity":1,"duration_days":30,"business_name":"BUSINESS_NAME","protocol":"both"}'
On success, data includes quote_id, country_code, city_name, quantity, duration_days, business_name, protocol, unit_price, total_amount, currency, and expires_in.
A quote belongs to the calling account and is valid for 300 seconds. Currency is USD. Show and review total_amount before purchasing. The quote checks current stock and pricing but does not reserve stock or account funds. If it expires, obtain another quote and review its amount again.
3. Submit with an idempotency key
The required Idempotency-Key header must contain 8–64 characters: letters, digits, periods, underscores, colons, or hyphens.
Save the key, purchase intent, and quote_id before sending the request. Use a new key for a deliberately new purchase and retain the original key for retries of the same purchase. Do not generate a fresh key on each network attempt.
# Use a unique key for a new purchase and retain it for retries.
export DFIP_PURCHASE_KEY='YOUR_UNIQUE_PURCHASE_KEY'
curl --silent --show-error --max-time 30 \
"$DFIP_API_BASE/api/user/v1/static-residential/orders" \
-H "Api-Token: $DFIP_API_KEY" \
-H "Idempotency-Key: $DFIP_PURCHASE_KEY" \
-H 'Content-Type: application/json' \
--data '{"quote_id":"YOUR_QUOTE_ID"}'
An accepted request returns HTTP 202, code: 0, and operation fields including operation_no and status. Do not display this as a completed purchase.
If the calling account already has an operation for the key, the endpoint returns that original operation, even after the old quote expires. Never reuse an old key for a different purchase. Do not rely on changed parameters always producing a conflict response: your application must retain and check the association between a key and its purchase intent.
4. Track the operation and delivery
curl --silent --show-error --max-time 30 \
"$DFIP_API_BASE/api/user/v1/static-residential/operations/YOUR_OPERATION_NO" \
-H "Api-Token: $DFIP_API_KEY"
As an integration recommendation, begin polling every 2–5 seconds and increase the interval for longer waits. This is not a fixed service quota. Keep querying the same operation_no.
| status | Meaning and action |
|---|---|
pending | Accepted and awaiting processing; continue polling |
processing | Work is in progress and funds may have been debited; do not buy again |
finalizing | The upstream purchase succeeded and local delivery records are being finalized; keep polling |
completed | The operation is complete; match local_order_id to the order and retrieve purchased IPs |
failed_refunded | Purchase failed and the pre-debited amount was returned; verify the balance before deciding on a new purchase |
failed | Failure without a charge; inspect message and correct the cause |
reconcile_required | Outcome needs verification; retain the operation number and contact support instead of submitting another purchase |
unknown | Unrecognized status; retain the operation and contact support, rather than assuming success |
Operation data contains operation_no, status, message, country_code, city_name, quantity, duration_days, business_name, amount, local_order_id, created_at, and completed_at. The order identifier and completion time can be null until available.
amount is the quoted amount, not proof that a debit occurred. Reconcile it with status and account records. After completed, use the purchased IP endpoints to obtain credentials and ports. A timeout in your polling loop does not itself mean the operation failed.
5. Errors
| HTTP / code | Meaning and response |
|---|---|
400 / 40002 | Invalid location, quantity, duration, business name, or protocol |
400 / 40004 | Missing or malformed idempotency key |
400 / 40005 | Missing, expired, or inaccessible quote; track any existing purchase before starting again |
402 / 40201 | Insufficient funds; data contains available_balance, required_amount, and currency |
403 / 40301 | Missing scope |
403 / 40302 | Request address is outside the key's IP allowlist |
403 / 40303, 40304, 40305 | Calling account, subaccount permission, or shared parent account is unavailable |
404 / 40401 | No accessible operation for this account |
409 / 40901 | Insufficient stock; inspect available_stock and choose again |
409 / 40902 | Conflicting idempotent parameters; inspect local records before making any new purchase |
503 / 50303 | Queue submission failed; retain the key and establish the original operation's outcome |
503 / 50304 | Location pricing unavailable; contact support |
503 / 50305 | Quote service temporarily unavailable |
500 / 50001 | Submission error; reuse the original key to establish the existing operation before considering another purchase |
Temporary authentication service failures can return 503 / 50300. Missing or invalid keys return 401 / 40101 or 40102. A timeout, lost response, or server error is not a reason to automatically generate a new purchase key.
Integration checklist
- Confirm the location and amount before submitting.
- Persist the key and purchase parameters; store operation_no as soon as it is returned.
- Treat HTTP 202 as in progress and only completed as completion.
- Stop automatic repurchasing for reconcile_required and arrange verification.
- Keep API keys, proxy credentials, and complete sensitive responses out of public logs.
This API group currently supports purchasing and querying. It does not expose renewal, auto-renew toggles, deletion, or IP replacement endpoints; use the existing console functions for those actions.