> ## Documentation Index
> Fetch the complete documentation index at: https://docs.macropay.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Type-hinted Python SDK for Macropay — sync or async billing, payments, and agent metering as the merchant of record.

Ship billing in a few lines of Python. The SDK wraps the full Macropay API — products, checkout, customers, usage meters, and agent signals — so you write business logic, not HTTP plumbing. Macropay is the **merchant of record**, which means the same client that creates a checkout also handles sales tax and VAT remittance, dispute management, and PCI scope on your behalf.

Every method is fully type-hinted, ships with both synchronous and asynchronous clients (powered by [HTTPX](https://www.python-httpx.org/)), and validates request and response payloads with [Pydantic](https://docs.pydantic.dev/latest/) — so most mistakes surface in your editor, not in production.

## Install

```bash Terminal theme={null}
pip install macropay
```

## Authenticate

Create a client with an [organization access token](/integrate/oauth2/introduction) or any valid bearer token. The token determines which organization and scopes the calls run against.

```python theme={null}
from macropay import Macropay

client = Macropay(
    access_token="<YOUR_BEARER_TOKEN_HERE>",
)
```

<Tip>
  Keep tokens out of source control. Read them from the environment instead — e.g. `access_token=os.environ["MACROPAY_TOKEN"]`.
</Tip>

## Your first call

List the benefits granted to the authenticated user. List endpoints are paginated, and the SDK exposes a cursor you can walk until it returns `None`:

```python theme={null}
res = client.users.benefits.list()

while res is not None:
    for benefit in res.items:
        print(benefit.id, benefit.type)

    res = res.next()
```

## Async usage

For concurrent workloads — webhook fan-out, batch event ingestion, agent loops — use the async client and `await` each call:

```python theme={null}
import asyncio
from macropay import Macropay


async def main():
    async with Macropay(access_token="<YOUR_BEARER_TOKEN_HERE>") as client:
        res = await client.products.list()
        for product in res.items:
            print(product.id, product.name)


asyncio.run(main())
```

## Sandbox environment

Point the client at the [sandbox](/integrate/sandbox) to develop and test against isolated data with no real money movement. Pass `server="sandbox"` when you instantiate the client — everything else stays identical:

```python theme={null}
client = Macropay(
    server="sandbox",
    access_token="<YOUR_SANDBOX_TOKEN_HERE>",
)
```

<Note>
  Sandbox and production use separate tokens and separate data. Promote to production by swapping the token and dropping the `server` argument.
</Note>

## Metering AI and agent usage

The same client powers Macropay's AI billing primitives. Ingest activity and outcome [signals](/features/usage-based-billing/introduction) for an agent, then bill by usage, activity, or verified outcome:

```python theme={null}
# Report that an agent completed a unit of work
client.events.ingest(events=[
    {
        "name": "agent.task_completed",
        "external_customer_id": "cus_acme",
        "metadata": {
            "agent_id": "support-triage",
            "tokens": 18420,
            "outcome": "ticket_resolved",
        },
    }
])
```

Macropay aggregates these events into meters and ties them to metered prices, so you can charge for outcomes (a resolved ticket, a booked meeting) while tracking **agentic margin** — billed revenue against the underlying AI cost — per agent.

## Read the reference

Every resource, parameter, and response model is documented in the [API reference](/api-reference/introduction). The SDK method names mirror the REST structure (`client.products`, `client.customers`, `client.checkouts`, `client.events`), so anything you find there maps directly to a typed Python call.
