Skip to main content

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 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​

HeaderExampleDescription
X-User-Tokenapi-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 TypeUse CasePayment RecordInitial Status
permissionGrant content accessNoapproved
reportExternal sale + payment recordYesapproved
salePublica.la checkout flowYespending

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
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​

OperationMethodEndpointDescription
List ordersGET/api/v3/ordersRetrieve orders with filters and pagination
Get orderGET/api/v3/orders/{id}Get a specific order by ID
Create orderPOST/api/v3/ordersCreate a new order
Bulk createPOST/api/v3/orders/bulkCreate multiple orders at once
Update orderPUT/api/v3/orders/{id}Update order expiration
Delete orderDELETE/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
IncludeDescription
userUser information (id, uuid, external_id, email) - all IDs as strings
productsProduct details with URLs and pricing
pending_checkoutCheckout 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​

  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
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​

StatusDescription
pendingSale order awaiting payment
approvedOrder active, user has access
pausedAccess temporarily suspended
cancelledOrder 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​


See Also​

X

Graph View