Publinza API
v1Read your account, the Marketplace, your orders and invoices, and - for publishers - your websites and the orders on them. Version 1 is read-only.
Getting access
API access requires approval. An administrator reviews every request before any key can be created.
- Request access. In Account → API access, say what your integration does and choose the scopes it needs.
- Admin approval. An administrator approves the request - for some or all of the scopes you asked for - or explains why not. Until then the request shows as pending.
- Create a key. Once approved, create keys on the same page, each with some or all of your approved scopes.
- Use approved scopes. Every request is checked against your approval as it stands now. If access is revoked, your keys are revoked with it; if a scope is removed, keys holding it are revoked. Revoked keys stay revoked.
Authentication
Once your access is approved, create an API key in your account and send it as a bearer token. A key is shown once; Publinza stores only a hash of it. A key acts as you and never more: each scope reads only your own data, and you can rotate or revoke a key at any time.
curl -H "Authorization: Bearer pz_xxxxxxxxxxxx_..." \ https://YOUR-PUBLINZA-HOST/api/v1/orders?limit=20
There is no administrator API. The machine-readable description is at /api/v1/openapi.json (OpenAPI 3.1).
Scopes
Explicit, read-only. A key holds only scopes approved for its owner's account that the account's roles allow.
account:read- Read your own account: name, email address and account type. (any account)marketplace:read- Browse approved Marketplace websites and their offers, as you can on the website. (advertiser accounts)orders:read- Read the orders you placed, their status and their invoices. (advertiser accounts)websites:read- Read your own websites and offers, and their review and publication state. (publisher accounts)publisher:orders:read- Read orders placed on your websites, what they pay you and which need your action. (publisher accounts)
Endpoints
GET
/api/v1no keyThe API version and where its documentation is. No key needed.
{ "name": "Publinza API", "version": "v1", "documentation": "/developers", "openapi": "/api/v1/openapi.json" }GET
/api/v1/openapi.jsonno keyThis API as an OpenAPI 3.1 document. No key needed.
{ "openapi": "3.1.0" }GET
/api/v1/categoriesno keyThe active Marketplace categories. No key needed.
{ "data": [ { "name": "Technology", "slug": "technology" } ] }GET
/api/v1/meaccount:readThe account the API key belongs to.
{ "data": { "id": "cm...", "name": "Ada", "email": "ada@example.com", "emailVerified": true, "accountType": "ADVERTISER", "createdAt": "2026-01-01T00:00:00.000Z" } }GET
/api/v1/marketplace/websitesmarketplace:readApproved Marketplace websites and their offers at the prices advertisers see, 20 per page. The same filters as the Marketplace page.
Parameters: q (query) - Search text.; category (query) - A category slug.; type (query) - GUEST_POST or LINK_INSERTION.; minPrice (query) - Minimum price, in whole dollars.; maxPrice (query) - Maximum price, in whole dollars.; page (query) - Page number, from 1.
{ "data": [ { "id": "cm...", "name": "Example Media", "domain": "example.com", "description": null, "countryCode": "US", "languageCode": "en", "publisher": "Example Media", "categories": [ { "name": "Technology", "slug": "technology" } ], "rating": { "average": null, "count": 0 }, "offers": [ { "id": "cm...", "type": "GUEST_POST", "price": { "amountCents": 25000, "currency": "USD" }, "turnaroundDays": 7, "description": null } ] } ], "pagination": { "page": 1, "pageSize": 20, "total": 1, "totalPages": 1 } }GET
/api/v1/marketplace/websites/{websiteId}marketplace:readOne approved Marketplace website.
Parameters: websiteId (path) - The website id.
{ "data": { "id": "cm...", "name": "Example Media", "domain": "example.com" } }GET
/api/v1/ordersorders:readOrders you placed, newest first, with what you paid and their invoice when issued.
Parameters: limit (query) - 1-50, default 20.; cursor (query) - nextCursor from the previous page.
{ "data": [ { "id": "cm...", "reference": "AB12CD34", "status": "IN_PROGRESS", "createdAt": "2026-01-01T00:00:00.000Z", "website": { "name": "Example Media", "domain": "example.com" }, "offerType": "GUEST_POST", "amount": { "amountCents": 25000, "currency": "USD" }, "paymentStatus": "CONFIRMED", "invoice": { "number": "INV-2026-00001", "issuedAt": "2026-01-01T00:00:00.000Z" } } ], "pagination": { "limit": 20, "nextCursor": null } }GET
/api/v1/orders/{orderId}orders:readOne order you placed.
Parameters: orderId (path) - The order id.
{ "data": { "id": "cm...", "reference": "AB12CD34", "status": "COMPLETED" } }GET
/api/v1/orders/{orderId}/invoiceorders:readThe invoice issued when the order's payment was confirmed, with download links. 404 until it is issued.
Parameters: orderId (path) - The order id.
{ "data": { "number": "INV-2026-00001", "issuedAt": "2026-01-01T00:00:00.000Z", "total": { "amountCents": 25000, "currency": "USD" }, "paymentMethod": "UPI_MANUAL", "status": "PAID", "downloads": { "pdf": "/api/v1/orders/cm.../invoice/pdf", "docx": "/api/v1/orders/cm.../invoice/docx" } } }GET
/api/v1/orders/{orderId}/invoice/pdforders:readThe invoice as a PDF file.
Parameters: orderId (path) - The order id.
Returns a file (application/pdf).
GET
/api/v1/orders/{orderId}/invoice/docxorders:readThe invoice as a Microsoft Word (.docx) file.
Parameters: orderId (path) - The order id.
Returns a file (application/vnd.openxmlformats-officedocument.wordprocessingml.document).
GET
/api/v1/publisher/websiteswebsites:readYour websites, newest first, with their review state and your offers at your price.
Parameters: limit (query) - 1-50, default 20.; cursor (query) - nextCursor from the previous page.
{ "data": [ { "id": "cm...", "name": "Example Media", "domain": "example.com", "reviewStatus": "APPROVED", "publishedOnMarketplace": true, "offers": [ { "id": "cm...", "type": "GUEST_POST", "yourPrice": { "amountCents": 25000, "currency": "USD" }, "active": true, "turnaroundDays": 7 } ] } ], "pagination": { "limit": 20, "nextCursor": null } }GET
/api/v1/publisher/orderspublisher:orders:readOrders placed on your websites, newest first, with what you are paid and whether they need your action.
Parameters: limit (query) - 1-50, default 20.; cursor (query) - nextCursor from the previous page.
{ "data": [ { "id": "cm...", "reference": "AB12CD34", "status": "REQUESTED", "requiresAction": true, "website": { "name": "Example Media", "domain": "example.com" }, "offerType": "GUEST_POST", "yourAmount": { "amountCents": 25000, "currency": "USD" } } ], "pagination": { "limit": 20, "nextCursor": null } }
Pagination
Lists of your own records use a cursor: pass limit (1-50, default 20) and the nextCursor from the previous response as cursor. nextCursor is null on the last page.
Marketplace websites are paged like the Marketplace page: page, 20 per page, with the total.
Rate limits and versioning
120 requests per minute per API key and 240 per account across its keys; 60 per minute per address for the endpoints that need no key and for failed authentications. Over the limit, the answer is 429 with a Retry-After header.
The version is in the path. Within v1 fields are only added; anything that would break a client becomes v2.
Writes, when they come, accept an Idempotency-Key header: a retry returns the first answer instead of acting twice.
Errors
One shape for every error; every response carries X-Request-Id.
{ "error": { "code": "insufficient_scope", "message": "...", "requestId": "..." } }400invalid_request- The request is not valid.401unauthorized- A valid API key is required. Send it as: Authorization: Bearer <key>.403insufficient_scope- This API key does not have the scope this endpoint needs.403forbidden- Your account cannot use this endpoint.403access_not_approved- This account's API access is not approved. Request access from your account's API Access page.403scope_not_approved- This API key holds a scope your account's API access no longer allows. Create a new key.404not_found- Not found.409idempotency_conflict- This Idempotency-Key was already used for a different request.429rate_limited- Too many requests. Wait, then try again.500internal_error- Something went wrong. Try again later.
Keep keys secret