openapi: 3.0.3
info:
  title: P2PSDK Control Plane API
  version: 1.0.0
  description: Public HTTP API for authentication, profile management, client applications, analytics, billing, news, webhooks, account API keys, sub-users, data transactions, and proxy targeting. Every endpoint accepts an optional `X-Request-ID` request header and returns the final request id in the `X-Request-ID` response header.
servers:
  - url: https://staging-api.papaproxy.com
    description: Sandbox
security:
  - BearerAuth: []
tags:
  - name: Authentication
    description: Authentication and token endpoints.
  - name: Profile
    description: Authenticated profile endpoints.
  - name: Account API Keys
    description: Account-level static API key endpoints.
  - name: Apps
    description: Seller application review and runtime app endpoints.
  - name: Users
    description: Owned buyer user management endpoints.
  - name: Data Transactions
    description: Data balance audit endpoints.
  - name: Analytics
    description: Usage and seller revenue analytics endpoints.
  - name: Locations
    description: Proxy targeting location catalog endpoints.
  - name: Billing
    description: Buyer pricing, purchase invoice, and seller payout endpoints.
  - name: Webhooks
    description: Webhook subscription endpoints.
  - name: News
    description: Service news endpoints.
  - name: Proxy Network
    description: Proxy servers and targeting metadata endpoints.
paths:
  /api/v1/analytics/bandwidth-revenue:
    get:
      operationId: getBandwidthRevenue
      tags:
        - Analytics
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedBandwidthRevenueList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Bandwidth Revenue
      description: Usage and seller revenue analytics endpoints.
  /api/v1/analytics/domains:
    get:
      operationId: getDomainAnalytics
      tags:
        - Analytics
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedDomainAnalyticsList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Domain Analytics
      description: Usage and seller revenue analytics endpoints.
  /api/v1/analytics/ips:
    get:
      operationId: getIpAnalytics
      tags:
        - Analytics
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedIpAnalyticsList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Ip Analytics
      description: Usage and seller revenue analytics endpoints.
  /api/v1/analytics/logs:
    get:
      operationId: getRequestLogs
      tags:
        - Analytics
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedRequestLogList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Request Logs
      description: Usage and seller revenue analytics endpoints.
  /api/v1/analytics/overall:
    get:
      operationId: getOverallAnalytics
      tags:
        - Analytics
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedOverallAnalyticsList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Overall Analytics
      description: Usage and seller revenue analytics endpoints.
  /api/v1/analytics/qualified-leads:
    get:
      operationId: getQualifiedLeads
      tags:
        - Analytics
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedQualifiedLeadList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Qualified Leads
      description: Usage and seller revenue analytics endpoints.
  /api/v1/analytics/qualified-revenue:
    get:
      operationId: getQualifiedRevenue
      tags:
        - Analytics
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedQualifiedRevenueList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Qualified Revenue
      description: Usage and seller revenue analytics endpoints.
  /api/v1/api-keys:
    get:
      operationId: listAccountApiKeys
      parameters:
        - $ref: '#/components/parameters/PaginatedLimitQuery'
        - $ref: '#/components/parameters/OffsetQuery'
        - $ref: '#/components/parameters/SearchQuery'
      tags:
        - Account API Keys
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedAPIKeyList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Account Api Keys
      description: Account-level static API key endpoints.
    post:
      operationId: createAccountApiKey
      tags:
        - Account API Keys
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/APIKeyRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/APIKeyRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/APIKeyRequest'
      security:
        - BearerAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIKey'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Create Account Api Key
      description: Account-level static API key endpoints.
  /api/v1/api-keys/{id}:
    patch:
      operationId: updateAccountApiKey
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Account API Keys
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedAPIKeyUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedAPIKeyUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedAPIKeyUpdateRequest'
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIKeyUpdate'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Update Account Api Key
      description: Account-level static API key endpoints.
    delete:
      operationId: deleteAccountApiKey
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Account API Keys
      security:
        - BearerAuth: []
      responses:
        '204':
          description: No response body
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Delete Account Api Key
      description: Account-level static API key endpoints.
  /api/v1/apps:
    get:
      operationId: listApps
      parameters:
        - $ref: '#/components/parameters/PaginatedLimitQuery'
        - $ref: '#/components/parameters/OffsetQuery'
        - $ref: '#/components/parameters/SearchQuery'
        - $ref: '#/components/parameters/AppPayoutTypeQuery'
      tags:
        - Apps
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedAppList'
              examples:
                AppsListResponse:
                  value:
                    count: 123
                    next: http://api.example.org/accounts/?offset=400&limit=100
                    previous: http://api.example.org/accounts/?offset=200&limit=100
                    results:
                      - id: 550e8400-e29b-41d4-a716-446655440000
                        name: Mobile VPN
                        key: key_example1234567890
                        application_type: android
                        programming_language: kotlin
                        application_url: https://play.google.com/store/apps/details?id=com.example.vpn
                        comment: Initial review notes for the app.
                        status: review
                        payout_type: dau
                        country_payout_prices:
                          au: 17
                          ca: 18
                          de: 16
                          gb: 18
                          us: 20
                        payout_period_days: 30
                        paid_out_cents: 0
                        limit_mbps: 0
                        connection_limit: 0
                        created: '2026-07-01T12:00:00Z'
                        updated: '2026-07-01T12:00:00Z'
                  summary: Apps list response
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Apps
      description: Seller application review and runtime app endpoints.
    post:
      operationId: createApp
      tags:
        - Apps
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppCreateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AppCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AppCreateRequest'
        required: true
      security:
        - BearerAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/App'
              examples:
                CreatedAppResponse:
                  value:
                    id: 550e8400-e29b-41d4-a716-446655440000
                    name: Mobile VPN
                    key: key_example1234567890
                    application_type: android
                    programming_language: kotlin
                    application_url: https://play.google.com/store/apps/details?id=com.example.vpn
                    comment: Initial review notes for the app.
                    status: review
                    payout_type: dau
                    country_payout_prices:
                      au: 17
                      ca: 18
                      de: 16
                      gb: 18
                      us: 20
                    payout_period_days: 30
                    paid_out_cents: 0
                    limit_mbps: 0
                    connection_limit: 0
                    created: '2026-07-01T12:00:00Z'
                    updated: '2026-07-01T12:00:00Z'
                  summary: Created app response
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Create App
      description: Seller application review and runtime app endpoints.
  /api/v1/apps/{id}:
    get:
      operationId: getApp
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Apps
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/App'
              examples:
                AppResponse:
                  value:
                    id: 550e8400-e29b-41d4-a716-446655440000
                    name: Mobile VPN
                    key: key_example1234567890
                    application_type: android
                    programming_language: kotlin
                    application_url: https://play.google.com/store/apps/details?id=com.example.vpn
                    comment: Initial review notes for the app.
                    status: review
                    payout_type: dau
                    country_payout_prices:
                      au: 17
                      ca: 18
                      de: 16
                      gb: 18
                      us: 20
                    payout_period_days: 30
                    paid_out_cents: 0
                    limit_mbps: 0
                    connection_limit: 0
                    created: '2026-07-01T12:00:00Z'
                    updated: '2026-07-01T12:00:00Z'
                  summary: App response
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Get App
      description: Seller application review and runtime app endpoints.
    put:
      operationId: putReviewApp
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Apps
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppReviewUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AppReviewUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AppReviewUpdateRequest'
        required: true
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/App'
              examples:
                AppResponse:
                  value:
                    id: 550e8400-e29b-41d4-a716-446655440000
                    name: Mobile VPN
                    key: key_example1234567890
                    application_type: android
                    programming_language: kotlin
                    application_url: https://play.google.com/store/apps/details?id=com.example.vpn
                    comment: Initial review notes for the app.
                    status: review
                    payout_type: dau
                    country_payout_prices:
                      au: 17
                      ca: 18
                      de: 16
                      gb: 18
                      us: 20
                    payout_period_days: 30
                    paid_out_cents: 0
                    limit_mbps: 0
                    connection_limit: 0
                    created: '2026-07-01T12:00:00Z'
                    updated: '2026-07-01T12:00:00Z'
                  summary: App response
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Put Review App
      description: Seller application review and runtime app endpoints.
    patch:
      operationId: updateReviewApp
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Apps
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedAppReviewUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedAppReviewUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedAppReviewUpdateRequest'
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/App'
              examples:
                AppResponse:
                  value:
                    id: 550e8400-e29b-41d4-a716-446655440000
                    name: Mobile VPN
                    key: key_example1234567890
                    application_type: android
                    programming_language: kotlin
                    application_url: https://play.google.com/store/apps/details?id=com.example.vpn
                    comment: Initial review notes for the app.
                    status: review
                    payout_type: dau
                    country_payout_prices:
                      au: 17
                      ca: 18
                      de: 16
                      gb: 18
                      us: 20
                    payout_period_days: 30
                    paid_out_cents: 0
                    limit_mbps: 0
                    connection_limit: 0
                    created: '2026-07-01T12:00:00Z'
                    updated: '2026-07-01T12:00:00Z'
                  summary: App response
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Update Review App
      description: Seller application review and runtime app endpoints.
    delete:
      operationId: deleteReviewApp
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Apps
      security:
        - BearerAuth: []
      responses:
        '204':
          description: No response body
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Delete Review App
      description: Seller application review and runtime app endpoints.
  /api/v1/auth/social/{provider}:
    post:
      operationId: socialAuth
      parameters:
        - in: path
          name: provider
          schema:
            type: string
          required: true
      tags:
        - Authentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SocialAuthRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/SocialAuthRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/SocialAuthRequest'
        required: true
      security:
        - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenPair'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenPair'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Social Auth
      description: Authentication and token endpoints.
  /api/v1/auth/social/providers:
    get:
      operationId: listSocialAuthProviders
      tags:
        - Authentication
      security:
        - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SocialAuthProviders'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Social Auth Providers
      description: Authentication and token endpoints.
  /api/v1/data-transactions:
    get:
      operationId: listDataTransactions
      parameters:
        - in: query
          name: end
          schema:
            type: string
            minLength: 1
        - in: query
          name: limit
          schema:
            type: integer
            maximum: 1000
            minimum: 1
        - in: query
          name: offset
          schema:
            type: integer
            minimum: 0
        - in: query
          name: start
          schema:
            type: string
            minLength: 1
        - in: query
          name: timezone
          schema:
            type: string
            minLength: 1
        - in: query
          name: user_id
          schema:
            type: array
            items:
              type: string
              format: uuid
        - $ref: '#/components/parameters/SearchQuery'
        - $ref: '#/components/parameters/DataTransactionTypeQuery'
      tags:
        - Data Transactions
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaginatedDataTransactionList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Data Transactions
      description: Data balance audit endpoints.
  /api/v1/invoices:
    get:
      operationId: listDataPurchaseInvoices
      description: Lists invoices owned by the authenticated top-level buyer. Use this endpoint to show purchase history, pending hosted checkout links, provider errors, and paid invoices that already credited data to the buyer balance.
      summary: List buyer data purchase invoices
      parameters:
        - in: query
          name: gateway
          schema:
            type: string
            title: Payment gateway
            enum:
              - adyen
              - coinbase
              - coingate
              - cryptomus
              - manual
              - mollie
              - nowpayments
              - paypal
              - stripe
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Payment provider selected for this invoice.</p></div>

            * `stripe` - Stripe
            * `paypal` - PayPal
            * `coinbase` - Coinbase Commerce
            * `cryptomus` - Cryptomus
            * `coingate` - CoinGate
            * `nowpayments` - NOWPayments
            * `adyen` - Adyen
            * `mollie` - Mollie
            * `manual` - Manual
        - name: ordering
          required: false
          in: query
          description: Which field to use when ordering the results.
          schema:
            type: string
        - in: query
          name: pricing_mode
          schema:
            type: string
            enum:
              - dynamic
              - fixed
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Pricing mode snapshot used when the invoice was created.</p></div>

            * `fixed` - Fixed packages
            * `dynamic` - Dynamic tiers
        - in: query
          name: status
          schema:
            type: string
            enum:
              - canceled
              - error
              - paid
              - pending
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Payment and fulfillment lifecycle status.</p></div>

            * `pending` - Pending
            * `paid` - Paid
            * `error` - Error
            * `canceled` - Canceled
        - $ref: '#/components/parameters/PaginatedLimitQuery'
        - $ref: '#/components/parameters/OffsetQuery'
        - $ref: '#/components/parameters/SearchQuery'
      tags:
        - Billing
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedDataPurchaseInvoiceList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
    post:
      operationId: createDataPurchaseInvoice
      description: Creates an invoice for a top-level buyer from the active pricing configuration and initializes a hosted checkout session with the selected payment gateway. The response includes payment_url, so clients can redirect the buyer without making an additional payment-link request.
      summary: Create buyer data purchase invoice
      tags:
        - Billing
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDataPurchaseInvoiceRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateDataPurchaseInvoiceRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateDataPurchaseInvoiceRequest'
        required: true
      security:
        - BearerAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataPurchaseInvoice'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /api/v1/invoices/{id}:
    get:
      operationId: getDataPurchaseInvoice
      description: Returns one buyer-owned data purchase invoice with its pricing snapshot, payment status, payment_url, provider status, error message, and fulfillment timestamps.
      summary: Get buyer data purchase invoice
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Billing
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataPurchaseInvoice'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
  /api/v1/locations/asns:
    get:
      operationId: listLocationAsns
      parameters:
        - in: query
          name: city
          schema:
            type: string
        - in: query
          name: country
          schema:
            type: string
            minLength: 1
          required: true
        - in: query
          name: limit
          schema:
            type: integer
            maximum: 1000
            minimum: 1
            default: 100
        - in: query
          name: offset
          schema:
            type: integer
            minimum: 0
            default: 0
        - in: query
          name: os_type
          schema:
            enum:
              - android
              - ios
              - linux
              - macos
              - windows
              - other
              - ''
            type: string
          description: |-
            * `android` - android
            * `ios` - ios
            * `linux` - linux
            * `macos` - macos
            * `windows` - windows
            * `other` - other
        - in: query
          name: region
          schema:
            type: string
        - in: query
          name: search
          schema:
            type: string
      tags:
        - Locations
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationAsnPage'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Location Asns
      description: Proxy targeting location catalog endpoints.
  /api/v1/locations/cities:
    get:
      operationId: listLocationCities
      parameters:
        - in: query
          name: country
          schema:
            type: string
        - in: query
          name: limit
          schema:
            type: integer
            maximum: 1000
            minimum: 1
            default: 100
        - in: query
          name: offset
          schema:
            type: integer
            minimum: 0
            default: 0
        - in: query
          name: os_type
          schema:
            enum:
              - android
              - ios
              - linux
              - macos
              - windows
              - other
              - ''
            type: string
          description: |-
            * `android` - android
            * `ios` - ios
            * `linux` - linux
            * `macos` - macos
            * `windows` - windows
            * `other` - other
        - in: query
          name: region
          schema:
            type: string
        - in: query
          name: search
          schema:
            type: string
      tags:
        - Locations
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationCityPage'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Location Cities
      description: Proxy targeting location catalog endpoints.
  /api/v1/locations/countries:
    get:
      operationId: listLocationCountries
      parameters:
        - in: query
          name: limit
          schema:
            type: integer
            maximum: 1000
            minimum: 1
            default: 100
        - in: query
          name: offset
          schema:
            type: integer
            minimum: 0
            default: 0
        - in: query
          name: os_type
          schema:
            enum:
              - android
              - ios
              - linux
              - macos
              - windows
              - other
              - ''
            type: string
          description: |-
            * `android` - android
            * `ios` - ios
            * `linux` - linux
            * `macos` - macos
            * `windows` - windows
            * `other` - other
        - in: query
          name: search
          schema:
            type: string
      tags:
        - Locations
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationCountryPage'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Location Countries
      description: Proxy targeting location catalog endpoints.
  /api/v1/locations/regions:
    get:
      operationId: listLocationRegions
      parameters:
        - in: query
          name: country
          schema:
            type: string
        - in: query
          name: limit
          schema:
            type: integer
            maximum: 1000
            minimum: 1
            default: 100
        - in: query
          name: offset
          schema:
            type: integer
            minimum: 0
            default: 0
        - in: query
          name: os_type
          schema:
            enum:
              - android
              - ios
              - linux
              - macos
              - windows
              - other
              - ''
            type: string
          description: |-
            * `android` - android
            * `ios` - ios
            * `linux` - linux
            * `macos` - macos
            * `windows` - windows
            * `other` - other
        - in: query
          name: search
          schema:
            type: string
      tags:
        - Locations
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationRegionPage'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Location Regions
      description: Proxy targeting location catalog endpoints.
  /api/v1/locations/zips:
    get:
      operationId: listLocationZips
      parameters:
        - in: query
          name: city
          schema:
            type: string
        - in: query
          name: country
          schema:
            type: string
            minLength: 1
          required: true
        - in: query
          name: limit
          schema:
            type: integer
            maximum: 1000
            minimum: 1
            default: 100
        - in: query
          name: offset
          schema:
            type: integer
            minimum: 0
            default: 0
        - in: query
          name: os_type
          schema:
            enum:
              - android
              - ios
              - linux
              - macos
              - windows
              - other
              - ''
            type: string
          description: |-
            * `android` - android
            * `ios` - ios
            * `linux` - linux
            * `macos` - macos
            * `windows` - windows
            * `other` - other
        - in: query
          name: region
          schema:
            type: string
        - in: query
          name: search
          schema:
            type: string
      tags:
        - Locations
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationZipPage'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Location Zips
      description: Proxy targeting location catalog endpoints.
  /api/v1/login:
    post:
      operationId: login
      tags:
        - Authentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlexibleAuthTokenObtainRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FlexibleAuthTokenObtainRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FlexibleAuthTokenObtainRequest'
        required: true
      security:
        - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenPair'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Login
      description: Authentication and token endpoints.
  /api/v1/news:
    get:
      operationId: listNews
      parameters:
        - $ref: '#/components/parameters/PaginatedLimitQuery'
        - $ref: '#/components/parameters/OffsetQuery'
      tags:
        - News
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedNewsList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List News
      description: Service news endpoints.
  /api/v1/password-reset:
    post:
      operationId: requestPasswordReset
      tags:
        - Authentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordResetRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PasswordResetRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PasswordResetRequestRequest'
        required: true
      security:
        - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasswordResetRequest'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Request Password Reset
      description: Authentication and token endpoints.
  /api/v1/password-reset/confirm:
    post:
      operationId: confirmPasswordReset
      tags:
        - Authentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordResetConfirmRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PasswordResetConfirmRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PasswordResetConfirmRequest'
        required: true
      security:
        - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasswordResetConfirm'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Confirm Password Reset
      description: Authentication and token endpoints.
  /api/v1/payouts:
    get:
      operationId: listPayouts
      parameters:
        - in: query
          name: app
          schema:
            type: string
            format: uuid
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
        - name: ordering
          required: false
          in: query
          description: Supported fields are `id`, `app`, `payout`, `status`, `amount_cents`, `crypto_currency`, `wallet_address`, `paypal_email`, `bank_account_details`, `transaction_id`, `period_start`, `period_end`, `reason`, `created`, and `updated`.
          schema:
            type: string
        - in: query
          name: status
          schema:
            type: string
            enum:
              - canceled
              - completed
              - processing
              - requested
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Operational payout lifecycle controlled by API requests and admin processing.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">requested</code><span class="text-xs text-gray-400">waiting for admin review</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">processing</code><span class="text-xs text-gray-400">being paid</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">completed</code><span class="text-xs text-gray-400">paid and accounted</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">canceled</code><span class="text-xs text-gray-400">rejected with reason</span></div></div>

            * `requested` - Requested
            * `processing` - Processing
            * `completed` - Completed
            * `canceled` - Canceled
        - $ref: '#/components/parameters/PaginatedLimitQuery'
        - $ref: '#/components/parameters/OffsetQuery'
        - $ref: '#/components/parameters/SearchQuery'
        - $ref: '#/components/parameters/PayoutMethodQuery'
      tags:
        - Billing
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedPayoutList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Payouts
      description: Buyer pricing, purchase invoice, and seller payout endpoints.
    post:
      operationId: createPayout
      tags:
        - Billing
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePayoutRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreatePayoutRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreatePayoutRequest'
        required: true
      security:
        - BearerAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payout'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Create Payout
      description: Buyer pricing, purchase invoice, and seller payout endpoints.
  /api/v1/payouts/{id}:
    get:
      operationId: getPayout
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Billing
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payout'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Get Payout
      description: Buyer pricing, purchase invoice, and seller payout endpoints.
  /api/v1/payouts/quote:
    get:
      operationId: getPayoutQuote
      parameters:
        - in: query
          name: app
          schema:
            type: string
            format: uuid
          required: true
      tags:
        - Billing
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutQuote'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Payout Quote
      description: Buyer pricing, purchase invoice, and seller payout endpoints.
  /api/v1/pricing:
    get:
      operationId: getDataPricing
      description: Returns the currently active site-wide data pricing catalog for top-level buyer accounts. The response describes whether buyers must choose from fixed traffic packages or enter a traffic amount priced by dynamic tiers. Use this endpoint before creating a data purchase invoice.
      summary: Get buyer data pricing
      tags:
        - Billing
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DataPricingCatalog'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /api/v1/pricing/quote:
    get:
      operationId: quoteDataPricing
      description: Calculates the exact price and data amount for a prospective buyer data purchase without creating an invoice. Fixed pricing requires package_id. Dynamic pricing requires traffic_gb. The returned values are the same pricing snapshot used when an invoice is created.
      summary: Quote buyer data pricing
      parameters:
        - in: query
          name: package_id
          schema:
            type: string
            minLength: 1
        - in: query
          name: traffic_gb
          schema:
            type: integer
            minimum: 1
      tags:
        - Billing
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataPricingQuote'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /api/v1/profile:
    get:
      operationId: getProfile
      tags:
        - Profile
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Profile
      description: Authenticated profile endpoints.
    patch:
      operationId: updateProfile
      tags:
        - Profile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedUserRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedUserRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedUserRequest'
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Update Profile
      description: Authenticated profile endpoints.
  /api/v1/profile/rotate-proxy-password:
    post:
      operationId: rotateProfileProxyPassword
      tags:
        - Profile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UserRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UserRequest'
        required: true
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Rotate Profile Proxy Password
      description: Authenticated profile endpoints.
  /api/v1/refresh:
    post:
      operationId: refreshToken
      tags:
        - Authentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/RefreshRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/RefreshRequestRequest'
        required: true
      security:
        - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenPair'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Refresh Token
      description: Authentication and token endpoints.
  /api/v1/servers:
    get:
      operationId: listProxyServers
      parameters:
        - $ref: '#/components/parameters/PaginatedLimitQuery'
        - $ref: '#/components/parameters/OffsetQuery'
        - $ref: '#/components/parameters/SearchQuery'
      tags:
        - Proxy Network
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedProxyServerList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Proxy Servers
      description: Proxy servers and targeting metadata endpoints.
  /api/v1/signup:
    post:
      operationId: signup
      tags:
        - Authentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignUpRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/SignUpRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/SignUpRequest'
        required: true
      security:
        - {}
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignUp'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Signup
      description: Authentication and token endpoints.
  /api/v1/targeting-options:
    get:
      operationId: getTargetingOptions
      tags:
        - Proxy Network
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Get Targeting Options
      description: Proxy servers and targeting metadata endpoints.
  /api/v1/users:
    get:
      operationId: listUsers
      parameters:
        - $ref: '#/components/parameters/PaginatedLimitQuery'
        - $ref: '#/components/parameters/OffsetQuery'
        - $ref: '#/components/parameters/SearchQuery'
      tags:
        - Users
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedManagedUserList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Users
      description: Owned buyer user management endpoints.
    post:
      operationId: createUser
      tags:
        - Users
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSubUserRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateSubUserRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateSubUserRequest'
        required: true
      security:
        - BearerAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubUser'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Create User
      description: Owned buyer user management endpoints.
  /api/v1/users/{id}:
    get:
      operationId: getUser
      parameters:
        - in: path
          name: id
          schema:
            type: string
            format: uuid
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Users
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubUser'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Get User
      description: Owned buyer user management endpoints.
    patch:
      operationId: updateUser
      parameters:
        - in: path
          name: id
          schema:
            type: string
            format: uuid
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Users
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedUpdateSubUserRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedUpdateSubUserRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedUpdateSubUserRequest'
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubUser'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Update User
      description: Owned buyer user management endpoints.
    delete:
      operationId: deleteUser
      parameters:
        - in: path
          name: id
          schema:
            type: string
            format: uuid
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Users
      security:
        - BearerAuth: []
      responses:
        '204':
          description: No response body
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Delete User
      description: Owned buyer user management endpoints.
  /api/v1/users/{id}/data:
    post:
      operationId: changeUserData
      parameters:
        - in: path
          name: id
          schema:
            type: string
            format: uuid
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Users
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangeSubUserDataRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ChangeSubUserDataRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ChangeSubUserDataRequest'
        required: true
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubUser'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Change User Data
      description: Owned buyer user management endpoints.
  /api/v1/users/{id}/rotate-proxy-password:
    post:
      operationId: rotateManagedUserProxyPassword
      parameters:
        - in: path
          name: id
          schema:
            type: string
            format: uuid
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Users
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubUser'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Rotate Managed User Proxy Password
      description: Owned buyer user management endpoints.
  /api/v1/webhooks:
    get:
      operationId: listWebhooks
      parameters:
        - $ref: '#/components/parameters/PaginatedLimitQuery'
        - $ref: '#/components/parameters/OffsetQuery'
        - $ref: '#/components/parameters/SearchQuery'
      tags:
        - Webhooks
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedWebhookList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: List Webhooks
      description: Webhook subscription endpoints.
    post:
      operationId: createWebhook
      tags:
        - Webhooks
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookCreateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/WebhookCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/WebhookCreateRequest'
        required: true
      security:
        - BearerAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookCreated'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Create Webhook
      description: Webhook subscription endpoints.
  /api/v1/webhooks/{id}:
    get:
      operationId: getWebhook
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Webhooks
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Get Webhook
      description: Webhook subscription endpoints.
    patch:
      operationId: updateWebhook
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Webhooks
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedWebhookUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedWebhookUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedWebhookUpdateRequest'
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookList'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Update Webhook
      description: Webhook subscription endpoints.
    delete:
      operationId: deleteWebhook
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Webhooks
      security:
        - BearerAuth: []
      responses:
        '204':
          description: No response body
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Delete Webhook
      description: Webhook subscription endpoints.
  /api/v1/webhooks/{id}/test:
    post:
      operationId: testWebhook
      parameters:
        - in: path
          name: id
          schema:
            type: string
            description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          required: true
      tags:
        - Webhooks
      security:
        - BearerAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookTestResult'
          description: ''
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      summary: Test Webhook
      description: Webhook subscription endpoints.
components:
  schemas:
    APIKey:
      type: object
      properties:
        id:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
        key:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Secret static API token used for account-level API authentication.</p><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Leave blank only when a service will generate or rotate the value.</div></div>
        created:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when the record was first created. Django sets it automatically.</p></div>
        allowed_ips:
          type: array
          items:
            type: string
      required:
        - created
        - id
        - key
    APIKeyRequest:
      type: object
      properties:
        allowed_ips:
          type: array
          items:
            type: string
    APIKeyUpdate:
      type: object
      properties:
        allowed_ips:
          type: array
          items:
            type: string
      required:
        - allowed_ips
    App:
      type: object
      properties:
        id:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
        name:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Application name shown in admin, owner API responses, and operational logs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">Mobile VPN</code><span class="text-xs text-gray-400">customer-facing app</span></div></div>
        key:
          type: string
          readOnly: true
          title: SDK Integration Key
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Secret key developers embed in their app configuration to initialize the SDK for this app.</p><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Rotating this value requires updating every app integration that initializes the SDK with it.</div></div>
        application_type:
          allOf:
            - $ref: '#/components/schemas/AppApplicationTypeEnum'
          readOnly: true
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Operating system family targeted by this app.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">ios</code><span class="text-xs text-gray-400">iOS app</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">android</code><span class="text-xs text-gray-400">Android app</span></div></div>

            * `ios` - iOS
            * `android` - Android
            * `macos` - macOS
            * `windows` - Windows
            * `linux` - Linux
        programming_language:
          allOf:
            - $ref: '#/components/schemas/AppProgrammingLanguageEnum'
          readOnly: true
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Primary programming language used by this app integration.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">swift</code><span class="text-xs text-gray-400">Swift SDK integration</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">kotlin</code><span class="text-xs text-gray-400">Kotlin SDK integration</span></div></div>

            * `java` - Java
            * `kotlin` - Kotlin
            * `objective_c` - Objective C
            * `swift` - Swift
            * `plain_c` - Plain C
            * `csharp` - C#
            * `rust` - Rust
            * `javascript` - JavaScript
        application_url:
          type: string
          format: uri
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Public app store, product, website, or owner page for this app.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">https://example.com/mobile-vpn</code><span class="text-xs text-gray-400">product website</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Direct downloadable package URLs such as APK, IPA, EXE, MSI, DMG, and package files are rejected.</div></div>
        comment:
          type: string
          readOnly: true
          title: Review comment
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Optional seller-provided note shown during app review.</p></div>
        status:
          allOf:
            - $ref: '#/components/schemas/AppStatusEnum'
          readOnly: true
          title: Review status
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Lifecycle state for seller-submitted apps.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">review</code><span class="text-xs text-gray-400">awaiting approval</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">approved</code><span class="text-xs text-gray-400">approved for runtime access</span></div></div>

            * `review` - Review
            * `approved` - Approved
            * `canceled` - Canceled
        payout_type:
          allOf:
            - $ref: '#/components/schemas/AppPayoutTypeEnum'
          readOnly: true
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Revenue calculation mode used by payout service for this app.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">dau</code><span class="text-xs text-gray-400">pay per daily active user</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">bandwidth</code><span class="text-xs text-gray-400">pay per routed gigabyte</span></div></div>

            * `dau` - DAU
            * `bandwidth` - Bandwidth
        country_payout_prices:
          readOnly: true
          description: '<div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Required JSON object mapping lowercased ISO2 country codes to payout prices in cents.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">{&quot;us&quot;: 10, &quot;de&quot;: 8}</code><span class="text-xs text-gray-400">country price map</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">For DAU apps the price is paid per qualified daily active user. For Bandwidth apps the price is paid per routed gigabyte.</div></div>'
        payout_period_days:
          type: integer
          readOnly: true
          title: Payout period (days)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Minimum number of days between payout requests for this app.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">30</code><span class="text-xs text-gray-400">monthly payout window</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">This administrative setting is intentionally not written to the app runtime cache.</div></div>
        paid_out_cents:
          type: integer
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Total completed payout amount for this app in USD cents.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">250000</code><span class="text-xs text-gray-400">$2,500.00 already paid</span></div></div>
        limit_mbps:
          type: integer
          readOnly: true
          title: Bandwidth Limit (Mbit/s)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum app bandwidth in megabits per second.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">100</code><span class="text-xs text-gray-400">100 Mbit/s</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Runtime cache stores this value unchanged; consumers convert units when needed.</div></div>
        connection_limit:
          type: integer
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum number of simultaneous app connections.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">1000</code><span class="text-xs text-gray-400">one thousand concurrent connections</span></div></div>
        created:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when the record was first created. Django sets it automatically.</p></div>
        updated:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp of the latest model save. Django updates it automatically.</p></div>
      required:
        - application_type
        - application_url
        - comment
        - connection_limit
        - country_payout_prices
        - created
        - id
        - key
        - limit_mbps
        - name
        - paid_out_cents
        - payout_period_days
        - payout_type
        - programming_language
        - status
        - updated
    AppApplicationTypeEnum:
      enum:
        - ios
        - android
        - macos
        - windows
        - linux
      type: string
      description: |-
        * `ios` - iOS
        * `android` - Android
        * `macos` - macOS
        * `windows` - Windows
        * `linux` - Linux
    AppCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        application_type:
          $ref: '#/components/schemas/AppApplicationTypeEnum'
        programming_language:
          $ref: '#/components/schemas/AppProgrammingLanguageEnum'
        application_url:
          type: string
          format: uri
          minLength: 1
          maxLength: 2048
        comment:
          type: string
          title: Review comment
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Optional seller-provided note shown during app review.</p></div>
        payout_type:
          $ref: '#/components/schemas/AppPayoutTypeEnum'
      required:
        - application_type
        - application_url
        - name
        - payout_type
        - programming_language
    AppPayoutTypeEnum:
      enum:
        - dau
        - bandwidth
      type: string
      description: |-
        * `dau` - DAU
        * `bandwidth` - Bandwidth
    AppProgrammingLanguageEnum:
      enum:
        - java
        - kotlin
        - objective_c
        - swift
        - plain_c
        - csharp
        - rust
        - javascript
      type: string
      description: |-
        * `java` - Java
        * `kotlin` - Kotlin
        * `objective_c` - Objective C
        * `swift` - Swift
        * `plain_c` - Plain C
        * `csharp` - C#
        * `rust` - Rust
        * `javascript` - JavaScript
    AppReviewUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Application name shown in admin, owner API responses, and operational logs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">Mobile VPN</code><span class="text-xs text-gray-400">customer-facing app</span></div></div>
          maxLength: 255
        application_type:
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Operating system family targeted by this app.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">ios</code><span class="text-xs text-gray-400">iOS app</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">android</code><span class="text-xs text-gray-400">Android app</span></div></div>

            * `ios` - iOS
            * `android` - Android
            * `macos` - macOS
            * `windows` - Windows
            * `linux` - Linux
          oneOf:
            - $ref: '#/components/schemas/AppApplicationTypeEnum'
            - $ref: '#/components/schemas/BlankEnum'
        programming_language:
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Primary programming language used by this app integration.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">swift</code><span class="text-xs text-gray-400">Swift SDK integration</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">kotlin</code><span class="text-xs text-gray-400">Kotlin SDK integration</span></div></div>

            * `java` - Java
            * `kotlin` - Kotlin
            * `objective_c` - Objective C
            * `swift` - Swift
            * `plain_c` - Plain C
            * `csharp` - C#
            * `rust` - Rust
            * `javascript` - JavaScript
          oneOf:
            - $ref: '#/components/schemas/AppProgrammingLanguageEnum'
            - $ref: '#/components/schemas/BlankEnum'
        application_url:
          type: string
          format: uri
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Public app store, product, website, or owner page for this app.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">https://example.com/mobile-vpn</code><span class="text-xs text-gray-400">product website</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Direct downloadable package URLs such as APK, IPA, EXE, MSI, DMG, and package files are rejected.</div></div>
          maxLength: 2048
        comment:
          type: string
          title: Review comment
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Optional seller-provided note shown during app review.</p></div>
      required:
        - name
    AppStatusEnum:
      enum:
        - review
        - approved
        - canceled
      type: string
      description: |-
        * `review` - Review
        * `approved` - Approved
        * `canceled` - Canceled
    AsnRow:
      type: object
      properties:
        asn:
          type: integer
          minimum: 1
        peer_count:
          type: integer
          minimum: 0
        os_counts:
          type: array
          items:
            $ref: '#/components/schemas/OperatingSystemCount'
      required:
        - asn
        - os_counts
        - peer_count
    BandwidthRevenueResult:
      type: object
      properties:
        app_id:
          type: string
        country:
          type: string
        data_bytes:
          type: integer
        data_gb:
          type: number
          format: double
        requests:
          type: integer
        price_cents_per_gb:
          type: integer
        revenue_cents:
          type: integer
      required:
        - app_id
        - country
        - data_bytes
        - data_gb
        - price_cents_per_gb
        - requests
        - revenue_cents
    BlankEnum:
      enum:
        - ''
    ChangeSubUserDataRequest:
      type: object
      properties:
        operation:
          $ref: '#/components/schemas/OperationEnum'
        amount:
          type: integer
          minimum: 1
      required:
        - operation
    CityRow:
      type: object
      properties:
        country:
          type: string
        peer_count:
          type: integer
          minimum: 0
        os_counts:
          type: array
          items:
            $ref: '#/components/schemas/OperatingSystemCount'
        region:
          type: string
        city:
          type: string
      required:
        - city
        - country
        - os_counts
        - peer_count
        - region
    CountryRow:
      type: object
      properties:
        country:
          type: string
        peer_count:
          type: integer
          minimum: 0
        os_counts:
          type: array
          items:
            $ref: '#/components/schemas/OperatingSystemCount'
      required:
        - country
        - os_counts
        - peer_count
    CreateDataPurchaseInvoiceGatewayEnum:
      enum:
        - stripe
        - paypal
        - coinbase
        - cryptomus
        - coingate
        - nowpayments
        - adyen
        - mollie
      type: string
      description: |-
        * `stripe` - stripe
        * `paypal` - paypal
        * `coinbase` - coinbase
        * `cryptomus` - cryptomus
        * `coingate` - coingate
        * `nowpayments` - nowpayments
        * `adyen` - adyen
        * `mollie` - mollie
    CreateDataPurchaseInvoiceRequest:
      type: object
      properties:
        gateway:
          $ref: '#/components/schemas/CreateDataPurchaseInvoiceGatewayEnum'
        package_id:
          type: string
          maxLength: 36
        traffic_gb:
          type: integer
          minimum: 1
        crypto_currency:
          type: string
          maxLength: 32
      required:
        - gateway
    CreatePayoutRequest:
      type: object
      properties:
        app:
          type: string
          format: uuid
        payout:
          $ref: '#/components/schemas/PayoutEnum'
        crypto_currency:
          oneOf:
            - $ref: '#/components/schemas/CryptoCurrencyEnum'
            - $ref: '#/components/schemas/BlankEnum'
        wallet_address:
          type: string
          maxLength: 255
        paypal_email:
          type: string
          format: email
          maxLength: 255
        bank_account_details:
          type: string
      required:
        - app
        - payout
    CreateSubUserRequest:
      type: object
      properties:
        email:
          type: string
          format: email
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 8
        limit_mbps:
          type: integer
          maximum: 10000000
          minimum: 0
        bandwidth_mode:
          $ref: '#/components/schemas/UserBandwidthModeEnum'
        limit_connections:
          type: integer
          maximum: 100000
          minimum: 0
      required:
        - email
        - password
    CryptoCurrencyEnum:
      enum:
        - eth
        - btc
        - usdt_trc20
        - usdc
      type: string
      description: |-
        * `eth` - ETH
        * `btc` - BTC
        * `usdt_trc20` - USDT TRC20
        * `usdc` - USDC
    DataPricingCatalog:
      type: object
      properties:
        mode:
          allOf:
            - $ref: '#/components/schemas/ModeEnum'
          readOnly: true
        currency:
          type: string
          readOnly: true
        unit:
          type: string
          readOnly: true
        bytes_per_gb:
          type: integer
          readOnly: true
        packages:
          type: array
          items:
            $ref: '#/components/schemas/DataPricingFixedPackage'
          readOnly: true
        tiers:
          type: array
          items:
            $ref: '#/components/schemas/DataPricingDynamicTier'
          readOnly: true
        max_traffic_gb:
          type: integer
          readOnly: true
      required:
        - bytes_per_gb
        - currency
        - max_traffic_gb
        - mode
        - packages
        - tiers
        - unit
    DataPricingDynamicTier:
      type: object
      properties:
        min_gb:
          type: integer
          readOnly: true
        max_gb:
          type: integer
          readOnly: true
        price_per_gb_cents:
          type: integer
          readOnly: true
      required:
        - max_gb
        - min_gb
        - price_per_gb_cents
    DataPricingFixedPackage:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        traffic_gb:
          type: integer
          readOnly: true
        data_bytes:
          type: integer
          readOnly: true
        price_cents:
          type: integer
          readOnly: true
      required:
        - data_bytes
        - id
        - price_cents
        - traffic_gb
    DataPricingQuote:
      type: object
      properties:
        mode:
          allOf:
            - $ref: '#/components/schemas/ModeEnum'
          readOnly: true
        currency:
          type: string
          readOnly: true
        traffic_gb:
          type: integer
          readOnly: true
        data_bytes:
          type: integer
          readOnly: true
        price_cents:
          type: integer
          readOnly: true
        package_id:
          type: string
          readOnly: true
          nullable: true
      required:
        - currency
        - data_bytes
        - mode
        - package_id
        - price_cents
        - traffic_gb
    DataPurchaseInvoice:
      type: object
      properties:
        id:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
        internal_id:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Short buyer-facing invoice identifier.</p></div>
        status:
          allOf:
            - $ref: '#/components/schemas/DataPurchaseInvoiceStatusEnum'
          readOnly: true
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Payment and fulfillment lifecycle status.</p></div>

            * `pending` - Pending
            * `paid` - Paid
            * `error` - Error
            * `canceled` - Canceled
        gateway:
          allOf:
            - $ref: '#/components/schemas/DataPurchaseInvoiceGatewayEnum'
          readOnly: true
          title: Payment gateway
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Payment provider selected for this invoice.</p></div>

            * `stripe` - Stripe
            * `paypal` - PayPal
            * `coinbase` - Coinbase Commerce
            * `cryptomus` - Cryptomus
            * `coingate` - CoinGate
            * `nowpayments` - NOWPayments
            * `adyen` - Adyen
            * `mollie` - Mollie
            * `manual` - Manual
        pricing_mode:
          allOf:
            - $ref: '#/components/schemas/PricingModeEnum'
          readOnly: true
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Pricing mode snapshot used when the invoice was created.</p></div>

            * `fixed` - Fixed packages
            * `dynamic` - Dynamic tiers
        package_id:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Fixed pricing package id snapshot. Empty for dynamic pricing invoices.</p></div>
        package_title:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Fixed package title snapshot shown to the buyer.</p></div>
        traffic_gb:
          type: integer
          readOnly: true
          title: Traffic (GB)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Decimal gigabytes purchased. Admin invoices may also set exact data bytes.</p></div>
        data_bytes:
          type: integer
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Exact data balance increment credited after payment.</p></div>
        currency:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">ISO currency code snapshot used for payment.</p></div>
        price_cents:
          type: integer
          readOnly: true
          title: Price (cents)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Invoice total in currency cents.</p></div>
        crypto_currency:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Requested cryptocurrency/network for crypto-capable providers.</p></div>
        payment_url:
          type: string
          format: uri
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Hosted provider URL where the buyer completes payment.</p></div>
        provider_status:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Latest raw provider payment status observed by API or webhook.</p></div>
        error:
          type: string
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Latest payment provider or fulfillment error shown by the API.</p></div>
        paid_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when the invoice was accepted as paid.</p></div>
        fulfilled_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when purchased data was credited to the buyer.</p></div>
        created:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when the record was first created. Django sets it automatically.</p></div>
        updated:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp of the latest model save. Django updates it automatically.</p></div>
      required:
        - created
        - crypto_currency
        - currency
        - data_bytes
        - error
        - fulfilled_at
        - gateway
        - id
        - internal_id
        - package_id
        - package_title
        - paid_at
        - payment_url
        - price_cents
        - pricing_mode
        - provider_status
        - status
        - traffic_gb
        - updated
    DataPurchaseInvoiceGatewayEnum:
      enum:
        - stripe
        - paypal
        - coinbase
        - cryptomus
        - coingate
        - nowpayments
        - adyen
        - mollie
        - manual
      type: string
      description: |-
        * `stripe` - Stripe
        * `paypal` - PayPal
        * `coinbase` - Coinbase Commerce
        * `cryptomus` - Cryptomus
        * `coingate` - CoinGate
        * `nowpayments` - NOWPayments
        * `adyen` - Adyen
        * `mollie` - Mollie
        * `manual` - Manual
    DataPurchaseInvoiceStatusEnum:
      enum:
        - pending
        - paid
        - error
        - canceled
      type: string
      description: |-
        * `pending` - Pending
        * `paid` - Paid
        * `error` - Error
        * `canceled` - Canceled
    DataTransactionRow:
      type: object
      properties:
        id:
          type: string
          format: uuid
        actor_user_id:
          type: string
          format: uuid
        target_user_id:
          type: string
          format: uuid
        type:
          type: string
        data:
          type: integer
        timestamp:
          type: string
      required:
        - actor_user_id
        - data
        - id
        - target_user_id
        - timestamp
        - type
    DomainAnalyticsRow:
      type: object
      properties:
        hostname:
          type: string
        requests:
          type: integer
        data:
          type: integer
      required:
        - data
        - hostname
        - requests
    FlexibleAuthTokenObtainRequest:
      type: object
      properties:
        username:
          type: string
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 1
        email:
          type: string
          minLength: 1
      required:
        - password
    IpAnalyticsRow:
      type: object
      properties:
        user_ip:
          type: string
        requests:
          type: integer
        data:
          type: integer
      required:
        - data
        - requests
        - user_ip
    LocationAsnPage:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
        previous:
          type: string
        results:
          type: array
          items:
            $ref: '#/components/schemas/AsnRow'
      required:
        - count
        - next
        - previous
        - results
    LocationCityPage:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
        previous:
          type: string
        results:
          type: array
          items:
            $ref: '#/components/schemas/CityRow'
      required:
        - count
        - next
        - previous
        - results
    LocationCountryPage:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
        previous:
          type: string
        results:
          type: array
          items:
            $ref: '#/components/schemas/CountryRow'
      required:
        - count
        - next
        - previous
        - results
    LocationRegionPage:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
        previous:
          type: string
        results:
          type: array
          items:
            $ref: '#/components/schemas/RegionRow'
      required:
        - count
        - next
        - previous
        - results
    LocationZipPage:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
        previous:
          type: string
        results:
          type: array
          items:
            $ref: '#/components/schemas/ZipRow'
      required:
        - count
        - next
        - previous
        - results
    ModeEnum:
      enum:
        - fixed
        - dynamic
      type: string
      description: |-
        * `fixed` - Fixed packages
        * `dynamic` - Dynamic tiers
    News:
      type: object
      properties:
        id:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          maxLength: 36
        tags:
          type: array
          items:
            type: string
          readOnly: true
        updated:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp of the latest model save. Django updates it automatically.</p></div>
        created:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when the record was first created. Django sets it automatically.</p></div>
        title:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Short admin-facing headline for the news item. It is used in list views and string representation.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">Network maintenance</code><span class="text-xs text-gray-400">operator-facing title</span></div></div>
          maxLength: 255
        body:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Full rich text news content shown to users.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">&lt;strong&gt;New locations&lt;/strong&gt; are available this week.</code><span class="text-xs text-gray-400">rich text update</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">&lt;ul&gt;&lt;li&gt;Added US&lt;/li&gt;&lt;li&gt;Added DE&lt;/li&gt;&lt;/ul&gt;</code><span class="text-xs text-gray-400">rich text list</span></div></div>
        hide_at:
          type: string
          format: date-time
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Optional timestamp when this news item should stop being returned by the public API.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">2026-07-01 12:00 UTC</code><span class="text-xs text-gray-400">scheduled hide time</span></div></div>
      required:
        - body
        - created
        - tags
        - updated
    OperatingSystemCount:
      type: object
      properties:
        os_type:
          $ref: '#/components/schemas/OsTypeEnum'
        peer_count:
          type: integer
          minimum: 0
      required:
        - os_type
        - peer_count
    OperationEnum:
      enum:
        - add
        - subtract
        - reset
      type: string
      description: |-
        * `add` - Add
        * `subtract` - Subtract
        * `reset` - Reset
    OsTypeEnum:
      enum:
        - android
        - ios
        - linux
        - macos
        - windows
        - other
      type: string
      description: |-
        * `android` - android
        * `ios` - ios
        * `linux` - linux
        * `macos` - macos
        * `windows` - windows
        * `other` - other
    PaginatedAPIKeyList:
      type: object
      required:
        - count
        - results
      properties:
        count:
          type: integer
          example: 123
        next:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=400&limit=100
        previous:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=200&limit=100
        results:
          type: array
          items:
            $ref: '#/components/schemas/APIKey'
    PaginatedAppList:
      type: object
      required:
        - count
        - results
      properties:
        count:
          type: integer
          example: 123
        next:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=400&limit=100
        previous:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=200&limit=100
        results:
          type: array
          items:
            $ref: '#/components/schemas/App'
    PaginatedBandwidthRevenueList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/BandwidthRevenueResult'
      required:
        - count
        - results
    PaginatedDataPurchaseInvoiceList:
      type: object
      required:
        - count
        - results
      properties:
        count:
          type: integer
          example: 123
        next:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=400&limit=100
        previous:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=200&limit=100
        results:
          type: array
          items:
            $ref: '#/components/schemas/DataPurchaseInvoice'
    PaginatedDataTransactionList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/DataTransactionRow'
      required:
        - count
        - results
    PaginatedDomainAnalyticsList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/DomainAnalyticsRow'
      required:
        - count
        - results
    PaginatedIpAnalyticsList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/IpAnalyticsRow'
      required:
        - count
        - results
    PaginatedManagedUserList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/SubUser'
      required:
        - count
        - results
    PaginatedNewsList:
      type: object
      required:
        - count
        - results
      properties:
        count:
          type: integer
          example: 123
        next:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=400&limit=100
        previous:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=200&limit=100
        results:
          type: array
          items:
            $ref: '#/components/schemas/News'
    PaginatedOverallAnalyticsList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/RequestTimeseriesRow'
      required:
        - count
        - results
    PaginatedPayoutList:
      type: object
      required:
        - count
        - results
      properties:
        count:
          type: integer
          example: 123
        next:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=400&limit=100
        previous:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=200&limit=100
        results:
          type: array
          items:
            $ref: '#/components/schemas/Payout'
    PaginatedQualifiedLeadList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/QualifiedLeadRow'
      required:
        - count
        - results
    PaginatedQualifiedRevenueList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/QualifiedRevenueResult'
      required:
        - count
        - results
    PaginatedRequestLogList:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
        next:
          type: string
          format: uri
          nullable: true
        previous:
          type: string
          format: uri
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/RequestLogRow'
      required:
        - count
        - results
    PasswordResetConfirm:
      type: object
      properties:
        uid:
          type: string
        token:
          type: string
      required:
        - token
        - uid
    PasswordResetConfirmRequest:
      type: object
      properties:
        uid:
          type: string
          minLength: 1
        token:
          type: string
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 1
      required:
        - password
        - token
        - uid
    PasswordResetRequest:
      type: object
      properties:
        email:
          type: string
          format: email
      required:
        - email
    PasswordResetRequestRequest:
      type: object
      properties:
        email:
          type: string
          format: email
          minLength: 1
      required:
        - email
    PatchedAPIKeyUpdateRequest:
      type: object
      properties:
        allowed_ips:
          type: array
          items:
            type: string
    PatchedAppReviewUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Application name shown in admin, owner API responses, and operational logs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">Mobile VPN</code><span class="text-xs text-gray-400">customer-facing app</span></div></div>
          maxLength: 255
        application_type:
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Operating system family targeted by this app.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">ios</code><span class="text-xs text-gray-400">iOS app</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">android</code><span class="text-xs text-gray-400">Android app</span></div></div>

            * `ios` - iOS
            * `android` - Android
            * `macos` - macOS
            * `windows` - Windows
            * `linux` - Linux
          oneOf:
            - $ref: '#/components/schemas/AppApplicationTypeEnum'
            - $ref: '#/components/schemas/BlankEnum'
        programming_language:
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Primary programming language used by this app integration.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">swift</code><span class="text-xs text-gray-400">Swift SDK integration</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">kotlin</code><span class="text-xs text-gray-400">Kotlin SDK integration</span></div></div>

            * `java` - Java
            * `kotlin` - Kotlin
            * `objective_c` - Objective C
            * `swift` - Swift
            * `plain_c` - Plain C
            * `csharp` - C#
            * `rust` - Rust
            * `javascript` - JavaScript
          oneOf:
            - $ref: '#/components/schemas/AppProgrammingLanguageEnum'
            - $ref: '#/components/schemas/BlankEnum'
        application_url:
          type: string
          format: uri
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Public app store, product, website, or owner page for this app.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">https://example.com/mobile-vpn</code><span class="text-xs text-gray-400">product website</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Direct downloadable package URLs such as APK, IPA, EXE, MSI, DMG, and package files are rejected.</div></div>
          maxLength: 2048
        comment:
          type: string
          title: Review comment
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Optional seller-provided note shown during app review.</p></div>
    PatchedUpdateSubUserRequest:
      type: object
      properties:
        email:
          type: string
          format: email
          minLength: 1
        password:
          type: string
          minLength: 8
          maxLength: 255
        new_password:
          type: string
          minLength: 8
          maxLength: 255
        limit_mbps:
          type: integer
          maximum: 10000000
          minimum: 0
        bandwidth_mode:
          $ref: '#/components/schemas/UserBandwidthModeEnum'
        limit_connections:
          type: integer
          maximum: 100000
          minimum: 0
    PatchedUserRequest:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
        is_superuser:
          type: boolean
          title: Superuser status
          description: Designates that this user has all permissions without explicitly assigning them.
        date_joined:
          type: string
          format: date-time
        username:
          type: string
          minLength: 1
          description: Generated immutable proxy username.
          pattern: ^[A-Za-z0-9]{16}$
          maxLength: 16
        email:
          type: string
          format: email
          minLength: 1
          title: Email address
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Unique email address used for login, notifications, and payout ownership checks.</p></div>
          maxLength: 254
        is_udp:
          type: boolean
          title: UDP
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Allows this user account to use UDP-capable proxy paths when infrastructure supports them.</p></div>
        type:
          allOf:
            - $ref: '#/components/schemas/UserTypeEnum'
          title: User Type
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Business role used by permissions, app ownership, and admin filtering.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">seller</code><span class="text-xs text-gray-400">app owner account</span></div></div>

            * `seller` - Seller
            * `buyer` - Buyer
        limit_mbps:
          type: integer
          maximum: 2147483647
          minimum: 0
          title: Bandwidth Limit (Mbit/s)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum bandwidth allowed for the user in megabits per second.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">100</code><span class="text-xs text-gray-400">100 Mbit/s</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Runtime cache stores this value unchanged; consumers convert units when needed.</div></div>
        bandwidth_mode:
          allOf:
            - $ref: '#/components/schemas/UserBandwidthModeEnum'
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">How the user bandwidth limit is applied by the proxy runtime.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">whole</code><span class="text-xs text-gray-400">limit is shared by all user connections</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">connection</code><span class="text-xs text-gray-400">limit is applied to each individual connection</span></div></div>

            * `whole` - Whole
            * `connection` - Connection
        limit_connections:
          type: integer
          maximum: 2147483647
          minimum: 0
          title: Connection Limit
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum simultaneous open connections allowed for the user.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">500</code><span class="text-xs text-gray-400">five hundred concurrent connections</span></div></div>
        data_used:
          type: integer
          maximum: 9223372036854776000
          minimum: -9223372036854776000
          format: int64
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Cumulative data usage recorded for this user in bytes.</p></div>
        latest_activity:
          type: string
          format: date-time
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Last known user activity timestamp used by operational monitoring and account views.</p></div>
        proxy_password:
          type: string
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Runtime proxy password for buyer users. Sellers do not have a proxy password.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">aB9xY2mN7pQ4rS6t</code><span class="text-xs text-gray-400">16 letters and digits</span></div></div>
          maxLength: 16
        proxy_password_reset:
          type: string
          format: date-time
          nullable: true
          title: Proxy Password Reset At
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp used to track when the current proxy password was issued.</p></div>
        parent:
          type: string
          format: uuid
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Top-level account that owns this sub-user. Empty value means this is a first-level user.</p></div>
          nullable: true
          title: Parent user
    PatchedWebhookUpdateRequest:
      type: object
      properties:
        endpoint:
          type: string
          minLength: 1
          maxLength: 500
        read_timeout:
          type: integer
          maximum: 60
          minimum: 1
        write_timeout:
          type: integer
          maximum: 60
          minimum: 1
        retries:
          type: integer
          maximum: 10
          minimum: 0
        retry_timeout:
          type: integer
          maximum: 300
          minimum: 1
    Payout:
      type: object
      properties:
        id:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          maxLength: 36
        app:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          readOnly: true
        app_name:
          type: string
          readOnly: true
        payout:
          allOf:
            - $ref: '#/components/schemas/PayoutEnum'
          title: Payout Method
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Destination type selected by the app owner when requesting a payout.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">crypto</code><span class="text-xs text-gray-400">wallet payout</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">paypal</code><span class="text-xs text-gray-400">PayPal payout</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">bank</code><span class="text-xs text-gray-400">bank transfer</span></div></div>

            * `crypto` - Crypto
            * `paypal` - PayPal
            * `bank_account` - Bank Account
        status:
          allOf:
            - $ref: '#/components/schemas/PayoutStatusEnum'
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Operational payout lifecycle controlled by API requests and admin processing.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">requested</code><span class="text-xs text-gray-400">waiting for admin review</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">processing</code><span class="text-xs text-gray-400">being paid</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">completed</code><span class="text-xs text-gray-400">paid and accounted</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">canceled</code><span class="text-xs text-gray-400">rejected with reason</span></div></div>

            * `requested` - Requested
            * `processing` - Processing
            * `completed` - Completed
            * `canceled` - Canceled
        amount_cents:
          type: integer
          maximum: 9223372036854776000
          minimum: 0
          format: int64
          title: Amount (cents)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Payout amount calculated by the payout service for the selected app and period.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">1250</code><span class="text-xs text-gray-400">$12.50</span></div></div>
        crypto_currency:
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Cryptocurrency network selected for crypto payouts. Required only for crypto method.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">btc</code><span class="text-xs text-gray-400">Bitcoin</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">eth</code><span class="text-xs text-gray-400">Ethereum</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">usdt_trc20</code><span class="text-xs text-gray-400">USDT TRC20</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">usdc</code><span class="text-xs text-gray-400">USDC</span></div></div>

            * `eth` - ETH
            * `btc` - BTC
            * `usdt_trc20` - USDT TRC20
            * `usdc` - USDC
          oneOf:
            - $ref: '#/components/schemas/CryptoCurrencyEnum'
            - $ref: '#/components/schemas/BlankEnum'
        wallet_address:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Validated destination wallet address for crypto payouts.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">bc1q...</code><span class="text-xs text-gray-400">Bitcoin address</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0x...</code><span class="text-xs text-gray-400">Ethereum-compatible address</span></div></div>
          maxLength: 255
        paypal_email:
          type: string
          format: email
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Validated PayPal payout email address. Required only for PayPal payouts.</p></div>
          maxLength: 255
        bank_account_details:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Free-form bank payout instructions supplied by the app owner.</p><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Use this field for IBAN, SWIFT/BIC, beneficiary name, address, and any bank-specific routing data.</div></div>
        transaction_id:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">External payment transaction identifier entered by admin after sending funds.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0xabc...</code><span class="text-xs text-gray-400">crypto transaction hash</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">PAYID-...</code><span class="text-xs text-gray-400">provider payment id</span></div></div>
          maxLength: 255
        period_start:
          type: string
          format: date
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">First date included in the revenue calculation for this payout.</p></div>
        period_end:
          type: string
          format: date
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Last date included in the revenue calculation for this payout.</p></div>
        reason:
          type: string
          title: Cancel Reason
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Admin-visible rejection reason. Required by service validation when moving a payout to canceled.</p></div>
        created:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when the record was first created. Django sets it automatically.</p></div>
        updated:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp of the latest model save. Django updates it automatically.</p></div>
      required:
        - app
        - app_name
        - created
        - updated
    PayoutEnum:
      enum:
        - crypto
        - paypal
        - bank_account
      type: string
      description: |-
        * `crypto` - Crypto
        * `paypal` - PayPal
        * `bank_account` - Bank Account
    PayoutQuote:
      type: object
      properties:
        app:
          type: string
          format: uuid
      required:
        - app
    PayoutStatusEnum:
      enum:
        - requested
        - processing
        - completed
        - canceled
      type: string
      description: |-
        * `requested` - Requested
        * `processing` - Processing
        * `completed` - Completed
        * `canceled` - Canceled
    PricingModeEnum:
      enum:
        - fixed
        - dynamic
      type: string
      description: |-
        * `fixed` - Fixed packages
        * `dynamic` - Dynamic tiers
    QualifiedLeadRow:
      type: object
      properties:
        app_id:
          type: string
        peer_id:
          type: string
        country:
          type: string
        ip:
          type: string
        ip_version:
          type: string
        region:
          type: string
        city:
          type: string
        asn:
          type: integer
        zip:
          type: string
        timezone:
          type: string
        os_type:
          type: string
        os_version:
          type: string
        sdk_version:
          type: string
        online_at:
          type: string
          nullable: true
        offline_at:
          type: string
          nullable: true
        qualified_at:
          type: string
          nullable: true
        session_duration:
          type: integer
      required:
        - app_id
        - asn
        - city
        - country
        - ip
        - ip_version
        - offline_at
        - online_at
        - os_type
        - os_version
        - peer_id
        - qualified_at
        - region
        - sdk_version
        - session_duration
        - timezone
        - zip
    QualifiedRevenueResult:
      type: object
      properties:
        month:
          type: string
        app_id:
          type: string
        country:
          type: string
        qualified_peers:
          type: integer
        price_cents:
          type: integer
        revenue_cents:
          type: integer
      required:
        - app_id
        - country
        - month
        - price_cents
        - qualified_peers
        - revenue_cents
    RefreshRequestRequest:
      type: object
      properties:
        refresh:
          type: string
          minLength: 1
      required:
        - refresh
    RegionRow:
      type: object
      properties:
        country:
          type: string
        peer_count:
          type: integer
          minimum: 0
        os_counts:
          type: array
          items:
            $ref: '#/components/schemas/OperatingSystemCount'
        region:
          type: string
      required:
        - country
        - os_counts
        - peer_count
        - region
    RequestLogRow:
      type: object
      properties:
        protocol:
          type: string
        method:
          type: string
        user_ip:
          type: string
        server_ip:
          type: string
        data:
          type: integer
        hostname:
          type: string
        port:
          type: integer
        continent:
          type: string
        country:
          type: string
        region:
          type: string
        city:
          type: string
        latitude:
          type: number
          format: double
        longitude:
          type: number
          format: double
        radius:
          type: integer
        asn:
          type: integer
        zip:
          type: string
        ip:
          type: string
        timestamp:
          type: string
        is_session:
          type: boolean
      required:
        - asn
        - city
        - continent
        - country
        - data
        - hostname
        - ip
        - is_session
        - latitude
        - longitude
        - method
        - port
        - protocol
        - radius
        - region
        - server_ip
        - timestamp
        - user_ip
        - zip
    RequestTimeseriesRow:
      type: object
      properties:
        timestamp:
          type: string
        requests:
          type: integer
        data:
          type: integer
      required:
        - data
        - requests
        - timestamp
    ServerList:
      type: object
      properties:
        id:
          type: string
          format: uuid
        ip:
          type: string
        domain:
          type: string
        http_ports:
          type: array
          items:
            type: integer
            maximum: 65535
            minimum: 0
        socks5_ports:
          type: array
          items:
            type: integer
            maximum: 65535
            minimum: 0
      required:
        - domain
        - http_ports
        - id
        - ip
        - socks5_ports
    SignUp:
      type: object
      properties:
        email:
          type: string
          format: email
        type:
          $ref: '#/components/schemas/UserTypeEnum'
      required:
        - email
        - type
    SignUpRequest:
      type: object
      properties:
        email:
          type: string
          format: email
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 1
        type:
          $ref: '#/components/schemas/UserTypeEnum'
      required:
        - email
        - password
        - type
    SocialAuthProviders:
      type: object
      properties:
        google:
          type: boolean
        facebook:
          type: boolean
        discord:
          type: boolean
      required:
        - discord
        - facebook
        - google
    SocialAuthRequest:
      type: object
      properties:
        access_token:
          type: string
          writeOnly: true
          minLength: 1
        type:
          $ref: '#/components/schemas/UserTypeEnum'
      required:
        - access_token
        - type
    SubUser:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
        parent:
          type: string
          format: uuid
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Top-level account that owns this sub-user. Empty value means this is a first-level user.</p></div>
          readOnly: true
          nullable: true
          title: Parent user
        email:
          type: string
          format: email
          readOnly: true
          title: Email address
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Unique email address used for login, notifications, and payout ownership checks.</p></div>
        username:
          type: string
          readOnly: true
          description: Generated immutable proxy username.
        type:
          allOf:
            - $ref: '#/components/schemas/UserTypeEnum'
          readOnly: true
          title: User Type
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Business role used by permissions, app ownership, and admin filtering.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">seller</code><span class="text-xs text-gray-400">app owner account</span></div></div>

            * `seller` - Seller
            * `buyer` - Buyer
        data:
          type: integer
          readOnly: true
          title: Data Balance
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Total data balance assigned to the user in bytes. Top-level users can adjust sub-user balances.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">10737418240</code><span class="text-xs text-gray-400">10 GiB</span></div></div>
        data_used:
          type: integer
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Cumulative data usage recorded for this user in bytes.</p></div>
        data_updated:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp of the latest saved data balance or usage update.</p></div>
        proxy_password:
          type: string
          readOnly: true
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Runtime proxy password for buyer users. Sellers do not have a proxy password.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">aB9xY2mN7pQ4rS6t</code><span class="text-xs text-gray-400">16 letters and digits</span></div></div>
        proxy_password_reset:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          title: Proxy Password Reset At
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp used to track when the current proxy password was issued.</p></div>
        limit_mbps:
          type: integer
          readOnly: true
          title: Bandwidth Limit (Mbit/s)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum bandwidth allowed for the user in megabits per second.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">100</code><span class="text-xs text-gray-400">100 Mbit/s</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Runtime cache stores this value unchanged; consumers convert units when needed.</div></div>
        bandwidth_mode:
          allOf:
            - $ref: '#/components/schemas/UserBandwidthModeEnum'
          readOnly: true
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">How the user bandwidth limit is applied by the proxy runtime.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">whole</code><span class="text-xs text-gray-400">limit is shared by all user connections</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">connection</code><span class="text-xs text-gray-400">limit is applied to each individual connection</span></div></div>

            * `whole` - Whole
            * `connection` - Connection
        limit_connections:
          type: integer
          readOnly: true
          title: Connection Limit
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum simultaneous open connections allowed for the user.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">500</code><span class="text-xs text-gray-400">five hundred concurrent connections</span></div></div>
        runtime_usage:
          type: object
          additionalProperties:
            oneOf:
              - type: number
                format: double
              - type: integer
          readOnly: true
        date_joined:
          type: string
          format: date-time
          readOnly: true
      required:
        - bandwidth_mode
        - data
        - data_updated
        - data_used
        - date_joined
        - email
        - id
        - limit_connections
        - limit_mbps
        - parent
        - proxy_password
        - proxy_password_reset
        - runtime_usage
        - type
        - username
    TokenPair:
      type: object
      properties:
        access:
          type: string
        refresh:
          type: string
      required:
        - access
        - refresh
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
        data:
          type: integer
          readOnly: true
        blocked_domains:
          type: array
          items:
            type: string
          readOnly: true
        blocked_tlds:
          type: array
          items:
            type: string
          readOnly: true
        allowed_ips:
          type: array
          items:
            type: string
          readOnly: true
        runtime_usage:
          type: object
          additionalProperties:
            oneOf:
              - type: number
                format: double
              - type: integer
          readOnly: true
        is_superuser:
          type: boolean
          title: Superuser status
          description: Designates that this user has all permissions without explicitly assigning them.
        date_joined:
          type: string
          format: date-time
        username:
          type: string
          description: Generated immutable proxy username.
          pattern: ^[A-Za-z0-9]{16}$
          maxLength: 16
        email:
          type: string
          format: email
          title: Email address
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Unique email address used for login, notifications, and payout ownership checks.</p></div>
          maxLength: 254
        is_udp:
          type: boolean
          title: UDP
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Allows this user account to use UDP-capable proxy paths when infrastructure supports them.</p></div>
        type:
          allOf:
            - $ref: '#/components/schemas/UserTypeEnum'
          title: User Type
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Business role used by permissions, app ownership, and admin filtering.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">seller</code><span class="text-xs text-gray-400">app owner account</span></div></div>

            * `seller` - Seller
            * `buyer` - Buyer
        limit_mbps:
          type: integer
          maximum: 2147483647
          minimum: 0
          title: Bandwidth Limit (Mbit/s)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum bandwidth allowed for the user in megabits per second.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">100</code><span class="text-xs text-gray-400">100 Mbit/s</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Runtime cache stores this value unchanged; consumers convert units when needed.</div></div>
        bandwidth_mode:
          allOf:
            - $ref: '#/components/schemas/UserBandwidthModeEnum'
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">How the user bandwidth limit is applied by the proxy runtime.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">whole</code><span class="text-xs text-gray-400">limit is shared by all user connections</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">connection</code><span class="text-xs text-gray-400">limit is applied to each individual connection</span></div></div>

            * `whole` - Whole
            * `connection` - Connection
        limit_connections:
          type: integer
          maximum: 2147483647
          minimum: 0
          title: Connection Limit
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum simultaneous open connections allowed for the user.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">500</code><span class="text-xs text-gray-400">five hundred concurrent connections</span></div></div>
        data_used:
          type: integer
          maximum: 9223372036854776000
          minimum: -9223372036854776000
          format: int64
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Cumulative data usage recorded for this user in bytes.</p></div>
        data_updated:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp of the latest saved data balance or usage update.</p></div>
        latest_activity:
          type: string
          format: date-time
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Last known user activity timestamp used by operational monitoring and account views.</p></div>
        proxy_password:
          type: string
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Runtime proxy password for buyer users. Sellers do not have a proxy password.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">aB9xY2mN7pQ4rS6t</code><span class="text-xs text-gray-400">16 letters and digits</span></div></div>
          maxLength: 16
        proxy_password_reset:
          type: string
          format: date-time
          nullable: true
          title: Proxy Password Reset At
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp used to track when the current proxy password was issued.</p></div>
        parent:
          type: string
          format: uuid
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Top-level account that owns this sub-user. Empty value means this is a first-level user.</p></div>
          nullable: true
          title: Parent user
      required:
        - allowed_ips
        - blocked_domains
        - blocked_tlds
        - data
        - data_updated
        - email
        - runtime_usage
        - username
    UserBandwidthModeEnum:
      enum:
        - whole
        - connection
      type: string
      description: |-
        * `whole` - Whole
        * `connection` - Connection
    UserRequest:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for the user account.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
        is_superuser:
          type: boolean
          title: Superuser status
          description: Designates that this user has all permissions without explicitly assigning them.
        date_joined:
          type: string
          format: date-time
        username:
          type: string
          minLength: 1
          description: Generated immutable proxy username.
          pattern: ^[A-Za-z0-9]{16}$
          maxLength: 16
        email:
          type: string
          format: email
          minLength: 1
          title: Email address
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Unique email address used for login, notifications, and payout ownership checks.</p></div>
          maxLength: 254
        is_udp:
          type: boolean
          title: UDP
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Allows this user account to use UDP-capable proxy paths when infrastructure supports them.</p></div>
        type:
          allOf:
            - $ref: '#/components/schemas/UserTypeEnum'
          title: User Type
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Business role used by permissions, app ownership, and admin filtering.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">seller</code><span class="text-xs text-gray-400">app owner account</span></div></div>

            * `seller` - Seller
            * `buyer` - Buyer
        limit_mbps:
          type: integer
          maximum: 2147483647
          minimum: 0
          title: Bandwidth Limit (Mbit/s)
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum bandwidth allowed for the user in megabits per second.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">100</code><span class="text-xs text-gray-400">100 Mbit/s</span></div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1">Runtime cache stores this value unchanged; consumers convert units when needed.</div></div>
        bandwidth_mode:
          allOf:
            - $ref: '#/components/schemas/UserBandwidthModeEnum'
          description: |-
            <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">How the user bandwidth limit is applied by the proxy runtime.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">whole</code><span class="text-xs text-gray-400">limit is shared by all user connections</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">connection</code><span class="text-xs text-gray-400">limit is applied to each individual connection</span></div></div>

            * `whole` - Whole
            * `connection` - Connection
        limit_connections:
          type: integer
          maximum: 2147483647
          minimum: 0
          title: Connection Limit
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Maximum simultaneous open connections allowed for the user.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">0</code><span class="text-xs text-gray-400">unlimited</span><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">500</code><span class="text-xs text-gray-400">five hundred concurrent connections</span></div></div>
        data_used:
          type: integer
          maximum: 9223372036854776000
          minimum: -9223372036854776000
          format: int64
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Cumulative data usage recorded for this user in bytes.</p></div>
        latest_activity:
          type: string
          format: date-time
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Last known user activity timestamp used by operational monitoring and account views.</p></div>
        proxy_password:
          type: string
          nullable: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Runtime proxy password for buyer users. Sellers do not have a proxy password.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">aB9xY2mN7pQ4rS6t</code><span class="text-xs text-gray-400">16 letters and digits</span></div></div>
          maxLength: 16
        proxy_password_reset:
          type: string
          format: date-time
          nullable: true
          title: Proxy Password Reset At
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp used to track when the current proxy password was issued.</p></div>
        parent:
          type: string
          format: uuid
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Top-level account that owns this sub-user. Empty value means this is a first-level user.</p></div>
          nullable: true
          title: Parent user
      required:
        - email
        - username
    UserTypeEnum:
      enum:
        - seller
        - buyer
      type: string
      description: |-
        * `seller` - Seller
        * `buyer` - Buyer
    WebhookCreateRequest:
      type: object
      properties:
        endpoint:
          type: string
          minLength: 1
          maxLength: 500
        read_timeout:
          type: integer
          maximum: 60
          minimum: 1
          default: 5
        write_timeout:
          type: integer
          maximum: 60
          minimum: 1
          default: 5
        retries:
          type: integer
          maximum: 10
          minimum: 0
          default: 3
        retry_timeout:
          type: integer
          maximum: 300
          minimum: 1
          default: 10
      required:
        - endpoint
    WebhookCreated:
      type: object
      properties:
        id:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          maxLength: 36
        endpoint:
          type: string
          format: uri
          title: Endpoint URL
          maxLength: 500
        secret:
          type: string
          readOnly: true
          title: Signing Secret
        read_timeout:
          type: integer
          maximum: 60
          minimum: 1
        write_timeout:
          type: integer
          maximum: 60
          minimum: 1
        retries:
          type: integer
          maximum: 10
          minimum: 0
        retry_timeout:
          type: integer
          maximum: 300
          minimum: 1
          title: Retry Interval
        created:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when the record was first created. Django sets it automatically.</p></div>
      required:
        - created
        - endpoint
        - secret
    WebhookList:
      type: object
      properties:
        id:
          type: string
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Stable public identifier for this record. Generated automatically and used by APIs instead of integer IDs.</p><div class="flex flex-wrap items-center gap-2 mt-1"><code class="text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">550e8400-e29b-41d4-a716-446655440000</code><span class="text-xs text-gray-400">UUID string</span></div></div>
          maxLength: 36
        endpoint:
          type: string
          format: uri
          title: Endpoint URL
          maxLength: 500
        read_timeout:
          type: integer
          maximum: 60
          minimum: 1
        write_timeout:
          type: integer
          maximum: 60
          minimum: 1
        retries:
          type: integer
          maximum: 10
          minimum: 0
        retry_timeout:
          type: integer
          maximum: 300
          minimum: 1
          title: Retry Interval
        created:
          type: string
          format: date-time
          readOnly: true
          description: <div class="flex flex-col gap-1 mt-1"><p class="text-sm text-gray-600 dark:text-gray-400">Timestamp when the record was first created. Django sets it automatically.</p></div>
      required:
        - created
        - endpoint
    WebhookTestResult:
      type: object
      properties:
        sent_message:
          type: object
          additionalProperties: {}
        delivery_status_code:
          type: integer
        delivery_response_body:
          type: string
      required:
        - delivery_response_body
        - delivery_status_code
        - sent_message
    ZipRow:
      type: object
      properties:
        country:
          type: string
        region:
          type: string
        city:
          type: string
        zip:
          type: string
        peer_count:
          type: integer
          minimum: 0
        os_counts:
          type: array
          items:
            $ref: '#/components/schemas/OperatingSystemCount'
      required:
        - city
        - country
        - os_counts
        - peer_count
        - region
        - zip
    Error:
      type: object
      additionalProperties: true
      properties:
        non_field_errors:
          type: array
          items:
            type: string
        request_id:
          type: string
    PaginatedProxyServerList:
      type: object
      required:
        - count
        - results
      properties:
        count:
          type: integer
          example: 123
        next:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=400&limit=100
        previous:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=200&limit=100
        results:
          type: array
          items:
            $ref: '#/components/schemas/ServerList'
    PaginatedWebhookList:
      type: object
      required:
        - count
        - results
      properties:
        count:
          type: integer
          example: 123
        next:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=400&limit=100
        previous:
          type: string
          nullable: true
          format: uri
          example: http://api.example.org/accounts/?offset=200&limit=100
        results:
          type: array
          items:
            $ref: '#/components/schemas/WebhookList'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT or account API key
      description: Public endpoints accept JWT or account API keys. Private endpoints accept only account API keys owned by superusers.
  headers:
    RequestId:
      description: Final request id assigned to the response.
      schema:
        type: string
  parameters:
    PaginatedLimitQuery:
      name: limit
      in: query
      required: false
      description: Maximum number of rows to return.
      schema:
        type: integer
        minimum: 1
    OffsetQuery:
      name: offset
      in: query
      required: false
      description: Zero-based row offset.
      schema:
        type: integer
        minimum: 0
    SearchQuery:
      name: search
      in: query
      required: false
      description: Search term.
      schema:
        type: string
    AppPayoutTypeQuery:
      name: payout_type
      in: query
      required: false
      description: Filter apps by payout type.
      schema:
        type: string
        enum:
          - dau
          - bandwidth
    DataTransactionTypeQuery:
      name: type
      in: query
      required: false
      description: Filter data transactions by type.
      schema:
        type: string
        enum:
          - added
          - removed
    PayoutMethodQuery:
      name: payout
      in: query
      required: false
      description: Filter payouts by destination method.
      schema:
        type: string
        enum:
          - crypto
          - paypal
          - bank
  responses:
    BadRequest:
      description: Bad request.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Authentication credentials were not provided or are invalid.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: Permission denied.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Not found.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
