Orders API
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
includeandfieldsparameters 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.
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 | Grant content access | No | approved |
| report | External sale + payment record | Yes | approved |
| sale | Publica.la checkout flow | Yes | pending |
Choosing the Right Order Type
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
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:
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:
GET /api/v3/orders?fields=id,status,type
Combining Both
GET /api/v3/orders?include=user,products&fields=id,status,user,products
Cursor Pagination
Cursor-based pagination provides efficient, consistent results across large datasets:
{
"data": [...],
"links": {
"next": "https://yourstore.publica.la/api/v3/orders?cursor=eyJjcmVhdGVkX2F0...",
"prev": null
},
"meta": {
"has_more": true
}
}
Pagination Workflow
- Make initial request without
cursor - Store
links.nexttoken - Use
cursor=<token>for next page - Continue until
meta.has_moreisfalse
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.
Common Response Format
All endpoints return consistent JSON structures:
Single Order Response
{
"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
{
"data": [
{
"id": "12345",
"uuid": "...",
"external_id": "...",
"type": "...",
"status": "..."
}
],
"links": {
"next": "https://...?cursor=...",
"prev": null
},
"meta": {
"has_more": true
}
}
Error Handling
Validation Errors (422)
{
"message": "The given data was invalid.",
"errors": {
"user": ["The user field is required."],
"products.0.id": ["The product does not exist."]
}
}
Authentication Errors (401)
{
"message": "Unauthenticated."
}
Not Found (404)
{
"message": "Order not found."
}
Quick Start Examples
List Recent Orders
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
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": "[email protected]"
},
"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 for full details.
Next Steps
- List Orders - Query and filter orders
- Get Order - Retrieve order details
- Permission Orders - Grant access without payment
- Report Orders - Record external sales
- Sale Orders - Publica.la checkout flow
- Bulk Operations - Create multiple orders
- Update & Cancel - Manage existing orders
See Also
- API Authentication
- Content API
- Migration Guide - Upgrading from API v1