---
title: "Buy traffic from the wallet balance (API and MCP)"
method: POST
path: "/v1/traffic/buy"
tags: ["traffic"]
---

# Buy traffic from the wallet balance (API and MCP)

`POST /v1/traffic/buy`

## Request

- Base URL: `https://api.portproof.org`
- URL: `https://api.portproof.org/v1/traffic/buy`
- Auth: one of:
  - API key in cookie `pp_session`
  - HTTP bearer

Creates and pays an order for `gb` whole GB (or the one-off trial) from the wallet; the price comes from the tier table for the ordered quantity, the client never sends a price. `accept_terms: true` is required, as at checkout: it records that the customer accepts the terms and the acceptable-use policy and asks for the service to start at once (optional `terms_version` names the version shown). Requires an `Idempotency-Key` header: the same key with the same body replays the same order, the same key with a different body is 409 `idempotency_conflict`. With an API key a refused purchase is kept under its key for 24 h as well, so after fixing the cause (for example a top-up) send a new key. An API key needs the `ports:write` scope. 402 `insufficient_funds` when the wallet is too low, 402 `kyb_required_for_volume` above the monthly volume for unverified organisations, 403 `account_suspended` when traffic is paused on the account, 409 `trial_already_used`, 409 `launch_waitlist` while `LAUNCH_MODE=waitlist`.

## Request body

- object
  - `gb` integer
  - `trial` boolean
  - `accept_terms` true, required
  - `terms_version` string

## Response `201`

Default Response

- object
  - `order` object, required
    - `id` string, required
    - `number` string, required
    - `customer_id` string, required
    - `org_id` string, required
    - `status` 'draft' | 'awaiting_payment' | 'awaiting_kyb' | 'paid' | 'provisioning' | 'fulfilled' | 'partially_fulfilled' | 'failed_refunded' | 'cancelled' | 'refunded', required
    - `subtotal_cents` integer, required
    - `discount_cents` integer, required
    - `vat_rate_bps` integer, required
    - `vat_cents` integer, required
    - `total_cents` integer, required
    - `currency` 'EUR' | 'USD', required
    - `payment_method` 'stripe' | 'coingate' | 'nowpayments' | 'wallet' | 'bank_transfer' | 'mock', required
    - `coupon_code` string, nullable, required
    - `items` object[], required
      - `id` string, required
      - `product_id` string, required
      - `sku_snapshot` object, required
        - `sku` string, required
        - `kind` 'port' | 'bandwidth' | 'topup' | 'sms' | 'esim', required
        - `title` string, required
        - `country` string, nullable, required
        - `carrier_hint` string, nullable, required
        - `term` 'monthly' | 'weekly' | 'daily' | 'gb' | 'none', required
        - `sell_cents` integer, required
        - `currency` 'EUR' | 'USD', required
        - `evidence` 'signed' | 'observed', required
        - `operator_label` string, required
        - `supply_kind` 'owned' | 'generic_pool' | 'mock', required
      - `quantity` integer, required
      - `unit_cents` integer, required
      - `total_cents` integer, required
      - `status` 'pending' | 'provisioning' | 'fulfilled' | 'failed' | 'refunded' | 'held', required
      - `fulfilment_ref` string, nullable, required
      - `attempts` integer, required
      - `last_error` string, nullable
      - `customer_reason` string, nullable
      - `resource_url` string, nullable, required
      - `credentials` object, nullable, required
        - `host` string, required
        - `http_port` integer, nullable, required
        - `socks_port` integer, nullable, required
        - `username` string, required
        - `password` string, required
        - `expires_at` string, date-time, nullable, required
        - `http` object
          - `host` string, required
          - `port` integer, required
          - `username` string, required
          - `password` string, required
        - `socks5` object
          - `host` string, required
          - `port` integer, required
          - `username` string, required
          - `password` string, required
      - `units` object[]
        - `unit` integer, required
        - `port_id` string, required
        - `resource_url` string, nullable, required
        - `credentials` object, nullable, required
          - `host` string, required
          - `http_port` integer, nullable, required
          - `socks_port` integer, nullable, required
          - `username` string, required
          - `password` string, required
          - `expires_at` string, date-time, nullable, required
          - `http` object
            - `host` string, required
            - `port` integer, required
            - `username` string, required
            - `password` string, required
          - `socks5` object
            - `host` string, required
            - `port` integer, required
            - `username` string, required
            - `password` string, required
      - `updated_at` string, date-time, required
    - `paid_at` string, date-time, nullable, required
    - `notes` string, nullable, required
    - `invoice_url` string, nullable, required
    - `payment_url` string, uri, nullable
    - `analytics_ref` string, nullable
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
  - `payment_id` string, required

## Other responses

- `400`: Default Response
- `401`: Default Response
- `402`: Default Response
- `403`: Default Response
- `409`: Default Response

---

[API](https://skmtc.dev/portproof/apis/portproof-api.md) · [All operations](https://skmtc.dev/portproof/apis/portproof-api/llms.txt) · [OpenAPI document](https://skmtc.dev/portproof/apis/portproof-api/revisions/4143916c0fac?raw)
