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

# Orders API Overview

Manage customer purchases and content access on your Publica.la platform.

## Features

- **Cursor-based pagination** for efficient, consistent results across large datasets
- **Response shaping** with `include` and `fields` parameters to control payload size
- **Advanced filtering** by status, type, user, product, and date ranges
- **Sorting** by creation or update date
- **Bulk operations** for creating up to 100 orders in a single request

---

## Authentication

| Header           | Example         | Description                                                          |
| ---------------- | --------------- | -------------------------------------------------------------------- |
| **X-User-Token** | `api-abc123...` | API token generated in your dashboard. **Header-only for security.** |

All requests **must** be performed over HTTPS.

```bash
curl -X GET "https://yourstore.publica.la/api/v3/orders" \
  -H "X-User-Token: api-abc123..." \
  -H "Accept: application/json"
```

---

## Available Order Types

The Orders API supports three order types:

| Order Type                                               | Use Case                       | Payment Record | Initial Status |
| -------------------------------------------------------- | ------------------------------ | -------------- | -------------- |
| **[permission](./create-order/orders-v3-permission.md)** | Grant content access           | No             | `approved`     |
| **[report](./create-order/orders-v3-report.md)**         | External sale + payment record | Yes            | `approved`     |
| **[sale](./create-order/orders-v3-sale.md)**             | Publica.la checkout flow       | Yes            | `pending`      |

### Choosing the Right Order Type

```mermaid
flowchart TD
    A[Who handles payment?] --> B{Your platform}
    A --> C{Publica.la}

    C --> D[SALE<br/>Publica.la checkout + payment]

    B --> E[What content is sold?]

    E --> F[PERMISSION<br/>Own catalog only<br/>No payment record]
    E --> G[REPORT<br/>Own or marketplace<br/>Creates payment record]

    class D,F,G accent
```

#### Permission Orders

Use when **you process payments in your own system** and only need Publica.la for content delivery:

- You collect payment externally and grant access to your own content
- Migrating legacy access from a previous system
- Promotional access: free trials, giveaways, review copies
- Corporate/institutional bulk access

No payment record is created in Publica.la.

#### Report Orders

Use when **you process payments externally but need financial records** in Publica.la:

- Selling marketplace content (third-party content with revenue sharing)
- Partner integrations where you need to track sales in Publica.la
- Any scenario requiring payment records for accounting/reporting

:::info Marketplace Content
Report orders are required for marketplace content. Contact support to enable marketplace sales.
:::

#### Sale Orders

Use when **Publica.la handles the payment**:

- Customer pays directly through Publica.la's checkout
- Automatic gateway selection (Stripe, MercadoPago) based on currency
- No need to handle PCI compliance
- Ideal for "Buy Now" buttons that redirect to Publica.la

---

## API Endpoints

| Operation    | Method   | Endpoint              | Description                                 |
| ------------ | -------- | --------------------- | ------------------------------------------- |
| List orders  | `GET`    | `/api/v3/orders`      | Retrieve orders with filters and pagination |
| Get order    | `GET`    | `/api/v3/orders/{id}` | Get a specific order by ID                  |
| Create order | `POST`   | `/api/v3/orders`      | Create a new order                          |
| Bulk create  | `POST`   | `/api/v3/orders/bulk` | Create multiple orders at once              |
| Update order | `PUT`    | `/api/v3/orders/{id}` | Update order expiration                     |
| Delete order | `DELETE` | `/api/v3/orders/{id}` | Cancel an order                             |

---

## Response Shaping

Control your response payload size and content:

### The `include` Parameter

Request additional data blocks:

```bash
GET /api/v3/orders?include=user,products
```

| Include            | Description                                                          |
| ------------------ | -------------------------------------------------------------------- |
| `user`             | User information (id, uuid, external_id, email) - all IDs as strings |
| `products`         | Product details with URLs and pricing                                |
| `pending_checkout` | Checkout URL for pending sale orders                                 |

### The `fields` Parameter

Trim the response to only the fields you need:

```bash
GET /api/v3/orders?fields=id,status,type
```

### Combining Both

```bash
GET /api/v3/orders?include=user,products&fields=id,status,user,products
```

---

## Cursor Pagination

Cursor-based pagination provides efficient, consistent results across large datasets:

```json
{
  "data": [...],
  "links": {
    "next": "https://yourstore.publica.la/api/v3/orders?cursor=eyJjcmVhdGVkX2F0...",
    "prev": null
  },
  "meta": {
    "has_more": true
  }
}
```

### Pagination Workflow

1. Make initial request without `cursor`
2. Store `links.next` token
3. Use `cursor=<token>` for next page
4. Continue until `meta.has_more` is `false`

:::tip Best Practice
Always use `meta.has_more` to detect the end of results, not by counting items.
:::

---

## Order Lifecycle

```
Permission/Report:    [Create] ──────────────────────────► approved ✓
                                                              │
Sale Order:           [Create] ► pending ──[User Pays]──► approved ✓
                                     │                        │
                                     └──────[Expires]────► cancelled ✗
                                                              │
All Types:                            approved ◄──► paused    │
                                          │           │       │
                                          └───────────┴───► cancelled ✗
```

### Status Values

| Status      | Description                     |
| ----------- | ------------------------------- |
| `pending`   | Sale order awaiting payment     |
| `approved`  | Order active, user has access   |
| `paused`    | Access temporarily suspended    |
| `cancelled` | Order cancelled, access revoked |

---

## Expiration Dates

`expiration_date` sets the day a product's access ends. It is optional, uses the `YYYY-MM-DD` format, and `null` grants access with no end date.

On creation (`POST /api/v3/orders` and `POST /api/v3/orders/bulk`), the date must be later than the current day in your store's timezone, so the earliest value you can send is tomorrow. Anything else returns `422 Unprocessable Entity` with "The expiration date must be a future date". The API rejects the current day along with past dates: an order that carries today's date is already expired the moment it is stored.

Updates and cancellations still accept past dates. Revoking access retroactively on an order that already exists is a supported operation. See [Update & Cancel](./orders-v3-update-cancel.md).

---

## Common Response Format

All endpoints return consistent JSON structures:

### Single Order Response

```json
{
  "data": {
    "id": "12345",
    "uuid": "275ca6c4-a815-4f64-8198-759a296dd495",
    "external_id": "ORDER-123",
    "type": "permission",
    "status": "approved",
    "unit_price": 29.99,
    "currency_id": "USD",
    "created_at": "2025-12-03T22:43:44.000000Z",
    "updated_at": "2025-12-03T22:43:44.000000Z"
  }
}
```

### List Response with Pagination

```json
{
  "data": [
    {
      "id": "12345",
      "uuid": "...",
      "external_id": "...",
      "type": "...",
      "status": "..."
    }
  ],
  "links": {
    "next": "https://...?cursor=...",
    "prev": null
  },
  "meta": {
    "has_more": true
  }
}
```

---

## Error Handling

### Validation Errors (422)

```json
{
  "message": "The given data was invalid.",
  "errors": {
    "user": ["The user field is required."],
    "products.0.id": ["The product does not exist."]
  }
}
```

### Authentication Errors (401)

```json
{
  "message": "Unauthenticated."
}
```

### Not Found (404)

```json
{
  "message": "Order not found."
}
```

---

## Quick Start Examples

### List Recent Orders

```bash
curl -X GET "https://yourstore.publica.la/api/v3/orders?per_page=10&include=user,products" \
  -H "X-User-Token: your-api-token" \
  -H "Accept: application/json"
```

### Create a Permission Order

```bash
curl -X POST "https://yourstore.publica.la/api/v3/orders" \
  -H "X-User-Token: your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "permission",
    "external_reference": "MY-ORDER-001",
    "user": {
      "email": "customer@example.com"
    },
    "products": [
      {
        "type": "content",
        "id": "9781234567890"
      }
    ]
  }'
```

---

## Rate Limiting

Two limits apply: a per-token burst of **60 requests/minute** and a **daily read quota** of 2,000 reads/token plus 5,000/store (`GET`/`HEAD` only; writes and bulk operations are separate). Exceeding either returns `429 Too Many Requests` with a `Retry-After` header.

To track order status, query the list endpoint with `filter[updated_at]` instead of polling each order by ID. See the [API Overview](../../rest-api/overview.md#rate-limiting-and-flood-protection) for full details.

---

## Next Steps

- **[List Orders](./orders-v3-list.md)** - Query and filter orders
- **[Get Order](./orders-v3-get.md)** - Retrieve order details
- **[Permission Orders](./create-order/orders-v3-permission.md)** - Grant access without payment
- **[Report Orders](./create-order/orders-v3-report.md)** - Record external sales
- **[Sale Orders](./create-order/orders-v3-sale.md)** - Publica.la checkout flow
- **[Bulk Operations](./create-order/orders-v3-bulk.md)** - Create multiple orders
- **[Update & Cancel](./orders-v3-update-cancel.md)** - Manage existing orders

---

## See Also

- [API Authentication](../../rest-api/overview.md)
- [Content API](../content/content-v3-overview.md)
- [Migration Guide](./orders-v1-to-v3-migration.md) - Upgrading from API v1
