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

# API Overview

> Base URLs, authentication, pagination, rate limits, and the difference between the Core API and the Customer Portal API

<CardGroup cols={2}>
  <Card title="Production Base URL" icon="globe">
    `https://api.polar.sh/v1`
  </Card>

  <Card title="Sandbox Base URL" icon="flask">
    `https://sandbox-api.polar.sh/v1`
  </Card>

  <Card title="Auth (Organization)" icon="key" href="/integrate/oat">
    Use an **Organization Access Token (OAT)** in the `Authorization: Bearer`
    header
  </Card>

  <Card title="Auth (Customer Portal)" icon="user-lock" href="/api-reference/customer-portal/sessions/create">
    Use a **Customer Access Token** created via `/v1/customer-sessions/`
  </Card>
</CardGroup>

## Base URLs

| Environment | Base URL                          | Purpose                         |
| ----------- | --------------------------------- | ------------------------------- |
| Production  | `https://api.polar.sh/v1`         | Real customers & live payments  |
| Sandbox     | `https://sandbox-api.polar.sh/v1` | Safe testing & integration work |

<Info>
  The sandbox environment is fully isolated—data, users, tokens, and
  organizations created there do not affect production. Create separate tokens
  in each environment.
</Info>

Read more: [Sandbox Environment](/integrate/sandbox)

## Authentication

### Organization Access Tokens (OAT)

Use an **OAT** to act on behalf of your organization (manage products, prices, checkouts, orders, subscriptions, benefits, etc.).

```http theme={null}
Authorization: Bearer polar_oat_xxxxxxxxxxxxxxxxx
```

<Tip>
  Create OATs in your organization settings. See: [Organization Access
  Tokens](/integrate/oat)
</Tip>

<Warning>
  Never expose an OAT in client-side code, public repos, or logs. If leaked, it
  will be revoked automatically by our secret scanning integrations.
</Warning>

### Customer Access Tokens

Do **not** use OATs in the browser. For customer-facing flows, [generate a **Customer Session**](/api-reference/customer-portal/sessions/create) server-side, then use the returned **customer access token** with the **Customer Portal API** to let a signed-in customer view their own orders, subscriptions, and benefits.

## Core API vs Customer Portal API

| Aspect               | Core API                                                                 | Customer Portal API                            |
| -------------------- | ------------------------------------------------------------------------ | ---------------------------------------------- |
| Audience             | Your server / backend                                                    | One of your customer                           |
| Auth Type            | Organization Access Token (OAT)                                          | Customer Access Token                          |
| Scope                | Full org resources (products, orders, subscriptions, benefits, checkout) | Only the authenticated customer’s data         |
| Typical Use          | Admin dashboards, internal tools, automation, provisioning               | Building a custom customer portal or gated app |
| Token Creation       | Via dashboard (manual)                                                   | Via `/v1/customer-sessions/` (server-side)     |
| Sensitive Operations | Yes (create/update products, issue refunds, etc.)                        | No (read/update only what the customer owns)   |

<Note>
  The Customer Portal API is a *restricted* surface designed for safe exposure
  in user-facing contexts (after exchanging a session). It cannot perform
  privileged org-level mutations like creating products or issuing refunds.
</Note>

## Quick Examples

<CodeGroup>
  ```bash curl (Production - Core API) theme={null}
  curl https://api.polar.sh/v1/products/ \
    -H "Authorization: Bearer $POLAR_OAT" \
    -H "Accept: application/json"
  ```

  ```bash curl (Sandbox - Core API) theme={null}
  curl https://sandbox-api.polar.sh/v1/products/ \
    -H "Authorization: Bearer $POLAR_OAT_SANDBOX" \
    -H "Accept: application/json"
  ```

  ```bash curl (Customer Portal API) theme={null}
  curl https://api.polar.sh/v1/customer-portal/orders/ \
    -H "Authorization: Bearer $POLAR_CUSTOMER_TOKEN" \
    -H "Accept: application/json"
  ```
</CodeGroup>

## Using SDKs

All official SDKs accept a `server` parameter for sandbox usage:

<CodeGroup>
  ```ts TypeScript theme={null}
  import { Polar } from "@polar-sh/sdk";

  const polar = new Polar({
  accessToken: process.env.POLAR_ACCESS_TOKEN!,
  server: "sandbox", // omit or use 'production' for live
  });

  ```

  ```py Python theme={null}
  from polar import Polar

  client = Polar(
      access_token=os.environ["POLAR_ACCESS_TOKEN"],
      server="sandbox",
  )
  ```

  ```go Go theme={null}
  s := polargo.New(
    polargo.WithServer("sandbox"),
    polargo.WithSecurity(os.Getenv("POLAR_ACCESS_TOKEN")),
  )
  ```

  ```php PHP theme={null}
  $sdk = Polar\Polar::builder()
      ->setServer('sandbox')
      ->setSecurity(getenv('POLAR_ACCESS_TOKEN'))
      ->build();
  ```
</CodeGroup>

## Pagination

List endpoints in the Polar API support pagination to help you efficiently retrieve large datasets. Use the `page` and `limit` query parameters to control pagination.

### Query Parameters

| Parameter | Type    | Default | Max   | Description                                      |
| --------- | ------- | ------- | ----- | ------------------------------------------------ |
| `page`    | integer | `1`     | -     | Page number, starting from 1                     |
| `limit`   | integer | `10`    | `100` | Number of items to return per page (window size) |

<Info>
  The `page` parameter works as a window offset. For example, `page=2&limit=10`
  means the API will skip the first 10 elements and return the next 10.
</Info>

### Response Format

All paginated responses include a `pagination` object with metadata about the current page and total results:

| Field         | Type    | Description                                                      |
| ------------- | ------- | ---------------------------------------------------------------- |
| `total_count` | integer | Total number of items matching your query across all pages       |
| `max_page`    | integer | Total number of pages available, given the current `limit` value |

### Example

Let's say you want to fetch products with a limit of 100 items per page:

<CodeGroup>
  ```bash Request theme={null}
  curl https://api.polar.sh/v1/products/?page=1&limit=100 \
    -H "Authorization: Bearer $POLAR_OAT" \
    -H "Accept: application/json"
  ```

  ```json Response theme={null}
  {
    "items": [
      {
        "id": "...",
        "name": "Product 1",
        ...
      },
      ...
    ],
    "pagination": {
      "total_count": 250,
      "max_page": 3
    }
  }
  ```
</CodeGroup>

In this example:

* `total_count=250` indicates there are 250 total products
* `limit=100` means each page contains up to 100 products
* `max_page=3` means you need to make 3 requests to retrieve all products (pages 1, 2, and 3)

<Tip>
  To retrieve all pages, increment the `page` parameter from `1` to `max_page`.
  Our SDKs provide built-in pagination helpers to automatically iterate through
  all pages.
</Tip>

## Rate Limits

Polar API has rate limits to ensure fair usage and maintain performance. Limits differ between the **Sandbox** and **Production** environments.

### Production

* **500 requests per minute** per organization/customer or OAuth2 Client.

### Sandbox

* **100 requests per minute** per organization/customer or OAuth2 Client.

Unauthenticated [validation](/api-reference/customer-portal/license-keys/validate), [activation](/api-reference/customer-portal/license-keys/activate), and [deactivation](/api-reference/customer-portal/license-keys/deactivate) endpoints are limited to **3 requests per second** in both environments.

If you exceed the rate limit, you will receive a `429 Too Many Requests` response. The response will include a `Retry-After` header indicating how long you should wait before making another request.

<Note>
  Organizations requiring higher rate limits for production workloads may
  contact our support team to discuss elevated limits.
</Note>
