Download OpenAPI specification:
The Publizon Reporting API provides a clear and consistent method for outbound customers (retailers and partners) to report back to Publizon on earnings, content consumption, and reader demography.
An API key and a set of credentials (email and password) must be used to authenticate. Use the auth api to get the short-lived token needed to call the reporting api endpoints.
Requests are limited to 5 per second. Requests exceeding the limit will be rejected with a 429 Too Many Requests response.
The companyId header is only relevant when your user belongs to more than one company. In that case it must be set on every request to indicate which company the call is being made on behalf of. If this applies to you, contact Publizon to obtain your company id.
This endpoint allows partners to upload structured data regarding the financial performance of content sold or consumed via their platform. It covers the flow of financial information back to Publizon.
retailerTransactionId is your own id for each transaction, and it protects against double reporting: we never insert the same id twice for your account. If a request fails (e.g. a timeout) and you retry it with the same ids, the retry is rejected with DUPLICATE_RETAILER_TRANSACTION_ID when the original request already went through — so it is safe to retry without risking duplicate transactions. A duplicate id, whether repeated within the batch or already reported earlier, rejects the whole request; no transactions are inserted.
UNAUTHORIZED: Authentication failed or the caller is not allowed to access this endpoint.FORBIDDEN: The caller is authenticated but does not have permission to report revenue data.PRODUCT_NOT_FOUND: One or more provided product identifiers do not exist. The request is rejected as a whole — if any product is missing, no transactions from the batch are inserted.COMPANY_NOT_FOUND: The company specified by the companyId header does not exist.DUPLICATE_RETAILER_TRANSACTION_ID: One or more retailerTransactionId values have already been reported by this retailer. The request is rejected as a whole.UNPROCESSABLE_ENTITY: The request payload is invalid.required | Array of objects (RevenueTransaction) [ 1 .. 250 ] items |
{- "transactions": [
- {
- "customerId": "string",
- "productIdentifier": "string",
- "retailerTransactionId": "string",
- "saleDateTime": "2019-08-24T14:15:22Z",
- "quantity": {
- "value": 0.1,
- "type": "Units"
}, - "unitAmount": 0.1,
- "totalAmount": 0.1,
- "currency": "DKK",
- "market": "AD"
}
]
}{- "errorCode": "UNAUTHORIZED",
- "message": "string",
- "traceId": "string"
}This endpoint allows publishers and sales channels to export transactional revenue data.
Response:
customerId: Optional customer identifier from the retailer system.productIdentifier: The primary identifier for the title, typically the ISBN-13.retailerTransactionId: A unique string generated by the retailer to ensure each consumption event or sale is reported only once and can be audited.quantity: The numerical volume of usage. Depending on the QuantityType, this could be a whole number (units / parts) or a decimal (hours/percentage).saleTimestamp: Datetime when the transaction occurred.unitAmount: The calculated rate paid per single unit of the chosentotalAmount: The total net revenue or royalty share to be paid to the publisher for this specific line item.market: The geographic market of the user (e.g., SE, DK, FI).UNAUTHORIZED: Authentication failed or the caller is not allowed to access this endpoint.FORBIDDEN: The caller is authenticated but does not have permission to read revenue data.UNPROCESSABLE_ENTITY: Query parameters are invalid.| startDate required | string The start date for the query range (ISO 8601 format). The range cannot exceed 31 days. |
| endDate required | string The end date for the query range (ISO 8601 format). |
[- {
- "saleTimestamp": "string",
- "customerId": "string",
- "productIdentifier": "string",
- "retailerTransactionId": "string",
- "quantity": {
- "value": 0.1,
- "type": "Units"
}, - "unitAmount": 0,
- "totalAmount": 0,
- "currency": "DKK",
- "market": "string"
}
]This endpoint handles the reporting of how end-users consume the digital content. It is only available to outbound channels.
UNAUTHORIZED: Authentication failed or the caller is not allowed to access this endpoint.FORBIDDEN: The caller is authenticated but does not have permission to report usage data.PRODUCT_NOT_FOUND: One or more provided product identifiers do not exist. The request is rejected as a whole — if any product is missing, no usage events from the batch are inserted.COMPANY_NOT_FOUND: The company specified by the companyId header does not exist.UNPROCESSABLE_ENTITY: The request payload is invalid.required | Array of objects (ProductUsageReport) [ 1 .. 50 ] items |
{- "products": [
- {
- "subscriptionId": "string",
- "customerId": "string",
- "productIdentifier": "string",
- "usages": [
- {
- "part": 0,
- "format": "Epub",
- "startPosition": 0,
- "endPosition": 0,
- "usageId": "string",
- "usageDateTime": "2019-08-24T14:15:22Z"
}
]
}
]
}{- "errorCode": "UNAUTHORIZED",
- "message": "string",
- "traceId": "string"
}This endpoint allows publishers and sales channels to export transactional usage data.
Response:
usageTimestamp: Datetime when the usage started.customerId: Optional customer identifier from the retailer system.productIdentifier: The primary identifier for the title, typically the ISBN-13.part: Part index reported for the usage event.format: Format in which the usage happened.startPosition: Start position in seconds (audiobooks) or words (ebooks).endPosition: End position in seconds (audiobooks) or words (ebooks).usageId: Unique identifier generated by the retailer for de-duplication.UNAUTHORIZED: Authentication failed or the caller is not allowed to access this endpoint.FORBIDDEN: The caller is authenticated but does not have permission to read usage data.UNPROCESSABLE_ENTITY: Query parameters are invalid.| startDate required | string The start date for the query range (ISO 8601 format). The range cannot exceed 31 days. |
| endDate required | string The end date for the query range (ISO 8601 format). |
[- {
- "customerId": "string",
- "productIdentifier": "string",
- "usageTimestamp": "string",
- "part": 0,
- "format": "Epub",
- "startPosition": 0,
- "endPosition": 0,
- "usageId": "string"
}
]This endpoint allows retailers to export the retail orders they have placed with Publizon.
Response:
orderId: The Publizon order identifier.orderTimestamp: Datetime when the order was registered.retailerOwnId: The order id assigned by the retailer in their own system.productIdentifier: The primary identifier for the title, typically the ISBN-13.contentType: The type of content ordered.publisher: The publisher the ordered title belongs to.buyerId: Optional buyer identifier from the retailer system.country: The country of the order.deliverySource: The source the order was delivered from.language: The language of the ordered title.netPrice: The net price of the content.discountNetPrice: Effective net price after discount; equals netPrice when there is no discount.protection: The content protection applied to the order. Chosen by the publisher.UNAUTHORIZED: Authentication failed or the caller is not allowed to access this endpoint.FORBIDDEN: The caller is authenticated but does not have permission to read retail orders.UNPROCESSABLE_ENTITY: Query parameters are invalid.| startDate required | string The start date for the query range (ISO 8601 format). The range cannot exceed 31 days. |
| endDate required | string The end date for the query range (ISO 8601 format). |
[- {
- "productIdentifier": "string",
- "orderId": "string",
- "orderTimestamp": "string",
- "retailerOwnId": "string",
- "contentType": "string",
- "publisher": {
- "id": "string",
- "name": "string"
}, - "buyerId": "string",
- "country": "string",
- "deliverySource": "string",
- "language": "string",
- "netPrice": {
- "amount": 0,
- "currency": "string"
}, - "discountNetPrice": {
- "amount": 0,
- "currency": "string"
}, - "protection": "string"
}
]Aggregated consumption per day, customer, product and format.
This data comes from reading inside the WeDoBooks SDK. If your account does not use the SDK the
response is an empty page with dataCompleteThrough set to null; the same applies before your
first day of data has been assembled.
Three ways to read, mutually exclusive:
startDate and endDate. There is no maximum range.fromUtcTimestamp to read only rows added or recalculated since that moment.Page to the end first — keep sending nextPaginationCursor back as paginationCursor until it
comes back null. Only then take toUtcTimestamp and use it as fromUtcTimestamp on your next
pull. Every page of one pull reports the same toUtcTimestamp; jumping to a new pull before the
last page silently skips whatever was left.
Rows replace, they do not add up. A row you receive replaces any row you already hold with
the same date, customerId, productIdentifier and format. If you append instead of
replacing, every corrected figure is counted twice. Rows are never removed — a figure corrected
to nothing arrives with its metrics set to zero.
To count checkouts over a period, use GET /checkouts and count the rows it returns.
UNAUTHORIZED: Authentication failed or the caller is not allowed to access this endpoint.FORBIDDEN: The caller is authenticated but does not have permission to read consumption data.UNPROCESSABLE_ENTITY: Query parameters are invalid, or fromUtcTimestamp was combined with a date range.| startDate | string Start of the reporting window (ISO 8601 date). Requires |
| endDate | string End of the reporting window (ISO 8601 date). Requires |
| fromUtcTimestamp | string Return only rows created or recomputed after this UTC timestamp. Cannot be combined with a date range. |
| paginationCursor | string The |
| paginationLimit | integer <int32> Rows per page. Defaults to 1000, maximum 5000. |
{- "data": [
- {
- "date": "2026-05-20",
- "customerId": "M0097921",
- "productIdentifier": "9788776325978",
- "format": "AUDIOBOOK",
- "contentSeconds": 4820.5,
- "wallClockSeconds": 3235.2,
- "lastModified": "2026-05-21T03:00:00.000Z"
}, - {
- "date": "2026-05-20",
- "customerId": "M0104882",
- "productIdentifier": "9788770361231",
- "format": "AUDIOBOOK",
- "contentSeconds": 1210,
- "wallClockSeconds": 1210,
- "lastModified": "2026-05-21T03:00:00.000Z"
}
], - "nextPaginationCursor": "eyJrZXkiOlsiMjAyNi0wNS0yMCIsIk0wMDk3OTIxIiwiOTc4ODc3NjMyNTk3OCIsIkFVRElPQk9PSyJdLCJzbmFwc2hvdEF0IjoiMjAyNi0wNS0yMVQwMzowMDowMC4wMDBaIn0",
- "dataCompleteThrough": "2026-05-20",
- "toUtcTimestamp": "2026-05-21T03:00:00.000Z"
}Aggregated consumption per day and hour, across all customers and titles.
These rows cannot be filtered or broken down by customer or title. Use GET /consumption when
you need either.
This data comes from reading inside the WeDoBooks SDK. If your account does not use the SDK the
response is an empty page with dataCompleteThrough set to null; the same applies before your
first day of data has been assembled.
Supports the same three ways to read and the same replace semantics as GET /consumption. Here
a row is identified by date, hour and format.
UNAUTHORIZED: Authentication failed or the caller is not allowed to access this endpoint.FORBIDDEN: The caller is authenticated but does not have permission to read consumption data.UNPROCESSABLE_ENTITY: Query parameters are invalid, or fromUtcTimestamp was combined with a date range.| startDate | string Start of the reporting window (ISO 8601 date). Requires |
| endDate | string End of the reporting window (ISO 8601 date). Requires |
| fromUtcTimestamp | string Return only rows created or recomputed after this UTC timestamp. Cannot be combined with a date range. |
| paginationCursor | string The |
| paginationLimit | integer <int32> Rows per page. Defaults to 1000, maximum 5000. |
{- "data": [
- {
- "date": "2026-05-20",
- "hour": 7,
- "format": "AUDIOBOOK",
- "uniqueCheckouts": 214,
- "contentSeconds": 411238.7,
- "wallClockSeconds": 402145,
- "lastModified": "2026-05-21T03:00:00.000Z"
}, - {
- "date": "2026-05-20",
- "hour": 11,
- "format": "AUDIOBOOK",
- "uniqueCheckouts": 363,
- "contentSeconds": 697796.2,
- "wallClockSeconds": 685907,
- "lastModified": "2026-05-21T03:00:00.000Z"
}
], - "nextPaginationCursor": null,
- "dataCompleteThrough": "2026-05-20",
- "toUtcTimestamp": "2026-05-21T03:00:00.000Z"
}One record per checkout, with the consumption accumulated against it over its whole life.
Checkouts that were never opened are included, with zeroed metrics and no activity timestamps.
This data comes from reading inside the WeDoBooks SDK. If your account does not use the SDK the
response is an empty page with dataCompleteThrough set to null; the same applies before your
first day of data has been assembled.
Three ways to read, mutually exclusive:
startDate and endDate, matched against the day the checkout was created.fromUtcTimestamp to read only checkouts added or recalculated since that
moment. A checkout being listened to changes at most once a day, not once per listening event.Page to the end first — keep sending nextPaginationCursor back as paginationCursor until it
comes back null. Only then take toUtcTimestamp and use it as fromUtcTimestamp on your next
pull. Every page of one pull reports the same toUtcTimestamp; jumping to a new pull before the
last page silently skips whatever was left.
Rows replace, they do not add up. A row you receive replaces any row you already hold with
the same checkoutId. If you append instead of replacing, every corrected figure is counted
twice.
Counting the rows returned for a period gives the number of checkouts in that period.
UNAUTHORIZED: Authentication failed or the caller is not allowed to access this endpoint.FORBIDDEN: The caller is authenticated but does not have permission to read checkout data.UNPROCESSABLE_ENTITY: Query parameters are invalid, or fromUtcTimestamp was combined with a date range.| startDate | string Earliest checkout creation date to include (ISO 8601 date). Requires |
| endDate | string Latest checkout creation date to include (ISO 8601 date). Requires |
| fromUtcTimestamp | string Return only rows created or recomputed after this UTC timestamp. Cannot be combined with a date range. |
| paginationCursor | string The |
| paginationLimit | integer <int32> Rows per page. Defaults to 1000, maximum 5000. |
{- "data": [
- {
- "checkoutId": "sB2mQ9xK4TnLpV7aRc1e",
- "createdAt": "2026-05-18T09:41:22.000Z",
- "customerId": "M0097921",
- "productIdentifier": "9788776325978",
- "format": "AUDIOBOOK",
- "firstActivity": "2026-05-18T09:44:10.000Z",
- "lastActivity": "2026-05-20T21:12:47.000Z",
- "contentSeconds": 14380.5,
- "wallClockSeconds": 9651.3,
- "lastModified": "2026-05-21T03:00:00.000Z"
}, - {
- "checkoutId": "hK8dR2wYt5NmXq3zBf6v",
- "createdAt": "2026-05-19T18:02:55.000Z",
- "customerId": "M0104882",
- "productIdentifier": "9788770361231",
- "format": "AUDIOBOOK",
- "firstActivity": null,
- "lastActivity": null,
- "contentSeconds": 0,
- "wallClockSeconds": 0,
- "lastModified": "2026-05-20T03:00:00.000Z"
}
], - "nextPaginationCursor": null,
- "dataCompleteThrough": "2026-05-20",
- "toUtcTimestamp": "2026-05-21T03:00:00.000Z"
}