Customer API
Manage proxies, traffic and billing from your own application.
Send your workspace API key as a Bearer token. Each endpoint lists its required permissions. Confirming a purchase or renewal charges your wallet.
Requests use your API key and the selected server. Purchase and renewal requests can spend your wallet balance.
Manage proxies, traffic and billing from your own application.
Send your workspace API key as a Bearer token. Each endpoint lists its required permissions. Confirming a purchase or renewal charges your wallet.
Workspace API
Required permissions: wallet:read.
Returns the same wallet DTO the portal uses.
curl https://portal.migoip.com/api/customer/v1/balance \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"balance_fen": "string"
}Wallet balance
Required permissions: account:read.
Requires account:read. Returns the workspace and issuer derived from the API key, its base permission and explicit scopes (null for a legacy key). No customer-selected identity parameters or secrets.
curl https://portal.migoip.com/api/customer/v1/account \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"user_id": "string",
"permission": "read",
"scopes": [
"account:read"
]
}Identify the authenticated workspace
Required permissions: catalog:read.
Exactly the tenant-effective type -> country -> location price resolution the portal uses, with exact terms and prices. Internal pricing provenance is not exposed.
curl https://portal.migoip.com/api/customer/v1/catalog \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"location_kind": "city",
"id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"base_fen": "string",
"optimization_fen": "string",
"optimization_enabled": true,
"optimization_supported": true,
"supported_protocols": [],
"supply_mode": "string"
}
],
"total": 0
}Effective offer list
Required permissions: orders:write.
Write permission required. Freezes the effective unit and total price for
the requested quantity and protocol. The response never
contains the simulator scenario or any supplier field. Unknown body
fields (including tenant_id and scenario) are rejected with 422.
The price_id must identify a named-location offer. Country/product rules
and country-only synthesized IDs return 422 LOCATION_REQUIRED.
Unknown fields, including tenant_id and scenario, are rejected with 422.
Integer numbers.
Select the independently priced per-IP access-optimization add-on; rejected when the effective offer does not support it
Opt the purchase into wallet auto-renew; non-financial until the scheduler charges
Optional one-per-purchase percentage coupon code. Trimmed and upper-cased server-side; an unknown
Optional plain-text instance note of at most 200 Unicode characters; a multi-IP purchase suffixes each instance by its durable order-item ordinal
A connection-format preference
curl https://portal.migoip.com/api/customer/v1/quotes \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"price_id": "",
"quantity": 1,
"protocol": "http",
"access_optimized": false,
"note": "",
"auto_renew_enabled": false,
"coupon_code": ""
}'
{
"purchase_kind": "purchase",
"service_id": "string",
"service_expires_at": "2026-10-26T05:45:59.177Z",
"id": "string",
"tenant_id": "string",
"price_id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"quantity": 1,
"protocol": "http",
"access_optimized": true,
"optimization_fen": "string",
"unit_fen": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"total_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"created_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z",
"note": "string",
"auto_renew_enabled": true
}Frozen quote
Required permissions: orders:write, wallet:spend.
Write permission required. Charges the wallet and queues exactly one
fulfillment operation, in one transaction. Requires Idempotency-Key;
an exact replay returns the original order and operation without another
debit, and a concurrent duplicate is collapsed to the same order.
Quotes without a named location return 422 LOCATION_REQUIRED before debit.
Exact replay returns the original result without spending twice; a changed body conflicts.
curl https://portal.migoip.com/api/customer/v1/orders \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"quote_id": ""
}'
{
"order": {
"purchase_kind": "purchase",
"service_id": "string",
"id": "string",
"tenant_id": "string",
"quote_id": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"total_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"status": "provisioning",
"created_at": "2026-10-26T05:45:59.177Z"
},
"operations": [
{
"id": "string",
"order_id": "string",
"kind": "string",
"state": "queued",
"error_code": "string",
"attempt_count": 0,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
}
]
}Accepted (or replayed) order with its queued operation
Required permissions: orders:read.
Newest first, bounded pagination.
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/orders?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"purchase_kind": "purchase",
"service_id": "string",
"id": "string",
"tenant_id": "string",
"quote_id": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"total_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"status": "provisioning",
"created_at": "2026-10-26T05:45:59.177Z"
}
],
"total": 0,
"page": 1,
"page_size": 1
}Order page
Required permissions: orders:read.
A foreign or unknown order id is 404; no other tenant's record is visible.
curl 'https://portal.migoip.com/api/customer/v1/orders/{id}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"order": {
"purchase_kind": "purchase",
"service_id": "string",
"id": "string",
"tenant_id": "string",
"quote_id": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"total_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"status": "provisioning",
"created_at": "2026-10-26T05:45:59.177Z"
},
"quote": {
"purchase_kind": "purchase",
"service_id": "string",
"service_expires_at": "2026-10-26T05:45:59.177Z",
"id": "string",
"tenant_id": "string",
"price_id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"quantity": 1,
"protocol": "http",
"access_optimized": true,
"optimization_fen": "string",
"unit_fen": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"total_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"created_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z",
"note": "string",
"auto_renew_enabled": true
},
"items": [
{
"id": "string",
"ordinal": 1,
"amount_fen": "string"
}
],
"operations": [
{
"id": "string",
"order_id": "string",
"kind": "string",
"state": "queued",
"error_code": "string",
"attempt_count": 0,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
}
],
"services": [
{
"id": "string",
"order_id": "string",
"operation_id": "string",
"ip": "string",
"hostname": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"refunded_at": "2026-10-26T05:45:59.177Z",
"protocol": "http",
"activated_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z",
"term_state": "active",
"connection_available": true,
"direct_connection_available": true,
"optimized_connection_available": true,
"supported_protocols": [],
"renewable": true,
"simulated": true,
"provenance": "provider",
"optimization": {
"selected": true,
"state": "pending",
"bandwidth": {
"upload": {
"bytes_per_second": "string",
"burst_bytes": "string"
},
"download": {
"bytes_per_second": "string",
"burst_bytes": "string"
}
}
},
"lifecycle": {
"supported": true,
"renewal_supported": true,
"revoke_supported": true,
"access_state": "string",
"expires_at": "2026-10-26T05:45:59.177Z",
"can_renew": true,
"renewal_block_reason": "string",
"latest_renewal": {
"id": "string",
"service_id": "string",
"quote_id": "string",
"branch": "extend",
"amount_fen": "string",
"state": "queued",
"error_code": "string",
"term_start": null,
"expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
},
"prices": [
{
"id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"base_fen": "string"
}
]
},
"note": "string",
"settings_version": 1,
"auto_renew_enabled": true,
"auto_renew_period": "string",
"auto_renew_state": "off",
"auto_renew_next_attempt_at": "2026-10-26T05:45:59.177Z"
}
]
}Order detail
Required permissions: orders:read.
Bounded status only: id, kind, state,
attempt count and timestamps. Supplier identifiers, leases, modes and raw
error codes are never exposed; any internal failure is reported as
OPERATION_NEEDS_ATTENTION.
curl 'https://portal.migoip.com/api/customer/v1/operations/{id}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"id": "string",
"order_id": "string",
"kind": "string",
"state": "queued",
"error_code": "string",
"attempt_count": 0,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
}Operation status
Required permissions: orders:read.
Requires orders:read. Includes static orders, optimization upgrades, renewals and dynamic traffic purchases.
Integer numbers.
Integer numbers.
Inclusive RFC3339 or YYYY-MM-DD UTC lower bound.
Exclusive RFC3339 or YYYY-MM-DD UTC upper bound. Must be later than from.
curl 'https://portal.migoip.com/api/customer/v1/order-history?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"tenant_id": "string",
"kind": "static",
"purchase_kind": "purchase",
"service_id": "string",
"product": "static_residential",
"country": "string",
"location_name": "string",
"period": "string",
"days": 0,
"quantity": 0,
"traffic_bytes": "string",
"total_fen": "string",
"status": "provisioning",
"created_at": "2026-10-26T05:45:59.177Z"
}
],
"total": 0,
"page": 1,
"page_size": 1
}List unified order history
Required permissions: proxies:read.
Bounded pagination; optional product and term-state filters, a literal free-text search (which may also match notes) and an exact IP filter. Each row carries the embedded lifecycle guard and its instance settings (note, optimistic version and auto-renew state), which a legacy row without settings reads as empty note, version 1 and auto-renew off.
Integer numbers.
Integer numbers.
Recorded dates only; not a live cutoff claim
Literal case-insensitive free-text search; may also match instance notes
Comma-separated normalized exact IPv4/IPv6 addresses
curl 'https://portal.migoip.com/api/customer/v1/proxies?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"order_id": "string",
"operation_id": "string",
"ip": "string",
"hostname": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"refunded_at": "2026-10-26T05:45:59.177Z",
"protocol": "http",
"activated_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z",
"term_state": "active",
"connection_available": true,
"direct_connection_available": true,
"optimized_connection_available": true,
"supported_protocols": [],
"renewable": true,
"simulated": true,
"provenance": "provider",
"optimization": {
"selected": true,
"state": "pending",
"bandwidth": {
"upload": {
"bytes_per_second": "string",
"burst_bytes": "string"
},
"download": {
"bytes_per_second": "string",
"burst_bytes": "string"
}
}
},
"lifecycle": {
"supported": true,
"renewal_supported": true,
"revoke_supported": true,
"access_state": "string",
"expires_at": "2026-10-26T05:45:59.177Z",
"can_renew": true,
"renewal_block_reason": "string",
"latest_renewal": {
"id": "string",
"service_id": "string",
"quote_id": "string",
"branch": "extend",
"amount_fen": "string",
"state": "queued",
"error_code": "string",
"term_start": null,
"expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
},
"prices": [
{
"id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"base_fen": "string"
}
]
},
"note": "string",
"settings_version": 1,
"auto_renew_enabled": true,
"auto_renew_period": "string",
"auto_renew_state": "off",
"auto_renew_next_attempt_at": "2026-10-26T05:45:59.177Z"
}
],
"total": 0,
"page": 1,
"page_size": 1
}Instance page
Required permissions: proxies:read, credentials:read.
Returns text/plain: one LF-terminated
host:port:username:password tuple per line for a single explicit
protocol, at most page_size lines. An IPv6 host is bracketed. Only
connections that are usable right now are exported: an expired or
otherwise credential-free instance contributes no line, so an empty
export is a 200 with an empty body, never JSON. A genuine read failure
fails the whole request instead of silently dropping an instance.
Pagination metadata rides on the response headers, not the body. Never
log the returned values. access_mode defaults to preferred. Explicit direct or
optimized selection never falls back to the other route. The exact ips
filter intersects product, term and search filters.
Explicit route selection; unavailable routes produce no line
Comma-separated exact IPv4/IPv6 values; at most 100 normalized unique addresses. Empty/invalid tokens and repeated ips parameters are rejected.
HTTP maps to the stored HTTPS/CONNECT representation
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/proxies/export?access_mode=preferred&protocol=http&page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
203.0.113.10:8443:acme-user:secret
One bounded page of plaintext tuples, one per line. The body is empty when no instance in the page has a usable connection for the requested protocol.
Required permissions: proxies:read, credentials:read.
Returns the instance plus the per-protocol connection tuples the backend permits. An expired instance exposes no usable connection. A foreign or unknown id is 404.
curl 'https://portal.migoip.com/api/customer/v1/proxies/{id}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"service": {
"id": "string",
"order_id": "string",
"operation_id": "string",
"ip": "string",
"hostname": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"refunded_at": "2026-10-26T05:45:59.177Z",
"protocol": "http",
"activated_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z",
"term_state": "active",
"connection_available": true,
"direct_connection_available": true,
"optimized_connection_available": true,
"supported_protocols": [],
"renewable": true,
"simulated": true,
"provenance": "provider",
"optimization": {
"selected": true,
"state": "pending",
"bandwidth": {
"upload": {
"bytes_per_second": "string",
"burst_bytes": "string"
},
"download": {
"bytes_per_second": "string",
"burst_bytes": "string"
}
}
},
"lifecycle": {
"supported": true,
"renewal_supported": true,
"revoke_supported": true,
"access_state": "string",
"expires_at": "2026-10-26T05:45:59.177Z",
"can_renew": true,
"renewal_block_reason": "string",
"latest_renewal": {
"id": "string",
"service_id": "string",
"quote_id": "string",
"branch": "extend",
"amount_fen": "string",
"state": "queued",
"error_code": "string",
"term_start": null,
"expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
},
"prices": [
{
"id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"base_fen": "string"
}
]
},
"note": "string",
"settings_version": 1,
"auto_renew_enabled": true,
"auto_renew_period": "string",
"auto_renew_state": "off",
"auto_renew_next_attempt_at": "2026-10-26T05:45:59.177Z"
},
"connections": [
{
"protocol": "http",
"host": "string",
"port": 1,
"username": "string",
"password": "string",
"simulated": true
}
],
"direct_connections": [
{
"protocol": "http",
"host": "string",
"port": 1,
"username": "string",
"password": "string",
"simulated": true
}
],
"optimized_connections": [
{
"protocol": "http",
"host": "string",
"port": 1,
"username": "string",
"password": "string",
"simulated": true
}
]
}Instance detail
Required permissions: proxies:write.
Write permission required. Applies one optimistic-concurrency settings update: an expected version plus the optional note and/or auto-renew opt-in; omitted fields stay unchanged. Bounded note validation (at most 200 Unicode characters). Opt-in requires a verified tenant and an active, unexpired, unrefunded instance with renewal support and an original purchase duration. Disabling and note-only edits do not require renewal eligibility. Never a financial command: enabling auto-renew has no wallet effect until the scheduler actually charges, which needs a current active/verified tenant and an active authorizing membership. A stale version is a 409 conflict; a foreign or unknown id is 404.
Optimistic-concurrency instance settings update. Omitted note/auto_renew_enabled stay unchanged; a stale expected_version conflicts.
The settings_version last read for the instance
Replacement auto-renew opt-in; non-financial until the scheduler charges
Replacement note
curl 'https://portal.migoip.com/api/customer/v1/proxies/{id}/settings' \
--request PATCH \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"expected_version": 1,
"note": "",
"auto_renew_enabled": true
}'
{
"service": {
"id": "string",
"order_id": "string",
"operation_id": "string",
"ip": "string",
"hostname": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"refunded_at": "2026-10-26T05:45:59.177Z",
"protocol": "http",
"activated_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z",
"term_state": "active",
"connection_available": true,
"direct_connection_available": true,
"optimized_connection_available": true,
"supported_protocols": [],
"renewable": true,
"simulated": true,
"provenance": "provider",
"optimization": {
"selected": true,
"state": "pending",
"bandwidth": {
"upload": {
"bytes_per_second": "string",
"burst_bytes": "string"
},
"download": {
"bytes_per_second": "string",
"burst_bytes": "string"
}
}
},
"lifecycle": {
"supported": true,
"renewal_supported": true,
"revoke_supported": true,
"access_state": "string",
"expires_at": "2026-10-26T05:45:59.177Z",
"can_renew": true,
"renewal_block_reason": "string",
"latest_renewal": {
"id": "string",
"service_id": "string",
"quote_id": "string",
"branch": "extend",
"amount_fen": "string",
"state": "queued",
"error_code": "string",
"term_start": null,
"expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
},
"prices": [
{
"id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"base_fen": "string"
}
]
},
"note": "string",
"settings_version": 1,
"auto_renew_enabled": true,
"auto_renew_period": "string",
"auto_renew_state": "off",
"auto_renew_next_attempt_at": "2026-10-26T05:45:59.177Z"
},
"connections": [
{
"protocol": "http",
"host": "string",
"port": 1,
"username": "string",
"password": "string",
"simulated": true
}
],
"direct_connections": [
{
"protocol": "http",
"host": "string",
"port": 1,
"username": "string",
"password": "string",
"simulated": true
}
],
"optimized_connections": [
{
"protocol": "http",
"host": "string",
"port": 1,
"username": "string",
"password": "string",
"simulated": true
}
]
}Updated instance detail (credentials omitted from a settings write)
Required permissions: orders:write.
Write permission required. Binds the service revision, effective price version and the exact extension arithmetic from the recorded expiry. Read-only: no debit and no provider mutation. An expired, unsupported or manual non-renewable instance returns the existing guard error and no quote.
curl 'https://portal.migoip.com/api/customer/v1/proxies/{id}/renewal-quotes' \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"price_id": ""
}'
{
"id": "string",
"service_id": "string",
"branch": "extend",
"price_id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"optimization_selected": true,
"base_fen": "string",
"optimization_fen": "string",
"total_fen": "string",
"old_expires_at": "2026-10-26T05:45:59.177Z",
"proposed_expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z"
}Renewal quote snapshot
Required permissions: orders:write, wallet:spend.
Write permission required. Debits exactly once with the required
Idempotency-Key: wallet debit and renewal row share one transaction and
the quote stays bound to the paying actor. An exact replay returns the
original renewal; a used quote or changed body conflicts without a debit.
The provider mutation is queued for the worker, never performed inline.
Exact replay returns the original result without spending twice; a changed body conflicts.
curl 'https://portal.migoip.com/api/customer/v1/proxies/{id}/renewals' \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"quote_id": ""
}'
{
"renewal": {
"id": "string",
"service_id": "string",
"quote_id": "string",
"branch": "extend",
"amount_fen": "string",
"state": "queued",
"error_code": "string",
"term_start": null,
"expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
}
}Accepted or replayed renewal
Required permissions: orders:read.
Only the key tenant's own renewal is visible.
curl 'https://portal.migoip.com/api/customer/v1/proxies/{id}/renewals/{renewal}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"renewal": {
"id": "string",
"service_id": "string",
"quote_id": "string",
"branch": "extend",
"amount_fen": "string",
"state": "queued",
"error_code": "string",
"term_start": null,
"expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
}
}Renewal status
Required permissions: orders:write.
Requires write permission and orders:write. Confirm through POST /orders. Existing service expiry is unchanged. Coupons are not supported on upgrades (COUPON_UNAVAILABLE). Unknown body fields are refused.
curl 'https://portal.migoip.com/api/customer/v1/proxies/{id}/optimization-quotes' \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"coupon_code": ""
}'
{
"purchase_kind": "purchase",
"service_id": "string",
"service_expires_at": "2026-10-26T05:45:59.177Z",
"id": "string",
"tenant_id": "string",
"price_id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"quantity": 1,
"protocol": "http",
"access_optimized": true,
"optimization_fen": "string",
"unit_fen": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"total_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"created_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z",
"note": "string",
"auto_renew_enabled": true
}Quote optimization for an existing static IP
Required permissions: orders:write.
Requires write permission and orders:write. Accepts 1–100 unique owned service IDs and their exact renewal price IDs. Any ineligible item rejects the entire quote.
curl https://portal.migoip.com/api/customer/v1/proxies/batch-renewal-quotes \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"items": [
{
"service_id": "",
"price_id": ""
}
]
}'
{
"id": "string",
"tenant_id": "string",
"actor_id": "string",
"total_fen": "string",
"created_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z",
"quotes": [
{
"id": "string",
"service_id": "string",
"branch": "extend",
"price_id": "string",
"product": "static_residential",
"country": "string",
"location_id": "string",
"location_name": "string",
"location_subdivision": "string",
"period": "string",
"days": 1,
"optimization_selected": true,
"base_fen": "string",
"optimization_fen": "string",
"total_fen": "string",
"old_expires_at": "2026-10-26T05:45:59.177Z",
"proposed_expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z"
}
]
}Quote an atomic batch renewal
Required permissions: orders:write, wallet:spend.
Requires write permission and orders:write, wallet:spend. One atomic wallet debit; each IP subsequently has its own fulfillment outcome. Reuse the Idempotency-Key on an exact retry.
Exact replay returns the original result without spending twice; a changed body conflicts.
curl https://portal.migoip.com/api/customer/v1/proxies/batch-renewals \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"quote_id": ""
}'
{
"id": "string",
"tenant_id": "string",
"quote_id": "string",
"total_fen": "string",
"created_at": "2026-10-26T05:45:59.177Z",
"renewals": [
{
"id": "string",
"service_id": "string",
"quote_id": "string",
"branch": "extend",
"amount_fen": "string",
"state": "queued",
"error_code": "string",
"term_start": null,
"expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
}
]
}Confirm a batch renewal
Required permissions: orders:read.
Requires orders:read. Foreign and unknown IDs return 404. Internal failure codes are returned as OPERATION_NEEDS_ATTENTION.
curl 'https://portal.migoip.com/api/customer/v1/proxies/batch-renewals/{batch}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"id": "string",
"tenant_id": "string",
"quote_id": "string",
"total_fen": "string",
"created_at": "2026-10-26T05:45:59.177Z",
"renewals": [
{
"id": "string",
"service_id": "string",
"quote_id": "string",
"branch": "extend",
"amount_fen": "string",
"state": "queued",
"error_code": "string",
"term_start": null,
"expires_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
}
]
}Read a batch renewal
Required permissions: dynamic:read.
Requires dynamic:read. Countries, protocols and sticky durations reflect configured support. Disabled products return no sellable packs. Select a pack by its kind: standard or optimization.
curl https://portal.migoip.com/api/customer/v1/dynamic/config \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"ready": true,
"ready_reason": "string",
"capabilities": {
"usage_analytics": {
"breakdowns": [
"overview"
],
"intervals": [
"hour"
],
"max_window_days": 0,
"bucket_timezone": "string",
"balance_reporting": true
},
"supported_countries": [
"string"
],
"protocols": [
"http"
],
"modes": [
"rotating"
],
"sticky_session_minutes": [
1
],
"sticky_default_minutes": 0
},
"packs": [
{
"id": "string",
"label": "string",
"kind": "standard",
"bytes": "string",
"price_fen": "string",
"version": 1
}
]
}Read dynamic capabilities and traffic packs
Required permissions: dynamic:read.
Requires dynamic:read. Residential/Usage supplies the standard total/used/remaining snapshot. Reading this data never changes the wallet or traffic allowance. Do not use windowed analytics as cumulative billing usage.
curl https://portal.migoip.com/api/customer/v1/dynamic/account \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"usage_status": "reported",
"purchased_bytes": "string",
"adjustment_bytes": "string",
"balance_status": "reported",
"balance_source": "local",
"balance_observed_at": "2026-10-26T05:45:59.177Z",
"total_bytes": "string",
"used_bytes": "string",
"remaining_bytes": "string",
"status": "none",
"last_usage_at": "2026-10-26T05:45:59.177Z",
"optimization": {
"purchased_bytes": "string",
"adjustment_bytes": "string",
"consumed_bytes": "string",
"reserved_bytes": "string",
"uncertain_bytes": "string",
"available_bytes": "string",
"remaining_bytes": "string",
"usable_bytes": "string",
"pending_node_bytes": "string",
"status": "none",
"availability_reason": "none"
}
}Read standard and optimization traffic balances
Required permissions: dynamic:read.
Requires dynamic:read. Defaults to the last 24 hours, ending at the current UTC minute. Maximum window 30 days, or a lower capability limit. Missing geographic attribution is country unknown, not zero usage. A reporting cooldown returns 429 DYNAMIC_USAGE_RATE_LIMITED with Retry-After.
Inclusive lower bound.
Exclusive upper bound; at most one minute in the future.
Maximum ranked host rows.
curl 'https://portal.migoip.com/api/customer/v1/dynamic/usage?breakdown=overview&interval=hour&limit=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"status": "reported",
"from": "2026-10-26T05:45:59.177Z",
"to": "2026-10-26T05:45:59.177Z",
"breakdown": "overview",
"interval": "hour",
"bucket_timezone": "string",
"observed_at": "2026-10-26T05:45:59.177Z",
"totals": {
"request_count": "string",
"limited_count": "string",
"error_count": "string",
"upload_bytes": "string",
"download_bytes": "string",
"total_bytes": "string"
},
"rows": [
{
"request_count": "string",
"limited_count": "string",
"error_count": "string",
"upload_bytes": "string",
"download_bytes": "string",
"total_bytes": "string",
"bucket_start": "2026-10-26T05:45:59.177Z",
"country": "string",
"host": "string"
}
],
"capabilities": {
"breakdowns": [
"overview"
],
"intervals": [
"hour"
],
"max_window_days": 0,
"bucket_timezone": "string",
"balance_reporting": true
}
}Read windowed dynamic usage analytics
Required permissions: dynamic:write.
Requires write permission and dynamic:write. Uses the workspace-effective pack price and optional eligible coupon.
curl https://portal.migoip.com/api/customer/v1/dynamic/quotes \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"pack_id": "",
"coupon_code": ""
}'
{
"id": "string",
"tenant_id": "string",
"pack_id": "string",
"pack_label": "string",
"kind": "standard",
"bytes": "string",
"price_version": 1,
"subtotal_fen": "string",
"discount_fen": "string",
"total_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"created_at": "2026-10-26T05:45:59.177Z",
"expires_at": "2026-10-26T05:45:59.177Z"
}Quote a dynamic traffic pack
Required permissions: dynamic:write, wallet:spend.
Requires write permission and dynamic:write, wallet:spend. Send pack_id, price_version and expected_total_fen from config, or include quote_id and echo the quote’s exact pack/version/total. Prefer a quote to freeze price and use coupons. Exact retries return the same receipt without another debit or supplier grant. A 502 grant result includes the purchase for status tracking; poll it or contact support rather than creating another purchase.
Exact replay returns the original result without spending twice; a changed body conflicts.
Integer CNY fen; no binary floating-point money
Integer numbers.
curl https://portal.migoip.com/api/customer/v1/dynamic/purchases \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"pack_id": "",
"price_version": 1,
"expected_total_fen": "",
"quote_id": ""
}'
{
"purchase": {
"id": "string",
"tenant_id": "string",
"pack_id": "string",
"pack_label": "string",
"quote_id": "string",
"kind": "standard",
"bytes": "string",
"price_fen": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"price_version": 1,
"status": "string",
"created_at": "2026-10-26T05:45:59.177Z"
}
}Purchase a traffic pack
Required permissions: dynamic:read.
Requires dynamic:read. Includes both traffic kinds unless filtered.
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/dynamic/purchases?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"tenant_id": "string",
"pack_id": "string",
"pack_label": "string",
"quote_id": "string",
"kind": "standard",
"bytes": "string",
"price_fen": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"price_version": 1,
"status": "string",
"created_at": "2026-10-26T05:45:59.177Z"
}
],
"total": 0,
"page": 1,
"page_size": 1
}List dynamic traffic purchases
Required permissions: dynamic:read.
Requires dynamic:read. Unknown and foreign IDs return 404. Provisioning retry, cancellation and wallet refunds remain operator-only.
curl 'https://portal.migoip.com/api/customer/v1/dynamic/purchases/{id}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"id": "string",
"tenant_id": "string",
"pack_id": "string",
"pack_label": "string",
"quote_id": "string",
"kind": "standard",
"bytes": "string",
"price_fen": "string",
"subtotal_fen": "string",
"discount_fen": "string",
"coupon": {
"id": "string",
"code": "string",
"name": "string",
"discount_bps": 1
},
"price_version": 1,
"status": "string",
"created_at": "2026-10-26T05:45:59.177Z"
}Read dynamic traffic purchase status
Required permissions: dynamic:read.
Requires dynamic:read. Newest first across direct and optimized profiles. The list is bounded by saved-profile limits and always omits credentials (connection is null).
curl https://portal.migoip.com/api/customer/v1/dynamic/profiles \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"optimization_available": true,
"items": [
{
"id": "string",
"tenant_id": "string",
"country": "string",
"mode": "rotating",
"duration_minutes": 1,
"state": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"access_optimized": true,
"connection": {
"username": "string",
"password": "string",
"endpoints": {
"http": {
"host": "string",
"port": 1
},
"socks5": {
"host": "string",
"port": 1
}
}
}
}
]
}List saved dynamic connections
Required permissions: dynamic:write, credentials:read.
Requires write permission and dynamic:write, credentials:read. Use country * for all available countries when advertised by config; country is required. Select rotating or sticky mode and a supported sticky duration. The same effective configuration reuses its saved profile, including under a new idempotency key. Optimized access requires available allowance, gateway and a healthy assigned node. Credential-bearing responses are sensitive.
Exact replay returns the original result without spending twice; a changed body conflicts.
ISO country code from config, or * for all available countries.
Integer numbers.
curl https://portal.migoip.com/api/customer/v1/dynamic/profiles \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"country": "",
"protocol": "http",
"mode": "rotating",
"duration_minutes": 1,
"access_optimized": false
}'
{
"profile": {
"id": "string",
"tenant_id": "string",
"country": "string",
"mode": "rotating",
"duration_minutes": 1,
"state": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"access_optimized": true,
"connection": {
"username": "string",
"password": "string",
"endpoints": {
"http": {
"host": "string",
"port": 1
},
"socks5": {
"host": "string",
"port": 1
}
}
}
}
}Generate or reuse a dynamic connection
Required permissions: dynamic:read, credentials:read.
Requires dynamic:read, credentials:read. Connection credentials are returned only for a ready, authorized and entitled profile. Unknown and foreign IDs return 404.
curl 'https://portal.migoip.com/api/customer/v1/dynamic/profiles/{id}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"profile": {
"id": "string",
"tenant_id": "string",
"country": "string",
"mode": "rotating",
"duration_minutes": 1,
"state": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"access_optimized": true,
"connection": {
"username": "string",
"password": "string",
"endpoints": {
"http": {
"host": "string",
"port": 1
},
"socks5": {
"host": "string",
"port": 1
}
}
}
}
}Read one dynamic connection
Required permissions: dynamic:write.
Requires write permission and dynamic:write. Removal is idempotent. Deleting a direct profile removes the saved configuration; it does not rotate shared credentials that were already copied, or refund traffic.
curl 'https://portal.migoip.com/api/customer/v1/dynamic/profiles/{id}' \
--request DELETE \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"revoked": true
}Remove a saved dynamic connection
Required permissions: wallet:read.
Requires wallet:read. Posted balance, current-month spending and latest recharge use the same consistent snapshot as the portal.
curl https://portal.migoip.com/api/customer/v1/wallet/summary \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"balance_fen": "string",
"spent_month_fen": "string",
"month_start": "2026-10-26T05:45:59.177Z",
"month_end": "2026-10-26T05:45:59.177Z",
"last_recharge": {
"id": "string",
"amount_fen": "string",
"channel": "manual",
"created_at": "2026-10-26T05:45:59.177Z"
}
}Read wallet totals
Required permissions: wallet:read.
Requires wallet:read. Pending payment intents are listed separately under recharges.
Integer numbers.
Integer numbers.
Inclusive RFC3339 or YYYY-MM-DD UTC lower bound.
Exclusive RFC3339 or YYYY-MM-DD UTC upper bound. Must be later than from.
curl 'https://portal.migoip.com/api/customer/v1/wallet/ledger?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"tenant_id": "string",
"kind": "recharge",
"channel": "manual",
"direction": "credit",
"amount_fen": "string",
"wallet_delta_fen": "string",
"reason": "string",
"reference_id": "string",
"created_at": "2026-10-26T05:45:59.177Z"
}
],
"total": 0,
"page": 1,
"page_size": 1
}List posted wallet movements
Required permissions: recharges:read.
Requires recharges:read. Availability and exact fees follow deployment payment policy. A method being listed does not imply it is enabled.
curl https://portal.migoip.com/api/customer/v1/recharges/config \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"currency": "CNY",
"mock": true,
"allow_unverified": false,
"can_create": true,
"eligibility_reason": "",
"channels": [
{
"channel": "card",
"enabled": true,
"policy_revision": "string",
"flat_fee_fen": "string",
"fee_bps": "string",
"fee_rounding": "up",
"min_amount_fen": "string",
"max_amount_fen": "string",
"validity_seconds": 1
}
],
"disabled_channels": [
"usdt"
]
}Read available recharge methods
Required permissions: recharges:read.
Requires recharges:read. Only limit, offset and state are accepted, each once. Lists omit actionable payment instructions.
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/recharges?limit=20&offset=0' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"tenant_id": "string",
"actor_id": "string",
"state": "queued",
"version": 1,
"credited": true,
"mock": true,
"channel": "card",
"currency": "CNY",
"policy_revision": "string",
"amount_fen": "string",
"gross_fen": "string",
"fee_fen": "string",
"credit_fen": "string",
"flat_fee_fen": "string",
"fee_bps": "string",
"fee_rounding": "up",
"instructions": {
"kind": "mock",
"reference": "string",
"payment_url": "string"
},
"expires_at": "2026-10-26T05:45:59.177Z",
"created_at": "2026-10-26T05:45:59.177Z"
}
],
"total": 0,
"limit": 1,
"offset": 0
}List payment intents
Required permissions: recharges:write.
Requires write permission and recharges:write. New payments require enabled wallet top-up policy. Creating an intent does not credit the wallet; credit follows verified settlement. Repeat an exact command with the same Idempotency-Key. Legacy asset_units input is accepted only for an existing USDT receipt replay; new USDT commands remain disabled.
Exact replay returns the original result without spending twice; a changed body conflicts.
Exact confirmed consent. Server independently recomputes fresh pricing. Existing exact replay uses its immutable original terms.
Canonical positive CNY fen no greater than 9223372036854775807; validated with exact integer arithmetic.
Canonical positive CNY fen no greater than 9223372036854775807; validated with exact integer arithmetic.
Canonical nonnegative CNY fen no greater than 9223372036854775807; validated with exact integer arithmetic.
Public immutable pricing revision; not a provider configuration revision.
curl https://portal.migoip.com/api/customer/v1/recharges \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"channel": "card",
"amount_fen": "",
"policy_revision": "",
"expected_fee_fen": "",
"expected_credit_fen": ""
}'
{
"id": "string",
"tenant_id": "string",
"actor_id": "string",
"state": "queued",
"version": 1,
"credited": true,
"mock": true,
"channel": "card",
"currency": "CNY",
"policy_revision": "string",
"amount_fen": "string",
"gross_fen": "string",
"fee_fen": "string",
"credit_fen": "string",
"flat_fee_fen": "string",
"fee_bps": "string",
"fee_rounding": "up",
"instructions": {
"kind": "mock",
"reference": "string",
"payment_url": "string"
},
"expires_at": "2026-10-26T05:45:59.177Z",
"created_at": "2026-10-26T05:45:59.177Z"
}Create a recharge payment intent
Required permissions: recharges:read.
Requires recharges:read. Payment instructions, including a card client_secret when applicable, appear only for the owning actor while the intent is actionable. These are sensitive single-payment instructions, not confirmation of payment.
curl 'https://portal.migoip.com/api/customer/v1/recharges/{id}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"id": "string",
"tenant_id": "string",
"actor_id": "string",
"state": "queued",
"version": 1,
"credited": true,
"mock": true,
"channel": "card",
"currency": "CNY",
"policy_revision": "string",
"amount_fen": "string",
"gross_fen": "string",
"fee_fen": "string",
"credit_fen": "string",
"flat_fee_fen": "string",
"fee_bps": "string",
"fee_rounding": "up",
"instructions": {
"kind": "mock",
"reference": "string",
"payment_url": "string"
},
"expires_at": "2026-10-26T05:45:59.177Z",
"created_at": "2026-10-26T05:45:59.177Z"
}Read payment intent and instructions
Required permissions: recharges:read.
Requires recharges:read. Expired uncredited payments have customer display state closed; later verified settlement may still succeed.
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/recharge-history?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"tenant_id": "string",
"kind": "gateway",
"channel": "manual",
"direction": "credit",
"amount_fen": "string",
"credit_fen": "string",
"state": "queued",
"reason": "string",
"created_at": "2026-10-26T05:45:59.177Z"
}
],
"total": 0,
"page": 1,
"page_size": 1
}List recharge and manual adjustment history
Required permissions: metrics:read.
Requires metrics:read. Reports only traffic observed by optimized forwarders. Empty, disabled, stale and unavailable states are distinct from zero traffic. Time windows and sample counts are bounded. Foreign IP IDs return 404 before querying telemetry.
RFC3339 UTC lower bound
RFC3339 UTC upper bound
Requested sample interval in seconds; adapted upward so the graph returns at most 720 points
curl https://portal.migoip.com/api/customer/v1/observability/metrics \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"status": "ready",
"reason": "string",
"observed_at": "2026-10-26T05:45:59.177Z",
"start": "2026-10-26T05:45:59.177Z",
"end": "2026-10-26T05:45:59.177Z",
"step_seconds": 1,
"coverage": "forwarder_only",
"points": [
{
"timestamp": "2026-10-26T05:45:59.177Z",
"upload_bps": 1,
"download_bps": 1,
"active_connections": 1
}
],
"totals": {
"upload_bytes": 1,
"download_bytes": 1
}
}Read workspace metrics
Required permissions: metrics:read.
Requires metrics:read. Reports only traffic observed by optimized forwarders. Empty, disabled, stale and unavailable states are distinct from zero traffic. Time windows and sample counts are bounded. Foreign IP IDs return 404 before querying telemetry.
RFC3339 UTC lower bound
RFC3339 UTC upper bound
Maximum number of events returned on one page
Opaque cursor bound to the original scope
Exact-match protocol filter; no wildcard or pattern syntax
Exact-match transport filter. tcp also selects legacy records stored before the field existed (all prior data plane traffic was TCP-only); udp matches only records that explicitly carry udp
Exact-match outcome filter
Exact-match client source address that must parse as IPv4 or IPv6
Exact-match destination host filter
curl 'https://portal.migoip.com/api/customer/v1/observability/logs?limit=50' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"status": "ready",
"reason": "string",
"observed_at": "2026-10-26T05:45:59.177Z",
"items": [
{
"schema_version": 1,
"event_id": "string",
"timestamp": "2026-10-26T05:45:59.177Z",
"event_type": "connection_open",
"node_id": "string",
"connection_id": "string",
"request_id": "string",
"tenant_id": "string",
"instance_id": "string",
"instance_ip": "string",
"instance_note": "string",
"assignment_id": "string",
"source_ip": "string",
"source_port": 1,
"destination_host": "string",
"destination_ip": "string",
"destination_port": 1,
"upstream_host": "string",
"upstream_port": 1,
"protocol": "http",
"transport": "tcp",
"upload_bytes": 1,
"download_bytes": 1,
"duration_ms": 1,
"outcome": "success",
"failure_stage": "string",
"close_reason": "string",
"http_method": "string",
"http_status": 1
}
],
"next_cursor": "string",
"coverage": "forwarder_only"
}Read workspace logs
Required permissions: metrics:read.
Requires metrics:read. Reports only traffic observed by optimized forwarders. Empty, disabled, stale and unavailable states are distinct from zero traffic. Time windows and sample counts are bounded. Foreign IP IDs return 404 before querying telemetry.
RFC3339 UTC lower bound
RFC3339 UTC upper bound
Requested sample interval in seconds; adapted upward so the graph returns at most 720 points
curl 'https://portal.migoip.com/api/customer/v1/proxies/{id}/observability/metrics' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"status": "ready",
"reason": "string",
"observed_at": "2026-10-26T05:45:59.177Z",
"start": "2026-10-26T05:45:59.177Z",
"end": "2026-10-26T05:45:59.177Z",
"step_seconds": 1,
"coverage": "forwarder_only",
"points": [
{
"timestamp": "2026-10-26T05:45:59.177Z",
"upload_bps": 1,
"download_bps": 1,
"active_connections": 1
}
],
"totals": {
"upload_bytes": 1,
"download_bytes": 1
}
}Read one IP’s metrics
Required permissions: metrics:read.
Requires metrics:read. Reports only traffic observed by optimized forwarders. Empty, disabled, stale and unavailable states are distinct from zero traffic. Time windows and sample counts are bounded. Foreign IP IDs return 404 before querying telemetry.
RFC3339 UTC lower bound
RFC3339 UTC upper bound
Maximum number of events returned on one page
Opaque cursor bound to the original scope
Exact-match protocol filter; no wildcard or pattern syntax
Exact-match transport filter. tcp also selects legacy records stored before the field existed (all prior data plane traffic was TCP-only); udp matches only records that explicitly carry udp
Exact-match outcome filter
Exact-match client source address that must parse as IPv4 or IPv6
Exact-match destination host filter
curl 'https://portal.migoip.com/api/customer/v1/proxies/{id}/observability/logs?limit=50' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"status": "ready",
"reason": "string",
"observed_at": "2026-10-26T05:45:59.177Z",
"items": [
{
"schema_version": 1,
"event_id": "string",
"timestamp": "2026-10-26T05:45:59.177Z",
"event_type": "connection_open",
"node_id": "string",
"connection_id": "string",
"request_id": "string",
"tenant_id": "string",
"instance_id": "string",
"instance_ip": "string",
"instance_note": "string",
"assignment_id": "string",
"source_ip": "string",
"source_port": 1,
"destination_host": "string",
"destination_ip": "string",
"destination_port": 1,
"upstream_host": "string",
"upstream_port": 1,
"protocol": "http",
"transport": "tcp",
"upload_bytes": 1,
"download_bytes": 1,
"duration_ms": 1,
"outcome": "success",
"failure_stage": "string",
"close_reason": "string",
"http_method": "string",
"http_status": 1
}
],
"next_cursor": "string",
"coverage": "forwarder_only"
}Read one IP’s logs
Required permissions: referrals:read.
Requires referrals:read. Only the workspace’s own referral program and masked invitee information are exposed.
curl https://portal.migoip.com/api/customer/v1/referrals \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"tenant_id": "string",
"program_enabled": true,
"can_generate_link": true,
"link": {
"token": "string",
"enabled": true,
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z"
},
"first_order_bps": 1,
"subsequent_order_bps": 1,
"invited_users": 0,
"qualifying_orders": 0,
"earned_fen": "string",
"reversed_fen": "string",
"outstanding_recovery_fen": "string"
}Read referral summary
Required permissions: referrals:write.
Requires write permission and referrals:write. Uses an optimistic version and a durable Idempotency-Key. Signup must be enabled to create or rotate a link; disabling remains available.
Exact replay returns the original result without spending twice; a changed body conflicts.
Integer numbers.
curl https://portal.migoip.com/api/customer/v1/referrals/link \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"action": "create",
"expected_version": 0
}'
{
"tenant_id": "string",
"program_enabled": true,
"can_generate_link": true,
"link": {
"token": "string",
"enabled": true,
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z"
},
"first_order_bps": 1,
"subsequent_order_bps": 1,
"invited_users": 0,
"qualifying_orders": 0,
"earned_fen": "string",
"reversed_fen": "string",
"outstanding_recovery_fen": "string"
}Create, rotate or disable referral link
Required permissions: referrals:read.
Requires referrals:read. Server controls attribution, identity masking and reward amounts.
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/referrals/invitees?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"display_label": "string",
"registered_at": "2026-10-26T05:45:59.177Z",
"created_workspace_count": 0,
"qualifying_orders": 0,
"earned_fen": "string",
"reversed_fen": "string"
}
],
"total": 0,
"page": 1,
"page_size": 1
}List referral invitees
Required permissions: referrals:read.
Requires referrals:read. Server controls attribution, identity masking and reward amounts.
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/referrals/rewards?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"invitee_label": "string",
"source_kind": "static_purchase",
"source_reference": "string",
"attribution_source": "workspace_creator",
"rate_bps": 0,
"eligible_paid_fen": "string",
"earned_fen": "string",
"reversed_fen": "string",
"outstanding_recovery_fen": "string",
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z"
}
],
"total": 0,
"page": 1,
"page_size": 1
}List referral rewards
Required permissions: webhooks:read.
Requires webhooks:read. Includes disabled/deleted subscriptions for delivery history. Signing secrets are omitted.
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/webhooks?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"name": "string",
"url": "https://example.com",
"event_types": [
"fulfillment.updated"
],
"enabled": true,
"wallet_low_balance_threshold_fen": null,
"id": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z",
"disabled_at": null
}
],
"total": 0,
"page": 1,
"page_size": 1
}List webhook subscriptions
Required permissions: webhooks:write.
Requires write permission and webhooks:write. Maximum 10 enabled subscriptions per workspace. Idempotency-Key is required; exact replay returns the same subscription. Copy the secret securely. Only later committed changes are captured; no historical backfill.
Exact replay returns the original result without spending twice; a changed body conflicts.
HTTPS, port 443 only, no credentials or fragment. Each delivery resolves and pins a public address; private, special and mixed public/private DNS answers are refused.
Exact CNY fen; required when wallet.low_balance is selected, null otherwise. Maximum 9007199254740992.
curl https://portal.migoip.com/api/customer/v1/webhooks \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"name": "",
"url": "",
"event_types": [
"fulfillment.updated"
],
"enabled": true,
"wallet_low_balance_threshold_fen": null
}'
{
"webhook": {
"name": "string",
"url": "https://example.com",
"event_types": [
"fulfillment.updated"
],
"enabled": true,
"wallet_low_balance_threshold_fen": null,
"id": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z",
"disabled_at": null
},
"secret": "string"
}Create a webhook subscription
Required permissions: webhooks:read.
Requires webhooks:read. Foreign IDs return 404.
curl 'https://portal.migoip.com/api/customer/v1/webhooks/{id}' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"webhook": {
"name": "string",
"url": "https://example.com",
"event_types": [
"fulfillment.updated"
],
"enabled": true,
"wallet_low_balance_threshold_fen": null,
"id": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z",
"disabled_at": null
}
}Read a webhook subscription
Required permissions: webhooks:write.
Requires write permission and webhooks:write. Supply current version; stale version returns 409. Omitted fields are unchanged. Remove wallet.low_balance and set its threshold to null together. Deleted subscriptions cannot be re-enabled.
Integer numbers.
HTTPS, port 443 only, no credentials or fragment. Each delivery resolves and pins a public address; private, special and mixed public/private DNS answers are refused.
Exact CNY fen; required when wallet.low_balance is selected, null otherwise. Maximum 9007199254740992.
curl 'https://portal.migoip.com/api/customer/v1/webhooks/{id}' \
--request PATCH \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"name": "",
"url": "",
"event_types": [
"fulfillment.updated"
],
"enabled": true,
"wallet_low_balance_threshold_fen": null,
"version": 1
}'
{
"webhook": {
"name": "string",
"url": "https://example.com",
"event_types": [
"fulfillment.updated"
],
"enabled": true,
"wallet_low_balance_threshold_fen": null,
"id": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z",
"disabled_at": null
}
}Update a webhook subscription
Required permissions: webhooks:write.
Requires write permission and webhooks:write. Soft deletion retains history and cancels pending deliveries. Repeated deletion is harmless. Already dispatched network requests may still arrive.
curl 'https://portal.migoip.com/api/customer/v1/webhooks/{id}' \
--request DELETE \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"webhook": {
"name": "string",
"url": "https://example.com",
"event_types": [
"fulfillment.updated"
],
"enabled": true,
"wallet_low_balance_threshold_fen": null,
"id": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z",
"disabled_at": null
}
}Delete a webhook subscription
Required permissions: webhooks:write.
Requires write permission and webhooks:write. Returns a fresh secret, replacing the previous one for subsequent attempts. This command is not idempotent: do not automatically repeat an uncertain response. An in-flight delivery can still carry the prior signature. If the response is lost, explicitly rotate again and install that new secret.
curl 'https://portal.migoip.com/api/customer/v1/webhooks/{id}/rotate-secret' \
--request POST \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"webhook": {
"name": "string",
"url": "https://example.com",
"event_types": [
"fulfillment.updated"
],
"enabled": true,
"wallet_low_balance_threshold_fen": null,
"id": "string",
"version": 1,
"created_at": "2026-10-26T05:45:59.177Z",
"updated_at": "2026-10-26T05:45:59.177Z",
"disabled_at": null
},
"secret": "string"
}Rotate webhook signing secret
Required permissions: webhooks:read.
Requires webhooks:read. Events are delivered at least once and may arrive out of order. Deduplicate using event_id. Failed deliveries stop automatically after 8 attempts per round; up to 3 manual retry rounds are allowed.
Integer numbers.
Integer numbers.
curl 'https://portal.migoip.com/api/customer/v1/webhooks/{id}/deliveries?page=1&page_size=20' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"items": [
{
"id": "string",
"event_id": "string",
"event_type": "fulfillment.updated",
"state": "pending",
"attempts": 1,
"max_attempts": 1,
"manual_retries": 0,
"attempt_budget": 1,
"next_attempt_at": null,
"last_attempt_at": null,
"last_status_code": null,
"last_error_code": "string",
"delivered_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"payload": {
"service_id": "string",
"status": "fulfilled",
"expires_at": null,
"activated_at": "2026-10-26T05:45:59.177Z",
"order_id": null
}
}
],
"total": 0,
"page": 1,
"page_size": 1
}List delivery history
Required permissions: webhooks:write.
Requires write permission and webhooks:write. Only failed deliveries on enabled subscriptions can be retried. Required Idempotency-Key makes exact replay a no-op. Creates one additional bounded retry round, retaining the same event ID.
Exact replay returns the original result without spending twice; a changed body conflicts.
curl 'https://portal.migoip.com/api/customer/v1/webhooks/{id}/deliveries/{delivery}/retry' \
--request POST \
--header 'Idempotency-Key: ' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
"delivery": {
"id": "string",
"event_id": "string",
"event_type": "fulfillment.updated",
"state": "pending",
"attempts": 1,
"max_attempts": 1,
"manual_retries": 0,
"attempt_budget": 1,
"next_attempt_at": null,
"last_attempt_at": null,
"last_status_code": null,
"last_error_code": "string",
"delivered_at": null,
"created_at": "2026-10-26T05:45:59.177Z",
"payload": {
"service_id": "string",
"status": "fulfilled",
"expires_at": null,
"activated_at": "2026-10-26T05:45:59.177Z",
"order_id": null
}
}
}Retry a failed delivery