Invoices
One endpoint, and the only paginated one in the API.
Invoices are the record of what you were charged and when. The endpoint returns totals, status, and links to the hosted invoice page and PDF. Card details and payment methods are never included — those live only in the billing portal.
List invoices
GET
/invoices Paginated billing history, newest first.
Returns one page of invoices, newest first. Pagination is cursor-based: pass the last id of a page as starting_after to get the next one, and stop when has_more is false. Draft invoices are filtered out, so everything you see is final.
Query parameters
| Name | Type | Description |
|---|---|---|
limit Optional | integer | Page size, between 1 and 100. Default 10 |
starting_after Optional | string | Invoice id to continue from. Use the id of the last item on the previous page. |
status Optional | string | Return only invoices in this state. openpaiduncollectiblevoid |
Example request
cURL
curl https://api.proxycharm.com/api/v1/public/invoices?limit=10&status=paid \
-H "Authorization: Bearer $PROXYCHARM_API_KEY" Python
import os
import requests
API_KEY = os.environ["PROXYCHARM_API_KEY"]
response = requests.get(
"https://api.proxycharm.com/api/v1/public/invoices?limit=10&status=paid",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=30,
)
payload = response.json()
if not payload["success"]:
raise RuntimeError(payload["error"]["message"])
print(payload["data"]) Node.js
const apiKey = process.env.PROXYCHARM_API_KEY;
const response = await fetch("https://api.proxycharm.com/api/v1/public/invoices?limit=10&status=paid", {
method: "GET",
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
const payload = await response.json();
if (!payload.success) {
throw new Error(payload.error.message);
}
console.log(payload.data); Go
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
type envelope struct {
Success bool `json:"success"`
Data json.RawMessage `json:"data"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
func main() {
req, err := http.NewRequest("GET", "https://api.proxycharm.com/api/v1/public/invoices?limit=10&status=paid", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("PROXYCHARM_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var payload envelope
if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
panic(err)
}
if !payload.Success {
panic(payload.Error.Message)
}
fmt.Println(string(payload.Data))
} PHP
<?php
$apiKey = getenv("PROXYCHARM_API_KEY");
$ch = curl_init("https://api.proxycharm.com/api/v1/public/invoices?limit=10&status=paid");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . $apiKey,
],
]);
$payload = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!$payload["success"]) {
throw new RuntimeException($payload["error"]["message"]);
}
print_r($payload["data"]); Example response
200 OK
{
"success": true,
"data": {
"items": [
{
"id": "in_1QRstuVWXyz01AbCdEfGhIjK",
"number": "B1C2D3E4-0001",
"status": "paid",
"amount_cents": 1200,
"currency": "usd",
"amount_display": "12.00 USD",
"created_at": "2026-02-18T09:00:02Z",
"billing_reason": "subscription_cycle",
"hosted_invoice_url": "https://invoice.stripe.com/i/acct_1Abc/live_YWNjdF8xQWJj",
"invoice_pdf": "https://pay.stripe.com/invoice/acct_1Abc/live_YWNjdF8xQWJj/pdf"
}
],
"has_more": false
},
"error": null,
"context": {
"affected_entities": [],
"suggested_next_actions": [
"open_billing_portal",
"get_my_subscription"
],
"warnings": []
},
"request_id": null,
"timestamp": "2026-02-18T09:31:04.512Z"
} Response fields
| Name | Type | Description |
|---|---|---|
items | array<object> | Invoices on this page, newest first. |
id | string | Invoice id, prefixed in_. Also the pagination cursor for starting_after. |
number | string | null | Human-readable invoice number. |
status | string | One of open, paid, uncollectible, void. Drafts are never returned. |
amount_cents | integer | Invoice total in minor units. |
currency | string | Lowercase ISO 4217 currency code. |
amount_display | string | Pre-formatted total, e.g. 12.00 USD. |
created_at | string | null | ISO timestamp the invoice was issued. |
billing_reason | string | null | Why the invoice exists, e.g. subscription_create, subscription_cycle, subscription_update. |
hosted_invoice_url | string | null | Hosted page where the invoice can be viewed or paid. |
invoice_pdf | string | null | Direct link to the invoice PDF. |
has_more | boolean | True when a later page exists. |
Errors
| Code | HTTP | What it means |
|---|---|---|
ORGANIZATION_PERMISSION_DENIED | 403 | The workspace id in the path belongs to another organization, or the profile that created the key is not an owner. Invoices require owner-level access. |
INVOICE_STATUS_INVALID | 200 | The status filter is not a customer-visible invoice status. |
INVOICE_LIST_FAILED | 200 | The billing provider rejected the invoice list call. |
API_KEY_INVALID | 401 | The Authorization header is missing the key prefix, the key does not exist, or its organization has been deleted. |
API_KEY_REVOKED | 401 | The key was revoked in the dashboard. |
API_KEY_EXPIRED | 401 | The key passed the expiry date it was created with. |
RATE_LIMIT_EXCEEDED | 429 | The key exceeded its request budget for the current window. |