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

# Run Your Agent

> A complete, production-ready agent example.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import os
    import atexit
    import httpx
    from oculus_sdk import OculusClient
    from oculus_sdk.exceptions import OculusAuthError, TokenRevokedException

    client = OculusClient(
        client_id=os.environ["AGENT_CLIENT_ID"],
        client_secret=os.environ["AGENT_CLIENT_SECRET"],
        base_url=os.environ.get("ANTI_AI_URL", "https://api.antiailabs.com"),
    )
    atexit.register(client.stop)

    def fetch_customer(customer_id: str) -> dict:
        token = client.get_token(scope="stripe:customer:read")
        response = httpx.get(
            f"https://api.stripe.com/v1/customers/{customer_id}",
            headers={"Authorization": f"Bearer {token}"},
        )
        response.raise_for_status()
        return response.json()

    def process_payment(amount: int, currency: str) -> dict:
        token = client.get_token(scope="stripe:charge:write")
        response = httpx.post(
            "https://api.stripe.com/v1/charges",
            headers={"Authorization": f"Bearer {token}"},
            json={"amount": amount, "currency": currency},
        )
        response.raise_for_status()
        return response.json()
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    import { OculusClient } from '@oculus/sdk';
    import axios from 'axios';

    const client = new OculusClient({
      clientId: process.env.AGENT_CLIENT_ID!,
      clientSecret: process.env.AGENT_CLIENT_SECRET!,
      baseUrl: process.env.ANTI_AI_URL ?? 'https://api.antiailabs.com',
      onTokenRevoked: (jti) => {
        console.error(`Token ${jti} revoked — agent access terminated`);
      },
    });

    process.on('SIGTERM', () => client.destroy());

    async function fetchCustomer(customerId: string) {
      const token = await client.getToken('stripe:customer:read');
      const { data } = await axios.get(
        `https://api.stripe.com/v1/customers/${customerId}`,
        { headers: { Authorization: `Bearer ${token}` } }
      );
      return data;
    }
    ```
  </Tab>
</Tabs>

## Key patterns

**One client per agent** — create `OculusClient` once at startup and reuse it. Creating a new instance per request bypasses the token cache.

**One scope per operation** — request only the scope needed for each call. Don't request `stripe:*` when you only need `stripe:customer:read`.

**Handle `TokenRevokedException`** — this means an operator intentionally revoked your agent. Don't silently retry — alert your team.

**Register a shutdown handler** — call `client.stop()` (Python) or `client.destroy()` (TypeScript) on shutdown to cleanly stop background TRL polling.
