openapi: 3.2.0 info: description: 'Manage existing proxy services using scoped Bearer keys. Default budget: 300 requests per minute per account, shared across keys and control replicas. On HTTP 429, wait for Retry-After. Protected responses use Cache-Control: no-store and X-Request-ID. Timestamps are ISO-8601; monetary amounts are cents. Use the dashboard for API key management. Creating and paying invoices requires billing:write or reseller:purchase.' title: TrueProxies Customer Invoices API version: 1.0.0 servers: - url: https://api.trueproxies.com tags: - name: Invoices paths: /v1/invoices: get: description: Invoice amounts are integer cents in the specified currency. Supports cursor pagination and an optional service_id filter. Creating and paying invoices requires billing:write or reseller:purchase; billing:read alone cannot spend money. operationId: get_v1_invoices parameters: - $ref: '#/components/parameters/CustomerId' - in: query name: cursor schema: type: string - in: query name: limit schema: default: 25 maximum: 100 minimum: 1 type: integer - description: Only invoices linked to this service and owned by the signed-in customer in: query name: service_id schema: format: uuid type: string - description: Filter before pagination and counting in: query name: status schema: $ref: '#/components/schemas/InvoiceStatus' - description: Filter before pagination and counting in: query name: kind schema: $ref: '#/components/schemas/InvoiceKind' responses: '200': content: application/json: schema: properties: items: items: $ref: '#/components/schemas/Invoice' type: array limit: type: integer next_cursor: type: string total: type: integer required: - items - total - limit type: object description: ok '400': $ref: '#/components/responses/Error' '401': $ref: '#/components/responses/Error' '403': $ref: '#/components/responses/Error' '404': $ref: '#/components/responses/Error' '409': $ref: '#/components/responses/Error' '429': $ref: '#/components/responses/Error' '500': $ref: '#/components/responses/Error' '503': $ref: '#/components/responses/Error' security: - customerAPIKey: [] summary: List invoices x-api-key-scope: billing:read x-required-scope: billing:read tags: - Invoices post: description: Requires billing:write; reseller:purchase also permits this operation. Add customer_id to buy for an owned managed customer, which additionally requires reseller:purchase. Prices and discount are snapshotted; a floor conflict returns 409. operationId: post_v1_invoices parameters: - $ref: '#/components/parameters/CustomerId' - $ref: '#/components/parameters/IdempotencyKey' requestBody: content: application/json: schema: $ref: '#/components/schemas/InvoiceCreate' required: true responses: '201': content: application/json: schema: $ref: '#/components/schemas/Invoice' description: created '400': $ref: '#/components/responses/Error' '401': $ref: '#/components/responses/Error' '403': $ref: '#/components/responses/Error' '404': $ref: '#/components/responses/Error' '409': $ref: '#/components/responses/Error' '429': $ref: '#/components/responses/Error' '500': $ref: '#/components/responses/Error' '503': $ref: '#/components/responses/Error' security: - customerAPIKey: [] summary: Create a purchase invoice x-api-key-scope: billing:write x-required-scope: billing:write tags: - Invoices /v1/invoices/{id}: get: description: Read invoice status, payment attempts and the associated service. No payment is initiated. operationId: get_v1_invoices_id parameters: - $ref: '#/components/parameters/CustomerId' - in: path name: id required: true schema: format: uuid type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Invoice' description: ok '400': $ref: '#/components/responses/Error' '401': $ref: '#/components/responses/Error' '403': $ref: '#/components/responses/Error' '404': $ref: '#/components/responses/Error' '409': $ref: '#/components/responses/Error' '429': $ref: '#/components/responses/Error' '500': $ref: '#/components/responses/Error' '503': $ref: '#/components/responses/Error' security: - customerAPIKey: [] summary: Get an invoice x-api-key-scope: billing:read x-required-scope: billing:read tags: - Invoices /v1/invoices/{id}/pay: post: description: Requires billing:write; reseller:purchase also permits this operation. On-behalf payments additionally require reseller:purchase and provider wallet. Insufficient funds return 409 with balance_cents and needed_cents. Never automatically retry an uncertain payment; first read invoice status. operationId: post_v1_invoices_id_pay parameters: - $ref: '#/components/parameters/CustomerId' - $ref: '#/components/parameters/IdempotencyKey' - in: path name: id required: true schema: format: uuid type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/PayRequest' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/PayResponse' description: ok '400': $ref: '#/components/responses/Error' '401': $ref: '#/components/responses/Error' '403': $ref: '#/components/responses/Error' '404': $ref: '#/components/responses/Error' '409': $ref: '#/components/responses/Error' '429': $ref: '#/components/responses/Error' '500': $ref: '#/components/responses/Error' '503': $ref: '#/components/responses/Error' security: - customerAPIKey: [] summary: Pay an invoice x-api-key-scope: billing:write x-required-scope: billing:write tags: - Invoices /v1/invoices/{id}/pdf: get: description: Download a PDF containing the recorded invoice amounts, current payment status and refund records. Returns application/pdf as an attachment. Send customer_id when acting for a managed customer. No payment is initiated. operationId: get_v1_invoices_id_pdf parameters: - $ref: '#/components/parameters/CustomerId' - in: path name: id required: true schema: format: uuid type: string responses: '200': content: application/pdf: schema: format: binary type: string description: Invoice PDF headers: Content-Disposition: description: Attachment named TrueProxies-INV-NNNNNN.pdf. schema: type: string '400': $ref: '#/components/responses/Error' '401': $ref: '#/components/responses/Error' '403': $ref: '#/components/responses/Error' '404': $ref: '#/components/responses/Error' '409': $ref: '#/components/responses/Error' '429': $ref: '#/components/responses/Error' '500': $ref: '#/components/responses/Error' '503': $ref: '#/components/responses/Error' security: - customerAPIKey: [] summary: Download an invoice PDF x-api-key-scope: billing:read x-required-scope: billing:read tags: - Invoices components: schemas: PayResponse: properties: checkout_url: type: string expires_at: format: date-time type: string payment_id: format: uuid type: string required: - payment_id - checkout_url - expires_at type: object Invoice: properties: activated_at: description: When this invoice's service activation, top-up, renewal, or charge-only processing committed. Payment receipt and an already-active service do not establish this outcome. format: date-time type: string activation_failed_at: description: Automatic fulfillment stopped and needs operator attention. Payment remains received; this does not mean a refund completed or previously purchased service was revoked. format: date-time type: string amount_cents: type: integer created_at: format: date-time type: string currency: type: string discount_bp: type: integer display_name: type: string due_at: format: date-time type: string id: description: Internal API identifier. Use reference for customer-facing display. format: uuid type: string kind: $ref: '#/components/schemas/InvoiceKind' list_amount_cents: type: integer offer_key: type: string options: $ref: '#/components/schemas/InvoiceOptions' paid_at: format: date-time type: string payments: items: $ref: '#/components/schemas/InvoicePayment' type: array promo_code: type: string promo_discount_cents: format: int64 minimum: 0 type: integer reference: description: Stable, unique customer-facing reference. example: INV-001001 pattern: ^INV-[0-9]{6,}$ type: string service_id: format: uuid type: string status: $ref: '#/components/schemas/InvoiceStatus' required: - id - reference - kind - offer_key - display_name - amount_cents - currency - status - due_at - created_at - payments type: object InvoiceStatus: enum: - open - paid - cancelled type: string InvoiceCreate: properties: offer_key: type: string options: $ref: '#/components/schemas/InvoiceOptions' promo_code: maxLength: 40 minLength: 3 pattern: ^[A-Za-z0-9][A-Za-z0-9-]{2,39}$ type: string request_id: description: Required when promo_code is present; keep stable only while retrying identical invoice content. format: uuid type: string service_id: description: required for renewal and topup format: uuid type: string required: - offer_key type: object Error: properties: code: enum: - BAD_REQUEST - UNAUTHENTICATED - FORBIDDEN - NOT_FOUND - CONFLICT - RATE_LIMITED - SERVICE_UNAVAILABLE - OFFER_UNAVAILABLE - CITY_UNAVAILABLE - CAPACITY_UNAVAILABLE - INVOICE_NOT_PAYABLE - PROVIDER_ERROR - PIPE_UNAVAILABLE - TRIAL_NOT_ELIGIBLE - EMAIL_UNVERIFIED - INTERNAL type: string details: additionalProperties: true description: What a client needs to act on the error (ids, flags), never display text. type: object message: type: string required: - code - message type: object InvoiceKind: enum: - wallet_topup - purchase - renewal - topup - custom - white_label type: string InvoiceOptions: properties: city: type: string gb: description: GB for top-ups; taken from the offer otherwise type: integer type: object PaymentProvider: description: Payment provider identifier (stripe or cryptomus). type: string PayRequest: properties: provider: $ref: '#/components/schemas/PaymentProvider' required: - provider type: object InvoicePayment: properties: amount_received_cents: type: integer attempt: type: integer checkout_url: description: present only while the invoice is payable and the pending checkout has not reached its known expiry type: string created_at: format: date-time type: string expires_at: format: date-time type: string id: format: uuid type: string provider: description: The payment rail, including staff-recorded manual settlements and compensation. oneOf: - $ref: '#/components/schemas/PaymentProvider' - enum: - manual type: string refund_amount_cents: minimum: 1 type: integer refund_amount_unknown: description: A provider refund was reported without a trustworthy amount. Reconciliation is required before any additional refund. type: boolean refund_completed_at: format: date-time type: string refund_reason: type: string refund_reference: type: string refund_retryable: description: The recorded request can be retried unchanged within the provider idempotency window. type: boolean refund_status: enum: - processing - uncertain - manual_required - submitted - failed - refunded type: string refunded_at: description: Refund request recorded at; not proof of completion format: date-time type: string status: $ref: '#/components/schemas/PaymentStatus' required: - id - attempt - provider - status - created_at type: object PaymentStatus: enum: - pending - paid - expired - failed - paid_unapplied - paid_duplicate type: string parameters: IdempotencyKey: description: 'Makes a retry safe. The first request carrying a given key is executed and its response recorded; repeating the same request with the same key replays that response, with Idempotency-Replayed: true, rather than buying or paying a second time. Reusing a key for a different request is refused with 409, as is a repeat that arrives while the first is still running. Keys are scoped to your account and to the endpoint. Successful and uncertain invoice commands are retained so that an old retry cannot create another invoice. Completed definite rejections are kept for at least 24 hours; after that, the same key may be evaluated again.' in: header name: Idempotency-Key required: false schema: maxLength: 200 type: string CustomerId: description: Owned sub-customer UUID. Resellers only; reads require reseller:read and writes reseller:purchase in addition to the operation scope. X-Customer-Id header is an alternative. Not allowed for me, wallet, trial, API keys, or reseller-management routes. in: query name: customer_id schema: format: uuid type: string responses: Error: content: application/json: schema: $ref: '#/components/schemas/Error' description: error securitySchemes: customerAPIKey: bearerFormat: API key description: 'Send Authorization: Bearer tp_api_… . Create a named, scoped key in the customer dashboard. Keys expire after 30, 90 or 365 days and can be revoked immediately.' scheme: bearer type: http