openapi_public.yml•385 kB
openapi: 3.0.0
servers:
- url: https://api.lulu.com
description: Production server, uses live data
- url: https://api.sandbox.lulu.com
description: Sandbox server, uses test data
info:
description: |
# Getting Started
The Lulu Print API allows you to use [Lulu](https://www.lulu.com/) as your production and fulfillment network. The API provides access to the same functionality that Lulu uses internally to normalize files and send Print-Jobs to our production partners around the world.
The Lulu Print API is a **RESTful API** that communicates with JSON encoded messages. Communication is secured with **OpenID Connect** and **transport layer security** (HTTPS).
Working with the API requires intermediate level programming skills and a general understanding of web APIs. Check out Lulu's **[printing and fulfillment](https://www.lulu.com/sell)** options without having to do technical work upfront.
## Registration
You have to create an account to start using the Lulu Print API. Your account will automatically receive a client-key and a client-secret.
## Sandbox Environment
The API is available in a production and a sandbox environment. The sandbox can be used for development and testing purposes. Print-Jobs created on the sandbox will never be forwarded to a real production and can be paid for with test credit cards.
To access the sandbox, you have to create a separate account at [https://developers.sandbox.lulu.com/](https://developers.sandbox.lulu.com/).
The sandbox API endpoint URL is `https://api.sandbox.lulu.com/`.
## Authorization
The Lulu API uses [OpenID Connect](https://en.wikipedia.org/wiki/OpenID_Connect), an authentication layer built on top of [OAuth 2.0](https://en.wikipedia.org/wiki/OAuth). Instead of exchanging username and password, the API uses [JSON Web Token (JWT)](https://en.wikipedia.org/wiki/JSON_Web_Token) to authorize client requests.
To interact with the API you need a **client-key** and a **client-secret**. Open the [Client Keys & Secret](https://developers.lulu.com/user-profile/api-keys) ([Sandbox](https://developers.sandbox.lulu.com/user-profile/api-keys)) page to generate them.
<img src="https://api.lulu.com/api-docs/assets/keyAndSecretExample.png">
## Generate a Token
To interact with the API you first have to generate an OAuth token. This requires the following parameters:
* `client_key`
* `client_secret`
* `grant-type` must be set to `client_credentials`
You have to send a POST request to the token endpoint a special Authorization header. For your convenience, you can copy the authorization string directly from your [API Keys](https://developers.lulu.com/user-profile/api-keys) page:
```bash
curl -X POST https://api.lulu.com/auth/realms/glasstree/protocol/openid-connect/token \
-d 'grant_type=client_credentials' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Authorization: Basic ZjJjNDdmMTctOWMxZi00ZWZlLWIzYzEtMDI4YTNlZTRjM2M3OjMzOTViZGU4LTBkMjQtNGQ0Ny1hYTRjLWM4NGM3NjI0OGRiYw=='
```
The request will return a JSON response that contains an `access_token` key:
```json
{
"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkI...",
"expires_in":3600,
"refresh_expires_in":604800,
"refresh_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6...",
"token_type":"bearer",
"not-before-policy":0,
"session_state":"a856fb91-eafc-460e-8f6a-f09325062c88"
}
```
Store this `access_token` and use it to authorize all further requests. The token will expire after a few minutes, but you can always request a fresh token from the server as outlined above. We recommend to use an OAuth capable client lib in your favorite programming language to simplify working with client credentials and tokens. Some might even automatically refresh your token after it expired.
## Make authenticated requests
To authenticate subsequent API requests, you must provide a valid access token in the HTTP header of the request:
`Authorization: Bearer {access_token}`:
```bash
curl -X GET https://api.lulu.com/{some_api_endpoint}/ \
-H 'Authorization: Bearer {access_token}' \
-H 'Content-Type: application/json'
```
## Select a Product
Lulu's Print API offers a wide range of products. Each product is represented by a 27 character code call **pod_package_id**:
> Trim Size + Color + Print Quality + Bind + Paper + PPI + Finish + Linen + Foil = **pod_package_id**
Here are a few examples:
| pod_package_id | Description |
| --- | --- |
| `0850X1100BWSTDLW060UW444MNG` | `0850X1100`: trim size 8.5” x 11”<br>`BW`: black-and-white<br>`STD`: standard quality <br>`LW`: linen wrap binding<br>`060UW444`: 60# uncoated white paper with a bulk of 444 pages per inch <br>`M`: matte cover coating <br>`N`: navy colored linen<br>`G`: golden foil stamping |
| `0600X0900FCSTDPB080CW444GXX` | `0600X0900`: trim size 6” x 9” <br>`FC`: full color<br>`STD`: standard quality<br>`PB`: perfect binding<br>`080CW444`: 80# coated white paper with a bulk of 444 ppi<br>`G`: gloss cover coating<br>`X`: no linen<br>`X`: no foil|
| `0700X1000FCPRECO060UC444MXX` | 7" x 10" black-and-white premium coil-bound book printed on 60# cream paper with a matte cover |
| `0600X0900BWSTDPB060UW444MXX` | 6" x 9" black-and-white standard quality paperback book printed on 60# white paper with a matte cover |
Use the [Pricing Calculator](https://developers.lulu.com/price-calculator) to input your product specifications and generate a SKU for your product. Once a price is calculated, the SKU will be available in the Your Selection area.
For a full listing of Lulu SKUs and product specification, download the [Product Specification Sheet](https://assets.lulu.com/media/specs/lulu-print-api-spec-sheet.xlsx). Also, please download and review our [Production Templates](https://developers.lulu.com/products-and-shipping#production-templates) for additional guidance with formatting and file preparation. If you have general questions about which Lulu products are right for your business, please [contact one of our experts](https://help.api.lulu.com) through our Technical Support form.
## Validate files
### Validate interior file
Print API allows you to validate your interior file without creating a Print-Job. Interior validation requires publicly exposed URL to download and validate a file.
File validation is being done asynchronously, it may take a while, so to retrieve validation result, use GET endpoint.
File validation result may return different statuses:
* `NULL` - file validation is not started yet
* `VALIDATING` - file validation is still running
* `VALIDATED` - file validation finished without any errors
* `NORMALIZING` - file normalization (next step of validation, available only if `pod_package_id` is was passed in the payload) is still running
* `NORMALIZED` - file normalization finished without any errors
* `ERROR` - file is invalid, list of errors is included in the response
So there are 3 possible final statuses of validation:
* `VALIDATED` - validation succeeded
* `NORMALIZED` - validation succeeded, possible only if `pod_package_id` was added to the payload
* `ERROR` - validation failed
Example reasons of `ERROR` status:
* invalid PDF file
* not enough pages - at least 2 pages are required
* different sizes of pages
* fonts not embedded
* corrupted images
Applicable reasons should be included in `errors` field in the file validation response.
You can find the detailed endpoints documentation in
[interior validation section](#operation/Validate-Interior_create).
### Calculate cover dimensions
You can also calculate required cover dimensions basing on interior data by using
[cover dimensions](#operation/Cover-Dimensions_create) endpoint. This endpoint returns cover width and height
in requested unit (print points by default).
### Validate cover file
As it was possible with interior file, Print API also allows you to validate cover files. Just as interior
validation, cover validation requires publicly exposed URL to download and validate a file. Other required
attributes are POD package ID of your book and interior page count to correctly validate cover file.
Also in this case, file validation is being done asynchronously, it may take a while, so to retrieve
validation result, use GET endpoint.
File validation result may return different statuses:
* `NULL` - file validation is not started yet
* `NORMALIZING` - file validation is still running
* `NORMALIZED` - file validation finished without any errors
* `ERROR` - file is invalid, list of errors is included in the response
Example reasons of `ERROR` status:
* invalid PDF file
* invalid file size
Applicable reasons should be included in `errors` field in the file validation response.
You can find the detailed endpoints documentation in
[cover validation section](#operation/Validate-Cover_create).
## Create a Print-Job
Now you can start to create Print-Jobs. A Print-Job request consists of at least three data fields:
* `line_items` **(required)**: the list of books that shall be printed
* `shipping_address` **(required)**: the (end) customer’s address where Lulu should send the books - including a phone number.
* `contact_email` **(required)**: an email address for questions regarding the Print-Job - normally, you want to use the email address of a developer or shop owner, not the end customer
* `shipping_level`**(required)**: Lulu offers five different quality levels for shipping:
* `MAIL` - Slowest ship method. Depending on the destination, tracking might not be available.
* `PRIORITY_MAIL` - priority mail shipping
* `GROUND` - Courier based shipping using ground transportation in the US.
* `EXPEDITED` - expedited (2nd day) delivery via air mail or equivalent
* `EXPRESS` - overnight delivery. Fastest shipping available.
* `external_id` (optional): a reference number to link the Print-Job to your system (e.g. your order number)
The **shipping address must contain a phone number**. This is required by our shipping carriers. If the shipping address does not contain a phone number, the default phone number from the account will be used.
If neither the account nor the shipping address contain a phone number, the Print-Job can not be created.
You can find the detailed documentation for [Creating a new Print-Job](#) below.
## Check Print-Job Status
After sending a Print-Job, you can check its status. Normally, a Print-Job goes through the following stages:
<img src="https://api.lulu.com/api-docs/assets/print-job-stages.svg">
* **CREATED**: Print-Job created
* **UNPAID**: Print-Job can be paid
* **PAYMENT_IN_PROGRESS**: Payment is in Progress
* **PRODUCTION_DELAYED**: Print-Job is paid and will move to production after the mandatory production delay.
* **PRODUCTION_READY**: Production delay has ended and the Print-Job will move to "in production" shortly.
* **IN_PRODUCTION**: Print-Job submitted to printer
* **SHIPPED**: Print-Job is fully shipped
There are a few more status that can occur when there is a problem with the Print-Job:
* **REJECTED**: When there is a problem with the input data or the file, Lulu will reject a Print-Job with a detailed error message. Please [contact our experts](https://help.api.lulu.com) if you need help in resolving this issue.
* **CANCELED**: You can cancel a Print-Job as long as it is “unpaid” using an API request to the status endpoint. In rare cases, Lulu might also cancel a Print-Job if a problem has surfaced in production and the order cannot be fulfilled.
## Shipping Notification
Once an order has been shipped, Lulu will provide tracking information in the Print-Job and Print-Job Status endpoint. Example shipped response:
```json
{
"name": "SHIPPED",
"message": "All line-items were shipped",
"changed": "2024-04-10T09:28:34.870842Z",
"line_item_statuses": [
{
"name": "SHIPPED",
"messages": {
"tracking_id": "3d4a53da-cc42-44c2-b47b-c3da8fa37491_1",
"tracking_urls": [
"https://api.sandbox.lulu.com/printer-wannabe-tracking/3d4a53da-cc42-44c2-b47b-c3da8fa37491_1"
],
"carrier_name": "Carrier"
},
"line_item_id": 57999
}
],
"print_job_id": 42776
}
```
## Webhooks
> **You can subscribe to receive webhooks on the following topics:**
> * **PRINT_JOB_STATUS_CHANGED**
To subscribe to webhooks, create a webhook configuration by calling <a href="#operation/subscribe-webhooks" target="_blank">this
</a> endpoint. You have to select topics that you want to subscribe to and the URL where webhooks should be sent.
You can create multiple webhooks, but the URL has to be unique for each of them.
Once you created a webhook configuration, you can retrieve a <a href="#operation/retrieve-webhooks"
target="_blank">list</a> of owned webhook or <a href="#operation/retrieve-webhook" target="_blank">
single webhook</a> to check data:
* id
* topics
* URL
* is_active
It can be <a href="#operation/update-webhook" target="_blank">updated</a>, for example, if you want to update the
URL, list of subscribed topics or activate it after automatic deactivation.
It can be also <a href="#operation/delete-webhook" target="_blank">deleted</a> - this operation cannot be undone.
Once the webhook configuration is created, you should start receiving webhooks depending on topics that you are
subscribed to. Each submission payload contains 2 fields:
* topic
* data - depends on the topic
Each webhook submission has calculated HMAC - a request payload signed with webhook's owner API secret. HMAC is
sent in `Lulu-HMAC-SHA256` header. HMAC is calculated with API secret as a key (UTF-8 encoded), payload as a
message (UTF-8 encoded) and SHA-256 as hash function. To validate HMAC, it should be calculated using
*raw response data* - parsing it to JSON can cause formatting issues.
If a webhook submission fails for any reason (connection error, HTTP error, etc.), it is retried 5 times. After 5
different failed submissions in a row, the webhook is deactivated (`is_active` field is set to `false`). It can be
activated back by updating it. There is an option to test webhook submission by calling <a
href="#operation/test-webhook-submission" target="_blank">test</a> endpoint. It sends dummy data of the selected
topic to configured URL.
All webhooks submissions can be retrieved by calling <a href="#operation/retrieve-webhook-submissions"
target="_blank">this</a> endpoint. It returns all submissions created during the last 30 days.
### PRINT_JOB_STATUS_CHANGED topic
PRINT_JOB_STATUS_CHANGED webhook is sent every time owned print job status is updated. The data sent in the payload
is print job data, the same as returned by <a href="#operation/Print-Jobs_read" target="_blank">print job details
</a> endpoint.
title: Universal Publishing Platform API
version: v1
x-logo:
url: https://api.lulu.com/api-docs/assets/logo-lulu-api.svg
altText: LULU API logo
paths:
/print-job-cost-calculations/:
post:
description: This endpoint allows you to calculate product and shipping cost without creating a Print-Job. Typically
used in an offer or checkout situation. The address is required to calculate sales tax / VAT and shipping cost.
operationId: Print-Job-cost-calculations_create
requestBody:
content:
application/json:
schema:
description: A Print-Job Cost Calculation represents a price calculation for multiple print job line items
properties:
line_items:
description: The line items that should be calculated
items:
description: A Print-Job Cost Calculation Line Item represents a price calculation for a print job line
item
properties:
page_count:
description: The page count of the book
type: integer
writeOnly: true
pod_package_id:
description: The id of the PodPackage of the book
type: string
writeOnly: true
quantity:
description: The quantity of printables to base the calculations on
format: int32
type: number
writeOnly: true
required:
- quantity
- pod_package_id
- page_count
type: object
type: array
writeOnly: true
shipping_address:
description: The shipping address for calculating Print-Job cost
properties:
city:
type: string
country_code:
description: '[ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) country code'
maxLength: 2
minLength: 2
type: string
email:
format: email
type: string
is_business:
default: false
description: Only relevant for US addresses. Some US carriers don't deliver to business-addresses on
Saturday.
type: boolean
name:
description: Full name of the person, including first and last name.
type: string
organization:
description: Name of an organization. Required if no person name is given.
type: string
phone_number:
description: "Validation Regex Pattern: `^\\+?[\\d\\s\\-.\\/()]{8,20}$`\n"
maxLength: 20
type: string
postcode:
description: Required for most countries
maxLength: 64
type: string
state_code:
description: 2 or 3 letter state codes (officially called [ISO-3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2)).
They are required for some countries (e.g. US, MX, CA, AU)
type: string
street1:
description: First address line
type: string
street2:
description: Second address line
type: string
title:
enum:
- MR
- MISS
- MRS
- MS
- DR
type: string
required:
- street1
- city
- country_code
- postcode
- phone_number
type: object
writeOnly: true
shipping_option:
description: The shipping option level
enum:
- MAIL
- PRIORITY_MAIL
- GROUND_HD
- GROUND_BUS
- GROUND
- EXPEDITED
- EXPRESS
type: string
writeOnly: true
required:
- shipping_option
- shipping_address
- line_items
type: object
examples:
Shipping Express to Germany:
value:
line_items:
- page_count: 32
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 20
- page_count: 324
pod_package_id: 0425X0687BWSTDPB060UW444GXX
quantity: 200
shipping_address:
city: Lübeck
country_code: DE
postcode: '23552'
state_code:
street1: Holstenstr. 40
phone_number: 844-212-0689
shipping_option: EXPRESS
Shipping Mail to United Kingdom:
value:
line_items:
- page_count: 120
pod_package_id: 0827X1169BWPRELW080CW444MGG
quantity: 5
shipping_address:
city: Wetherby
country_code: GB
postcode: LS22 6LL
street1: Lucky Garden, 11, West Gate
phone_number: +44 113 496 0000
shipping_option: MAIL
responses:
201:
content:
application/json:
schema:
description: Summary of the costs of a Print-Job
properties:
shipping_address:
description: The shipping address of the customer.
properties:
city:
type: string
country_code:
description: '[ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) country code'
maxLength: 2
minLength: 2
type: string
email:
format: email
type: string
description: "Shipping carriers require an email address for notifications or handling delivery issues.
If no email is given, the default email in the user profile will be used.\n"
is_business:
default: false
description: Only relevant for US addresses. Some US carriers don't deliver to business-addresses
on Saturday.
type: boolean
name:
description: Full name of the person, including first and last name.
type: string
organization:
description: Name of an organization. Required if no person name is given.
type: string
phone_number:
description: "Shipping carriers require a phone number for handling delivery issues. If no phone number
is given, the default in the API user profile will be used. Validation Regex Pattern for phone numbers
`^\\+?[\\d\\s\\-.\\/()]{8,20}$`\n"
maxLength: 20
type: string
postcode:
description: Required for most countries
maxLength: 64
type: string
state_code:
description: 2 or 3 letter state codes (officially called [ISO-3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2)).
They are required for some countries (e.g. US, MX, CA, AU)
type: string
street1:
description: First address line
type: string
street2:
description: Second address line
type: string
title:
enum:
- MR
- MISS
- MRS
- MS
- DR
type: string
warnings:
description: Warnings found during address validation
readOnly: true
type: array
items:
properties:
type:
description: Type of warning
type: string
readOnly: true
code:
description: Warning code which describe what was suggested by validation
type: string
readOnly: true
path:
description: Describes the validation origin of warning
type: string
readOnly: true
message:
description: Warning message with suggested change
type: string
readOnly: true
suggested_address:
description: Suggested address returned by shipping address validation
readOnly: true
type: object
properties:
country_code:
description: Suggested country code
type: string
readOnly: true
state_code:
description: Suggested state code
type: string
readOnly: true
postcode:
description: Suggested postal code
type: string
readOnly: true
city:
description: Suggested city
type: string
readOnly: true
street1:
description: Suggested first address line
type: string
readOnly: true
street2:
description: Suggested second address line
type: string
readOnly: true
currency:
description: Currency for the costs
readOnly: true
type: string
line_item_costs:
description: List of cost summaries for each line item
items:
description: Costs for a Print-Job line item
properties:
cost_excl_discounts:
description: Per unit cost without any discounts applied as a decimal string
readOnly: true
type: string
discounts:
description: Discounts applied to this line item
items:
properties:
amount:
description: The deducted amount as a decimal string
readOnly: true
type: string
description:
description: Description of the discount
readOnly: true
type: string
required:
- amount
- description
type: object
readOnly: true
type: array
quantity:
description: The quantity of printables to base the calculations on
format: int32
readOnly: true
type: number
tax_rate:
description: The tax rate applied to the line as a decimal string
readOnly: true
type: string
total_cost_excl_discounts:
description: The total line price without any discounts applied as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: The total line price including discounts excluding tax as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: The total line price including discounts and taxes as a decimal string
readOnly: true
type: string
total_tax:
description: The total line tax amount as a decimal string
readOnly: true
type: string
unit_tier_cost:
description: Per unit cost with tier discount applied, null for list price (non-tier) customers
readOnly: true
type: string
required:
- quantity
- cost_excl_discounts
- cost_excl_tax
- tax_rate
- discounts
- total_cost_excl_discounts
- total_tax
- total_cost_excl_tax
- total_cost_incl_tax
type: object
readOnly: true
type: array
shipping_cost:
description: Summary of the combined shipping and handling costs
properties:
tax_rate:
description: Tax rate that was applied on shipping and handling costs as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: Total shipping and handling costs excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total shipping and handling costs including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on shipping and handling as a decimal string
readOnly: true
type: string
readOnly: true
type: object
fulfillment_cost:
description: Summary of the fulfillment fee costs
type: object
readOnly: true
properties:
total_cost_excl_tax:
description: Total fulfillment fee costs excluding taxes as a decimal string
type: string
readOnly: true
total_cost_incl_tax:
description: Total fulfillment fee costs including taxes as a decimal string
type: string
readOnly: true
total_tax:
description: Total amount of taxes on fulfillment fee as a decimal string
type: string
readOnly: true
tax_rate:
description: Tax rate that was applied on fulfillment fee costs as a decimal string
total_cost_excl_tax:
description: Total costs of the job excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total costs of the job including taxes as a decimal string
readOnly: true
type: string
total_discount_amount:
description: The total discount amount as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on the job as a decimal string
readOnly: true
type: string
fees:
description: All fees applied to Print Job
readOnly: true
type: array
items:
properties:
currency:
description: Print Job Fee currency
type: string
readOnly: true
fee_type:
description: Print Job Fee type
type: string
readOnly: true
sku:
description: Print Job Fee unique sku
type: string
readOnly: true
tax_rate:
type: string
description: The tax rate applied to the fee as a decimal string
readOnly: true
total_cost_excl_tax:
type: string
description: The total fee rate excluding tax as a decimal string
readOnly: true
total_cost_incl_tax:
type: string
description: The total fee rate including tax as a decimal string
readOnly: true
total_tax:
type: string
description: The total fee rate tax amount as a decimal string
readOnly: true
readOnly: true
required:
- shipping_cost
- line_item_costs
- total_cost_excl_tax
- total_cost_incl_tax
- total_discount_amount
- total_tax
- currency
type: object
example:
shipping_address:
city: Lübeck
country_code: DE
is_business: false
name: Hans Dampf
phone_number: 844-212-0689
postcode: '23552'
state_code: ''
street1: Holstenstr. 40
street2: ''
warnings:
type: validation_warning
path: external
code: REPLACED
message: 'street1: Holstenstr. 40 -> Holstenstraße 40'
suggested_address:
country_code: DE
state_code:
postcode: 23552
city: Lübeck
street1: Holstenstraße 40"
street2:
currency: USD
fees:
- currency: USD
fee_type: HANDLING_FEE
sku: HANDLING_FEE
tax_rate: '0.060000'
total_cost_excl_tax: '14.00'
total_cost_incl_tax: '14.84'
total_tax: '0.84'
- currency: USD
fee_type: FULFILLMENT_FEE
sku: FULFILLMENT_FEE
tax_rate: '0.060000'
total_cost_excl_tax: '0.75'
total_cost_incl_tax: '0.80'
total_tax: '0.05'
fulfillment_cost:
tax_rate: '0.06'
total_cost_excl_tax: '0.75'
total_cost_incl_tax: '0.80'
total_tax: '0.05'
line_item_costs:
- cost_excl_discounts: '2.55'
discounts: []
quantity: 20
tax_rate: '0.060000'
total_cost_excl_discounts: '51.00'
total_cost_excl_tax: '51.00'
total_cost_incl_tax: '54.06'
total_tax: '3.06'
unit_tier_cost:
- cost_excl_discounts: '9.26'
discounts:
- amount: '92.60'
description: Volume Discount 5%
quantity: 200
tax_rate: '0.060000'
total_cost_excl_discounts: '1852.00'
total_cost_excl_tax: '1759.40'
total_cost_incl_tax: '1864.96'
total_tax: '105.56'
unit_tier_cost:
shipping_cost:
tax_rate: '0.06'
total_cost_excl_tax: '318.44'
total_cost_incl_tax: '337.55'
total_tax: '19.11'
total_cost_excl_tax: '2129.59'
total_cost_incl_tax: '2257.37'
total_discount_amount: '92.60'
total_tax: '127.78'
description: Created
400:
$ref: '#/components/responses/BadRequest'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
security:
- oauth2: []
summary: Create a Print-Job cost calculation
tags:
- Print-Job Cost Calculations
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/print-job-cost-calculations/"
payload = json.dumps({
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 20
},
{
"page_count": 324,
"pod_package_id": "0425X0687BWSTDPB060UW444GXX",
"quantity": 200
}
],
"shipping_address": {
"city": "Washington",
"country_code": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE",
"phone_number": "+1 206 555 0100"
},
"shipping_option": "EXPRESS"
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/print-job-cost-calculations/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 20
},
{
"page_count": 324,
"pod_package_id": "0425X0687BWSTDPB060UW444GXX",
"quantity": 200
}
],
"shipping_address": {
"city": "Washington",
"country_code": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE",
"phone_number": "+1 206 555 0100"
},
"shipping_option": "EXPRESS"
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/print-job-cost-calculations/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 20
},
{
"page_count": 324,
"pod_package_id": "0425X0687BWSTDPB060UW444GXX",
"quantity": 200
}
],
"shipping_address": {
"city": "Washington",
"country_code": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE",
"phone_number": "+1 206 555 0100"
},
"shipping_option": "EXPRESS"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/print-job-cost-calculations/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"line_items\": [\n {\n \"page_count\": 32,\n \"pod_package_id\": \"0600X0900BWSTDPB060UW444MXX\",\n \"quantity\": 20\n },\n {\n \"page_count\": 324,\n \"pod_package_id\": \"0425X0687BWSTDPB060UW444GXX\",\n \"quantity\": 200\n }\n ],\n \"shipping_address\": {\n \"city\": \"Washington\",\n \"country_code\": \"US\",\n \"postcode\": \"20540\",\n \"state_code\": \"DC\",\n \"street1\": \"101 Independence Ave SE\",\n \"phone_number\": \"+1 206 555 0100\"\n },\n \"shipping_option\": \"EXPRESS\"\n}")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 20
},
{
"page_count": 324,
"pod_package_id": "0425X0687BWSTDPB060UW444GXX",
"quantity": 200
}
],
"shipping_address": {
"city": "Washington",
"country_code": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE",
"phone_number": "+1 206 555 0100"
},
"shipping_option": "EXPRESS"
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-job-cost-calculations/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/print-job-cost-calculations/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 20
},
{
"page_count": 324,
"pod_package_id": "0425X0687BWSTDPB060UW444GXX",
"quantity": 200
}
],
"shipping_address": {
"city": "Washington",
"country_code": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE",
"phone_number": "+1 206 555 0100"
},
"shipping_option": "EXPRESS"
}'
/print-jobs/:
get:
description: |
Use this request to show a list of Print-Jobs. The list is paginated
and can be filtered by various attributes that are given as query parameters.
Timestamps like `created_after`, `created_before`, `modified_after`, and `modified_before`
can be entered as [ISO8601 datetime strings](https://www.w3.org/TR/NOTE-datetime).
Internally, the Lulu API uses [Coordinated Universal Time (UTC)](https://en.wikipedia.org/wiki/Coordinated_Universal_Time).
The following formats are valid:
* `2017-11-09` (date only)
* `2017-11-09T09:30` (datetime with minute precision)
* `2017-11-09T09:30:08` (datetime with second precision)
* `2017-11-09T09:30:08Z` (UTC datetime)
* `2017-11-09T09:30:08+06:00` (datetime with offset)
To filter Print-Jobs by status you can use any valid status string
(`CREATED`, `REJECTED`, `UNPAID`, `PAYMENT_IN_PROGRESS`, `PRODUCTION_READY`,
`PRODUCTION_DELAYED`, `IN_PRODUCTION`, `ERROR`, `SHIPPED`, `CANCELED`).
`PAYMENT_IN_PROGRESS` and `PRODUCTION_READY` are rather short-lived
states that exist only for a few minutes at max; filtering by these status
will rarely yield any results.
operationId: Print-Jobs_list
parameters:
- description: 'Result page, default: 1'
in: query
name: page
schema:
type: integer
- description: The default is 100.
in: query
name: page_size
schema:
type: integer
- description: Filter by creation timestamp after the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp.
in: query
name: created_after
required: false
schema:
type: string
- description: Filter by creation timestamp before the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp.
in: query
name: created_before
required: false
schema:
type: string
- description: Filter by modification timestamp after the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
timestamp.
in: query
name: modified_after
required: false
schema:
type: string
- description: Filter by modification timestamp before the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
timestamp.
in: query
name: modified_before
required: false
schema:
type: string
- description: Filter by status
in: query
name: status
required: false
schema:
type: string
- description: Filter by id
in: query
name: id
required: false
schema:
type: string
- description: Filter by order_id
in: query
name: order_id
required: false
schema:
type: string
- description: Leave the list of line_items out of the Print-Jobs in the response.
in: query
name: exclude_line_items
required: false
schema:
type: boolean
- description: Search across the fields `id`, `external_id`, `order_id`, `status`, `line_item_id`, `line_item_external_id`,
`line_item_title`, `line_item_tracking_id` and `shipping_address`
in: query
name: search
required: false
schema:
type: string
- description: Which field to use when ordering the results.
in: query
name: ordering
required: false
schema:
type: string
responses:
200:
content:
application/json:
schema:
properties:
count:
example: 1
type: integer
next:
example: https://api.lulu.com/resources/?page=1&page_size=1
type: string
previous:
example: https://api.lulu.com/resources/?page=1&page_size=1
type: string
results:
items:
description: The job resource that represents a print order
properties:
contact_email:
description: |
Email address that should be contacted if
questions regarding the Print-Job arise. Lulu recommends
to use the email of a person who is responsible for placing
the Print-Job like a developer or business owner.
format: email
type: string
costs:
description: Summary of the costs of a Print-Job
properties:
line_item_costs:
description: Costs for a Print-Job line item
properties:
cost_excl_discounts:
description: Per unit cost without any discounts applied as a decimal string
readOnly: true
type: string
discounts:
description: Discounts applied to this line item
items:
properties:
amount:
description: The deducted amount as a decimal string
readOnly: true
type: string
description:
description: Description of the discount
readOnly: true
type: string
required:
- amount
- description
type: object
readOnly: true
type: array
quantity:
description: The quantity of printables to base the calculations on
format: int32
readOnly: true
type: number
tax_rate:
description: The tax rate applied to the line as a decimal string
readOnly: true
type: string
total_cost_excl_discounts:
description: The total line price without any discounts applied as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: The total line price including discounts excluding tax as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: The total line price including discounts and taxes as a decimal string
readOnly: true
type: string
total_tax:
description: The total line tax amount as a decimal string
readOnly: true
type: string
unit_tier_cost:
description: Per unit cost with tier discount applied, null for list price (non-tier) customers
readOnly: true
type: string
required:
- quantity
- cost_excl_discounts
- cost_excl_tax
- tax_rate
- discounts
- total_cost_excl_discounts
- total_tax
- total_cost_excl_tax
- total_cost_incl_tax
type: object
currency:
description: Currency for the costs
readOnly: true
type: string
shipping_cost:
description: Summary of the combined shipping and handling costs
properties:
tax_rate:
description: Tax rate that was applied on shipping and handling costs as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: Total shipping and handling costs excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total shipping and handling costs including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on shipping and handling as a decimal string
readOnly: true
type: string
readOnly: true
type: object
fulfillment_cost:
description: Summary of the fulfillment fee costs
type: object
readOnly: true
properties:
total_cost_excl_tax:
description: Total fulfillment fee costs excluding taxes as a decimal string
type: string
readOnly: true
total_cost_incl_tax:
description: Total fulfillment fee costs including taxes as a decimal string
type: string
readOnly: true
total_tax:
description: Total amount of taxes on fulfillment fee as a decimal string
type: string
readOnly: true
tax_rate:
description: Tax rate that was applied on fulfillment fee costs as a decimal string
fees:
description: All fees applied to Print Job
readOnly: true
type: array
items:
properties:
currency:
description: Print Job Fee currency
type: string
readOnly: true
fee_type:
description: Print Job Fee type
type: string
readOnly: true
sku:
description: Print Job Fee unique sku
type: string
readOnly: true
tax_rate:
type: string
description: The tax rate applied to the fee as a decimal string
readOnly: true
total_cost_excl_tax:
type: string
description: The total fee rate excluding tax as a decimal string
readOnly: true
total_cost_incl_tax:
type: string
description: The total fee rate including tax as a decimal string
readOnly: true
total_tax:
type: string
description: The total fee rate tax amount as a decimal string
readOnly: true
total_cost_excl_tax:
description: Total costs of the job excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total costs of the job including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on the job as a decimal string
readOnly: true
type: string
readOnly: true
type: object
estimated_shipping_dates:
description: The estimated ship and delivery dates for a Print-Job
properties:
arrival_max:
description: |
The slowest estimated delivery date for
a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
arrival_min:
description: |
The fastest estimated delivery date for
a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_max:
description: |
The slowest estimated ship date for a Print-Job
in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_min:
description: |
The fastest estimated ship date for a Print-Job
in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
readOnly: true
type: object
external_id:
description: |
Arbitrary string to identify and connect a
print job to your systems. Set it to an order number,
a purchase order or whatever else works for your particular
use case.
type: string
id:
format: int64
readOnly: true
type: number
line_items:
description: The line items of a Print-Job, defining it's Printables and their quantities. The property
name 'items' can be used instead.
items:
description: The line item of a Print-Job, defining it's printable and quantity
properties:
cover:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the cover source definition. If used together with 'interior' ,
it can replace 'printable_normalization', Alternatively to both options, a 'printable_id'
of an existing printable can be provided.
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it
to an order number, a purchase order or whatever else works for your particular use case
type: string
id:
format: int64
readOnly: true
type: number
interior:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the interior source definition. If used together with 'cover' ,
it can replace 'printable_normalization'. Alternatively to both options, a 'printable_id'
of an existing printable can be provided.
page_count:
description: The page count of the printable
format: int32
readOnly: true
type: number
pod_package_id:
description: The id of the PodPackage of the printable of this line item
maxLength: 27
type: string
printable_id:
description: Id of the Printable of of this line item. It can be used instead of 'printable_normalization'
/ 'interior' / 'cover'
format: uuid
type: string
printable_normalization:
description: Represents the normalization processes of the interior and cover source files.
Alternatively, 'interior' and 'cover' can be set as a shorthand for creation or a 'printable_id'
of an existing printable can be provided.
properties:
cover:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or
a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the cover source files
interior:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or
a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the interior source files
required:
- interior
- cover
type: object
quantity:
description: Quantity of printed books for this line item
format: int32
type: number
status:
default:
messages: {}
name: CREATED
description: Status object that contains the actual line item processing status as well as
additional status related data
properties:
messages:
description: A map of status related messages / data
properties:
delay:
description: Expected delay in hours for error status'
maxLength: 64
readOnly: true
type: string
error:
description: General status error message
readOnly: true
type: string
info:
description: General info message on the status
readOnly: true
type: string
printable_normalization:
description: A map of printable normalization related messages / data
properties:
cover:
description: Array of messages related to the cover file normalization
items:
readOnly: true
type: string
type: array
interior:
description: Array of messages related to the interior file normalization
items:
readOnly: true
type: string
type: array
readOnly: true
type: object
timestamp:
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp of last status
change'
maxLength: 64
readOnly: true
type: string
tracking_urls:
anyOf:
- type: string
- items:
type: string
type: array
description: Tracking url(s)
tracking_id:
description: Tracking id for this line item's shipment
readOnly: true
type: string
carrier_name:
description: Name of the carrier handling shipment
readOnly: true
type: string
readOnly: true
type: object
name:
default: CREATED
description: The actual processing status of the Print-Job.
enum:
- CREATED
- ACCEPTED
- REJECTED
- IN_PRODUCTION
- ERROR
- SHIPPED
type: string
readOnly: true
required:
- name
type: object
title:
description: The title of the line item. Should be on the cover. This field will become mandatory
on October 1, 2019!
maxLength: 255
type: string
tracking_id:
description: Tracking id for this line item's shipment
readOnly: true
type: string
tracking_urls:
description: A list of tracking urls for this line item's shipment.
items:
type: string
readOnly: true
type: array
carrier_name:
description: Name of the carrier handling shipment
readOnly: true
type: string
required:
- id
- status
- quantity
type: object
type: array
order_id:
description: Reference to the order, which this PrintJob has created
readOnly: true
type: string
production_delay:
default: 60
description: Delay before a newly created Print-Job is sent to production. Minimum is 60 minutes,
maximum is 2880 minutes (=48 hours). As most cancellation requests occur right after an order
has been placed, it makes sense to wait for some time before sending an order to production. Once
production has started, orders cannot be canceled anymore.
format: int32
maximum: 2880
minimum: 60
type: integer
production_due_time:
description: Target timestamp of when this job will move into production ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
format: date-time
readOnly: true
type: string
shipping_address:
description: The shipping address of the customer.
properties:
city:
type: string
country_code:
description: '[ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) country code'
maxLength: 2
minLength: 2
type: string
email:
format: email
type: string
description: "Shipping carriers require an email address for notifications or handling delivery
issues. If no email is given, the default email in the user profile will be used.\n"
is_business:
default: false
description: Only relevant for US addresses. Some US carriers don't deliver to business-addresses
on Saturday.
type: boolean
name:
description: Full name of the person, including first and last name.
type: string
organization:
description: Name of an organization. Required if no person name is given.
type: string
phone_number:
description: "Shipping carriers require a phone number for handling delivery issues. If no phone
number is given, the default in the API user profile will be used. Validation Regex Pattern
for phone numbers `^\\+?[\\d\\s\\-.\\/()]{8,20}$`\n"
maxLength: 20
type: string
postcode:
description: Required for most countries
maxLength: 64
type: string
state_code:
description: 2 or 3 letter state codes (officially called [ISO-3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2)).
They are required for some countries (e.g. US, MX, CA, AU)
type: string
street1:
description: First address line
type: string
street2:
description: Second address line
type: string
title:
enum:
- MR
- MISS
- MRS
- MS
- DR
type: string
warnings:
description: Warnings found during address validation
readOnly: true
type: array
items:
properties:
type:
description: Type of warning
type: string
readOnly: true
code:
description: Warning code which describe what was suggested by validation
type: string
readOnly: true
path:
description: Describes the validation origin of warning
type: string
readOnly: true
message:
description: Warning message with suggested change
type: string
readOnly: true
suggested_address:
description: Suggested address returned by shipping address validation
readOnly: true
type: object
properties:
country_code:
description: Suggested country code
type: string
readOnly: true
state_code:
description: Suggested state code
type: string
readOnly: true
postcode:
description: Suggested postal code
type: string
readOnly: true
city:
description: Suggested city
type: string
readOnly: true
street1:
description: Suggested first address line
type: string
readOnly: true
street2:
description: Suggested second address line
type: string
readOnly: true
required:
- name
- street1
- city
- country_code
- postcode
- phone_number
- email
type: object
shipping_level:
description: The shipping level that this Print-Job is shipped with
enum:
- MAIL
- PRIORITY_MAIL
- GROUND_HD
- GROUND_BUS
- GROUND
- EXPEDITED
- EXPRESS
type: string
tax_country:
description: '[ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code
of the tax country determined for this job'
maxLength: 2
readOnly: true
type: string
required:
- id
- status
- line_items
- shipping_address
- contact_email
- shipping_level
type: object
example:
contact_email: test@test.com
costs:
line_item_costs:
shipping_cost:
total_cost_excl_tax: '132.74'
total_cost_incl_tax: '132.74'
total_tax: '0.00'
tax_rate: '0.000000'
fulfillment_cost:
total_cost_excl_tax: '0.75'
total_cost_incl_tax: '0.81'
total_tax: '0.06'
tax_rate: '0.080000'
fees:
- currency: USD
fee_type: HANDLING_FEE
sku: HANDLING_FEE_6
tax_rate: '0.088750'
total_cost_excl_tax: '4.00'
total_cost_incl_tax: '4.36'
total_tax: '0.36'
total_cost_excl_tax:
total_cost_incl_tax:
total_tax:
date_created: '2017-08-07T08:47:26.485456Z'
date_modified: '2017-08-07T08:47:26.485490Z'
estimated_shipping_dates:
arrival_max: '2017-08-12'
arrival_min: '2017-08-10'
dispatch_max: '2017-08-09'
dispatch_min: '2017-08-07'
external_id: demo-time
id: 1
line_items:
- external_id: item-reference-1
id: 1
printable_id:
printable_normalization:
cover:
job_id:
normalized_file:
page_count:
source_file:
source_md5sum: e78512c777e7f5841fe8f1992cefb898
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1
interior:
job_id:
normalized_file:
page_count:
source_file:
source_md5sum: 7f8af20c296747689756f8e310135d79
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 20
status:
messages:
info: Line-item is currently being validated
name: CREATED
title: My Book
production_delay: 120
production_due_time:
shipping_address:
city: Lübeck
country_code: DE
is_business: false
name: Hans Dampf
phone_number: 844-212-0689
postcode: '23552'
state_code: ''
street1: Holstenstr. 40
street2: ''
warnings:
type: validation_warning
path: external
code: REPLACED
message: 'street1: Holstenstr. 40 -> Holstenstraße 40'
suggested_address:
country_code: DE
state_code:
postcode: 23552
city: Lübeck
street1: Holstenstraße 40"
street2:
shipping_level: MAIL
shipping_option_level: MAIL
status:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job is currently being validated
name: CREATED
type: array
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
security:
- oauth2: []
summary: Retrieve a list of Print-Jobs
tags:
- Print-Jobs
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/print-jobs/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/print-jobs/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/print-jobs/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/print-jobs/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-jobs/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/print-jobs/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
post:
description: |
Print-Jobs are the core resource of the Print API. A Printjob
consists of line items, shipping information and some additional metadata.
## Elements of a Print-Job
### Line Items
A line item represents a book that should be printed or in short a **printable**.
Printables consist of cover and interior files as well as a `pod_package_id`.
The `pod_package_id` represents the manufacturing options; see the ["Select
a product"](#section/Select-a-Product) section for details. Each printable
can be identified by an immutable `printable_id`. The `printable_id` can be
used for re-orders so that the files don''t have to be transferred again.
#### Linen Wrap Foil
Foil stamping is available on Hardcover Linen with Dust Jacket products only.
The foil stamp is placed on the spine of your book and cannot exceed 42 characters.
Lulu's foil stamping supports the following characters:
* Roman Character sets (A-Z, a-z, 0-9)
* [];',./!`^&*()~+=:?"]ˇ˘°´¨¸¯- ØŁ
* ÀÁÃĀÄĂĆČÇĎÈÉËĒĔĚĞÌÍĨÏĪĬĽĹÑŃŇÒÓÕÖŌŎŔŘŚŞŠŢŤÙÚŨŪÜŬÝŸŹŽ
* àáãäāăćčçďèéëēĕěğìíĩïīĭľĺñńňòóõöōŏŕřśşšţťùúũūüŭýÿźž
Unsupported characters:
- _ and all non-roman character sets (Cyrillic, Arabic, Hebrew, Farsi, Chinese, Japanese, Thai, etc.)
Your linen and foil stamping color selections should be included at the end of your SKU using the following letters to indicate color, with the linen option first and the foil stamping option last:
* Linen:
* Navy: N
* Gray: G
* Red: R
* Black: B
* Tan: T
* Forest: F
* Foil:
* Gold: G
* Black: B
* White: W
For example: 0600X0900BWSTDPB060UW444M**NG**
### Shipping Information & Metadata
Print-Jobs have to contain a `shipping_address` as well as a `shipping_level`.
Lulu offers five different service levels that differ in speed and traceability.
### Additional Metadata
A few additional metadata fields can be specified in the Print-Job as well:
* `contact_email` for questions related to the Print-Job itself
* `production_delay` allows you to specify a delay (between 60 minutes and
2,880 minutes) before the Print-Job goes to production.
* `external_id` allows you to link the Print-Job to an internal order number
or other reference.
* `recipient_tax_id` is required for shipping addresses to Brazil, Chile, and Mexico.
This field holds the recipient's tax identification number (CPF/CNPJ for Brazil, RUT for Chile, and RFC for Mexico).
The tax ID can be provided in formatted form (with dots, dashes, or slashes), but will be standardized to a compact version
without separators (e.g., "12.345.678/0001-90" will be converted to "12345678000190") for further processing.
## File Handling and Normalization
Interior and cover files have to be specified with a URL from which Lulu can
download the files. Using encoded [basic authentication](https://en.wikipedia.org/wiki/Basic_access_authentication#URL_encoding)
in the URL is ok. All files processed by Lulu will be validated and normalized
before sending them to production. If problems with the file occur, the PrintJob
will be rejected or cancelled and an error message will be displayed.
## Automation and Payment
After a Print-Job has been created successfully, it will remain in an `UNPAID`
state until it is paid for through the developer portal. However, you can
automate the process by putting a credit card on file. Then, the Print-Job
will automatically transition to the `PRODUCTION_DELAY` status and your card
will charged when the Print-Job is sent to production.
For any questions related to alternative payment options,
[contact our support team](https://help.api.lulu.com/en/support/tickets/new).
operationId: Print-Jobs_create
requestBody:
content:
application/json:
schema:
description: The job resource that represents a print order
properties:
contact_email:
description: "Email address that should be contacted if questions regarding the Print-Job arise. Lulu recommends
to use the email of a person who is responsible for placing the Print-Job like a developer or business
owner.\n"
format: email
type: string
costs:
description: Summary of the costs of a Print-Job
properties:
line_item_costs:
description: Costs for a Print-Job line item
properties:
cost_excl_discounts:
description: Per unit cost without any discounts applied as a decimal string
readOnly: true
type: string
discounts:
description: Discounts applied to this line item
items:
properties:
amount:
description: The deducted amount as a decimal string
readOnly: true
type: string
description:
description: Description of the discount
readOnly: true
type: string
required:
- amount
- description
type: object
readOnly: true
type: array
quantity:
description: The quantity of printables to base the calculations on
format: int32
readOnly: true
type: number
tax_rate:
description: The tax rate applied to the line as a decimal string
readOnly: true
type: string
total_cost_excl_discounts:
description: The total line price without any discounts applied as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: The total line price including discounts excluding tax as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: The total line price including discounts and taxes as a decimal string
readOnly: true
type: string
total_tax:
description: The total line tax amount as a decimal string
readOnly: true
type: string
unit_tier_cost:
description: Per unit cost with tier discount applied, null for list price (non-tier) customers
readOnly: true
type: string
required:
- quantity
- cost_excl_discounts
- cost_excl_tax
- tax_rate
- discounts
- total_cost_excl_discounts
- total_tax
- total_cost_excl_tax
- total_cost_incl_tax
type: object
shipping_cost:
description: Summary of the shipping costs
properties:
tax_rate:
description: Tax rate that was applied on shipping costs as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: Total shipping costs excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total shipping costs including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on shipping as a decimal string
readOnly: true
type: string
readOnly: true
type: object
total_cost_excl_tax:
description: Total costs of the job excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total costs of the job including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on the job as a decimal string
readOnly: true
type: string
readOnly: true
type: object
estimated_shipping_dates:
description: The estimated ship and delivery dates for a Print-Job
properties:
arrival_max:
description: The slowest estimated delivery date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
arrival_min:
description: The fastest estimated delivery date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_max:
description: The slowest estimated ship date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_min:
description: The fastest estimated ship date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
readOnly: true
type: object
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it to an order number,
a purchase order or whatever else works for your particular use case.
type: string
id:
format: int64
readOnly: true
type: number
line_items:
description: The line items of a Print-Job, defining it's Printables and their quantities. The property
name 'items' can be used instead.
items:
description: The line item of a Print-Job, defining it's printable and quantity
properties:
cover:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the cover source definition. If used together with 'interior' , it can replace
'printable_normalization', Alternatively to both options, a 'printable_id' of an existing printable
can be provided.
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it to an order
number, a purchase order or whatever else works for your particular use case
type: string
id:
format: int64
readOnly: true
type: number
interior:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the interior source definition. If used together with 'cover' , it can replace
'printable_normalization'. Alternatively to both options, a 'printable_id' of an existing printable
can be provided.
page_count:
description: The page count of the printable
format: int32
readOnly: true
type: number
pod_package_id:
description: The id of the PodPackage of the printable of this line item
maxLength: 27
type: string
printable_id:
description: Id of the Printable of of this line item. It can be used instead of 'printable_normalization'
/ 'interior' / 'cover'
format: uuid
type: string
printable_normalization:
description: Represents the normalization processes of the interior and cover source files. Alternatively,
'interior' and 'cover' can be set as a shorthand for creation or a 'printable_id' of an existing
printable can be provided.
properties:
cover:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the cover source files
interior:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the interior source files
required:
- interior
- cover
type: object
quantity:
description: Quantity of printed books for this line item
format: int32
type: number
status:
default:
messages: {}
name: CREATED
description: Status object that contains the actual line item processing status as well as additional
status related data
properties:
messages:
description: A map of status related messages / data
properties:
delay:
description: Expected delay in hours for error status'
maxLength: 64
readOnly: true
type: string
error:
description: General status error message
readOnly: true
type: string
info:
description: General info message on the status
readOnly: true
type: string
printable_normalization:
description: A map of printable normalization related messages / data
properties:
cover:
description: Array of messages related to the cover file normalization
items:
readOnly: true
type: string
type: array
interior:
description: Array of messages related to the interior file normalization
items:
readOnly: true
type: string
type: array
readOnly: true
type: object
timestamp:
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp of last status change'
maxLength: 64
readOnly: true
type: string
url:
anyOf:
- type: string
- items:
type: string
type: array
description: Tracking url(s)
readOnly: true
type: object
name:
default: CREATED
description: The actual processing status of the Print-Job.
enum:
- CREATED
- ACCEPTED
- REJECTED
- IN_PRODUCTION
- ERROR
- SHIPPED
type: string
readOnly: true
required:
- name
type: object
title:
description: The title of the line item. Should be on the cover. This field will become mandatory
on October 1, 2019!
maxLength: 255
type: string
tracking_id:
description: A list of tracking ids for this line item's shipment
readOnly: true
type: string
tracking_urls:
description: A list of tracking urls for this line item's shipment.
items:
type: string
readOnly: true
type: array
required:
- id
- status
- quantity
type: object
type: array
order_id:
description: Reference to the order, which this PrintJob has created
readOnly: true
type: string
production_delay:
default: 60
description: Delay before a newly created Print-Job is sent to production. Minimum is 60 minutes, maximum
is 2880 minutes (=48 hours). As most cancellation requests occur right after an order has been placed,
it makes sense to wait for some time before sending an order to production. Once production has started,
orders cannot be canceled anymore.
format: int32
maximum: 2880
minimum: 60
type: integer
production_due_time:
description: Target timestamp of when this job will move into production ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
format: date-time
readOnly: true
type: string
shipping_address:
description: The shipping address of the customer.
properties:
city:
type: string
country_code:
description: '[ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) country code'
maxLength: 2
minLength: 2
type: string
email:
format: email
type: string
description: "Shipping carriers require an email address for notifications or handling delivery issues.
If no email is given, the default email in the user profile will be used.\n"
is_business:
default: false
description: Only relevant for US addresses. Some US carriers don't deliver to business-addresses on
Saturday.
type: boolean
name:
description: Full name of the person, including first and last name.
type: string
organization:
description: Name of an organization. Required if no person name is given.
type: string
phone_number:
description: "Shipping carriers require a phone number for handling delivery issues. If no phone number
is given, the default in the API user profile will be used. Validation Regex Pattern for phone numbers
`^\\+?[\\d\\s\\-.\\/()]{8,20}$`\n"
maxLength: 20
type: string
postcode:
description: Required for most countries
maxLength: 64
type: string
state_code:
description: 2 or 3 letter state codes (officially called [ISO-3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2)).
They are required for some countries (e.g. US, MX, CA, AU)
type: string
street1:
description: First address line
type: string
street2:
description: Second address line
type: string
title:
enum:
- MR
- MISS
- MRS
- MS
- DR
type: string
recipient_tax_id:
description: The recipient’s tax identification number. Required for shipping addresses to Brazil, Chile, and Mexico.
type: string
required:
- name
- street1
- city
- country_code
- postcode
- phone_number
- email
type: object
shipping_level:
description: The shipping level that this Print-Job is shipped with
enum:
- MAIL
- PRIORITY_MAIL
- GROUND_HD
- GROUND_BUS
- GROUND
- EXPEDITED
- EXPRESS
type: string
tax_country:
description: '[ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the
tax country determined for this job'
maxLength: 2
readOnly: true
type: string
required:
- id
- status
- line_items
- shipping_address
- contact_email
- shipping_level
type: object
examples:
Example Book:
value:
contact_email: test@test.com
external_id: demo-time
line_items:
- external_id: item-reference-1
printable_normalization:
cover:
source_url: https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1
interior:
source_url: https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 30
title: My Book
production_delay: 120
shipping_address:
city: Lübeck
country_code: GB
name: Hans Dampf
phone_number: 844-212-0689
postcode: PO1 3AX
state_code: ''
street1: Holstenstr. 48
shipping_level: MAIL
Example Linen Wrap Book:
value:
contact_email: test@test.com
external_id: demo-time
line_items:
- external_id: item-reference-1
printable_normalization:
cover:
source_url: https://www.dropbox.com/scl/fi/7t4muts0gh4qe7833ay8b/cover_template.pdf?rlkey=0jlesya87pd9xe5k1u2l7lcws&st=75qgd5jt&dl=1
interior:
source_url: https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1
pod_package_id: 0600X0900BWPRELW060UW444MFB
foil_stamp_author_text: Author name
foil_stamp_title_text: My Book
quantity: 5
title: My Book
production_delay: 120
shipping_address:
city: Lübeck
country_code: GB
name: Hans Dampf
phone_number: 844-212-0689
postcode: PO1 3AX
state_code: ''
street1: Holstenstr. 48
shipping_level: MAIL
responses:
201:
content:
application/json:
schema:
description: The job resource that represents a print order
properties:
contact_email:
description: Email address that should be contacted if questions regarding the Print-Job arise. Lulu recommends
to use the email of a person who is responsible for placing the Print-Job like a developer or business
owner.
format: email
type: string
costs:
description: Summary of the costs of a Print-Job
properties:
line_item_costs:
description: Costs for a Print-Job line item
properties:
cost_excl_discounts:
description: Per unit cost without any discounts applied as a decimal string
readOnly: true
type: string
discounts:
description: Discounts applied to this line item
items:
properties:
amount:
description: The deducted amount as a decimal string
readOnly: true
type: string
description:
description: Description of the discount
readOnly: true
type: string
required:
- amount
- description
type: object
readOnly: true
type: array
quantity:
description: The quantity of printables to base the calculations on
format: int32
readOnly: true
type: number
tax_rate:
description: The tax rate applied to the line as a decimal string
readOnly: true
type: string
total_cost_excl_discounts:
description: The total line price without any discounts applied as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: The total line price including discounts excluding tax as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: The total line price including discounts and taxes as a decimal string
readOnly: true
type: string
total_tax:
description: The total line tax amount as a decimal string
readOnly: true
type: string
unit_tier_cost:
description: Per unit cost with tier discount applied, null for list price (non-tier) customers
readOnly: true
type: string
required:
- quantity
- cost_excl_discounts
- cost_excl_tax
- tax_rate
- discounts
- total_cost_excl_discounts
- total_tax
- total_cost_excl_tax
- total_cost_incl_tax
type: object
shipping_cost:
description: Summary of the shipping costs
properties:
tax_rate:
description: Tax rate that was applied on shipping costs as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: Total shipping costs excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total shipping costs including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on shipping as a decimal string
readOnly: true
type: string
readOnly: true
type: object
total_cost_excl_tax:
description: Total costs of the job excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total costs of the job including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on the job as a decimal string
readOnly: true
type: string
readOnly: true
type: object
estimated_shipping_dates:
description: The estimated ship and delivery dates for a Print-Job
properties:
arrival_max:
description: The slowest estimated delivery date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
arrival_min:
description: The fastest estimated delivery date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_max:
description: The slowest estimated ship date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_min:
description: The fastest estimated ship date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
readOnly: true
type: object
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it to an order
number, a purchase order or whatever else works for your particular use case.
type: string
id:
format: int64
readOnly: true
type: number
line_items:
description: The line items of a Print-Job, defining it's Printables and their quantities. The property
name 'items' can be used instead.
items:
description: The line item of a Print-Job, defining it's printable and quantity
properties:
cover:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the cover source definition. If used together with 'interior' , it can
replace 'printable_normalization', Alternatively to both options, a 'printable_id' of an existing
printable can be provided.
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it to an
order number, a purchase order or whatever else works for your particular use case
type: string
id:
format: int64
readOnly: true
type: number
interior:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the interior source definition. If used together with 'cover' , it can
replace 'printable_normalization'. Alternatively to both options, a 'printable_id' of an existing
printable can be provided.
page_count:
description: The page count of the printable
format: int32
readOnly: true
type: number
pod_package_id:
description: The id of the PodPackage of the printable of this line item
maxLength: 27
type: string
printable_id:
description: Id of the Printable of of this line item. It can be used instead of 'printable_normalization'
/ 'interior' / 'cover'
format: uuid
type: string
printable_normalization:
description: Represents the normalization processes of the interior and cover source files. Alternatively,
'interior' and 'cover' can be set as a shorthand for creation or a 'printable_id' of an existing
printable can be provided.
properties:
cover:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the cover source files
interior:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the interior source files
required:
- interior
- cover
type: object
quantity:
description: Quantity of printed books for this line item
format: int32
type: number
status:
default:
messages: {}
name: CREATED
description: Status object that contains the actual line item processing status as well as additional
status related data
properties:
messages:
description: A map of status related messages / data
properties:
delay:
description: Expected delay in hours for error status'
maxLength: 64
readOnly: true
type: string
error:
description: General status error message
readOnly: true
type: string
info:
description: General info message on the status
readOnly: true
type: string
printable_normalization:
description: A map of printable normalization related messages / data
properties:
cover:
description: Array of messages related to the cover file normalization
items:
readOnly: true
type: string
type: array
interior:
description: Array of messages related to the interior file normalization
items:
readOnly: true
type: string
type: array
readOnly: true
type: object
timestamp:
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp of last status
change'
maxLength: 64
readOnly: true
type: string
url:
anyOf:
- type: string
- items:
type: string
type: array
description: Tracking url(s)
readOnly: true
type: object
name:
default: CREATED
description: The actual processing status of the Print-Job.
enum:
- CREATED
- ACCEPTED
- REJECTED
- IN_PRODUCTION
- ERROR
- SHIPPED
type: string
readOnly: true
required:
- name
type: object
title:
description: The title of the line item. Should be on the cover. This field will become mandatory
on October 1, 2019!
maxLength: 255
type: string
tracking_id:
description: A list of tracking ids for this line item's shipment
readOnly: true
type: string
tracking_urls:
description: A list of tracking urls for this line item's shipment.
items:
type: string
readOnly: true
type: array
required:
- id
- status
- quantity
type: object
type: array
order_id:
description: Reference to the order, which this PrintJob has created
readOnly: true
type: string
production_delay:
default: 60
description: Delay before a newly created Print-Job is sent to production. Minimum is 60 minutes, maximum
is 2880 minutes (=48 hours). As most cancellation requests occur right after an order has been placed,
it makes sense to wait for some time before sending an order to production. Once production has started,
orders cannot be canceled anymore.
format: int32
maximum: 2880
minimum: 60
type: integer
production_due_time:
description: Target timestamp of when this job will move into production ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
format: date-time
readOnly: true
type: string
shipping_address:
description: The shipping address of the customer.
properties:
city:
type: string
country_code:
description: '[ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) country code'
maxLength: 2
minLength: 2
type: string
email:
format: email
type: string
description: "Shipping carriers require an email address for notifications or handling delivery issues.
If no email is given, the default email in the user profile will be used.\n"
is_business:
default: false
description: Only relevant for US addresses. Some US carriers don't deliver to business-addresses
on Saturday.
type: boolean
name:
description: Full name of the person, including first and last name.
type: string
organization:
description: Name of an organization. Required if no person name is given.
type: string
phone_number:
description: "Shipping carriers require a phone number for handling delivery issues. If no phone number
is given, the default in the API user profile will be used. Validation Regex Pattern for phone numbers
`^\\+?[\\d\\s\\-.\\/()]{8,20}$`\n"
maxLength: 20
type: string
postcode:
description: Required for most countries
maxLength: 64
type: string
state_code:
description: 2 or 3 letter state codes (officially called [ISO-3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2)).
They are required for some countries (e.g. US, MX, CA, AU)
type: string
street1:
description: First address line
type: string
street2:
description: Second address line
type: string
title:
enum:
- MR
- MISS
- MRS
- MS
- DR
type: string
warnings:
description: Warnings found during address validation
readOnly: true
type: array
items:
properties:
type:
description: Type of warning
type: string
readOnly: true
code:
description: Warning code which describe what was suggested by validation
type: string
readOnly: true
path:
description: Describes the validation origin of warning
type: string
readOnly: true
message:
description: Warning message with suggested change
type: string
readOnly: true
suggested_address:
description: Suggested address returned by shipping address validation
readOnly: true
type: object
properties:
country_code:
description: Suggested country code
type: string
readOnly: true
state_code:
description: Suggested state code
type: string
readOnly: true
postcode:
description: Suggested postal code
type: string
readOnly: true
city:
description: Suggested city
type: string
readOnly: true
street1:
description: Suggested first address line
type: string
readOnly: true
street2:
description: Suggested second address line
type: string
readOnly: true
required:
- name
- street1
- city
- country_code
- postcode
- phone_number
- email
type: object
shipping_level:
description: The shipping level that this Print-Job is shipped with
enum:
- MAIL
- PRIORITY_MAIL
- GROUND_HD
- GROUND_BUS
- GROUND
- EXPEDITED
- EXPRESS
type: string
tax_country:
description: '[ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the
tax country determined for this job'
maxLength: 2
readOnly: true
type: string
required:
- id
- status
- line_items
- shipping_address
- contact_email
- shipping_level
type: object
example:
contact_email: test@test.com
costs:
line_item_costs:
shipping_cost:
total_cost_excl_tax:
total_cost_incl_tax:
total_tax:
date_created: '2017-08-07T08:47:26.485456Z'
date_modified: '2017-08-07T08:47:26.485490Z'
estimated_shipping_dates:
arrival_max: '2017-08-12'
arrival_min: '2017-08-10'
dispatch_max: '2017-08-09'
dispatch_min: '2017-08-07'
external_id: demo-time
id: 1
line_items:
- external_id: item-reference-1
id: 1
printable_id:
printable_normalization:
cover:
job_id:
normalized_file:
page_count:
source_file:
source_md5sum: e78512c777e7f5841fe8f1992cefb898
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1
interior:
job_id:
normalized_file:
page_count:
source_file:
source_md5sum: 7f8af20c296747689756f8e310135d79
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 20
status:
messages:
info: Line-item is currently being validated
name: CREATED
title: My Book
production_delay: 120
production_due_time:
shipping_address:
city: Lübeck
country_code: DE
is_business: false
name: Hans Dampf
phone_number: 844-212-0689
postcode: '23552'
state_code: ''
street1: Holstenstr. 48
street2: ''
shipping_level: MAIL
shipping_option_level: MAIL
status:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job is currently being validated
name: CREATED
example:
contact_email: test@test.com
costs:
line_item_costs:
shipping_cost:
total_cost_excl_tax:
total_cost_incl_tax:
total_tax:
date_created: '2017-08-07T08:47:26.485456Z'
date_modified: '2017-08-07T08:47:26.485490Z'
estimated_shipping_dates:
arrival_max: '2017-08-12'
arrival_min: '2017-08-10'
dispatch_max: '2017-08-09'
dispatch_min: '2017-08-07'
external_id: demo-time
id: 1
line_items:
- external_id: item-reference-1
id: 1
printable_id:
printable_normalization:
cover:
job_id:
normalized_file:
page_count:
source_file:
source_md5sum: e78512c777e7f5841fe8f1992cefb898
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1
interior:
job_id:
normalized_file:
page_count:
source_file:
source_md5sum: 7f8af20c296747689756f8e310135d79
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 20
status:
messages:
info: Line-item is currently being validated
name: CREATED
title: My Book
production_delay: 120
production_due_time:
shipping_address:
city: Lübeck
country_code: DE
is_business: false
name: Hans Dampf
phone_number: 844-212-0689
postcode: '23552'
state_code: ''
street1: Holstenstr. 40
street2: ''
warnings:
type: validation_warning
path: external
code: REPLACED
message: 'street1: Holstenstr. 40 -> Holstenstraße 40'
suggested_address:
country_code: DE
state_code:
postcode: 23552
city: Lübeck
street1: Holstenstraße 40"
street2:
shipping_level: MAIL
shipping_option_level: MAIL
status:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job is currently being validated
name: CREATED
description: Created
400:
content:
application/json:
schema:
example:
attribute_1:
- This field is required.
attribute_2:
- This field is required.
title: Bad Request
example:
attribute_1:
- This field is required.
attribute_2:
- This field is required.
description: Bad Request
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
security:
- oauth2: []
summary: Create a new Print-Job
tags:
- Print-Jobs
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/print-jobs/"
payload = json.dumps({
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "Lübeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/print-jobs/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "Lübeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/print-jobs/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "Lübeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/print-jobs/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"contact_email\": \"test@test.com\",\n \"external_id\": \"demo-time\",\n \"line_items\": [\n {\n \"external_id\": \"item-reference-1\",\n \"printable_normalization\": {\n \"cover\": {\n \"source_url\": \"https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1\"\n },\n \"interior\": {\n \"source_url\": \"https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1\"\n },\n \"pod_package_id\": \"0600X0900BWSTDPB060UW444MXX\"\n },\n \"quantity\": 30,\n \"title\": \"My Book\"\n }\n ],\n \"production_delay\": 120,\n \"shipping_address\": {\n \"city\": \"L\\u00fcbeck\",\n \"country_code\": \"GB\",\n \"name\": \"Hans Dampf\",\n \"phone_number\": \"844-212-0689\",\n \"postcode\": \"PO1 3AX\",\n \"state_code\": \"\",\n \"street1\": \"Holstenstr. 48\"\n },\n \"shipping_level\": \"MAIL\"\n}")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "Lübeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-jobs/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/print-jobs/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data-raw '{
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "L\u00fcbeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
}'
# use empty path param to show multiple examples for same path. see https://github.com/OAI/OpenAPI-Specification/issues/182#
/print-jobs/ :
post:
description: |
### Usage of printable_id
The immutable `printable_id` can be used for re-orders so that the files don't have to be transferred again.
Given there is an already created and validated Print-Job, you can use the `printable_id` of each line-item
to create re-orders for that particular printable. As the normalized files are already on the server, you
omit the complete `printable_normalization` object from the request and send a valid `printable_id` instead.
### Shipping Information & Metadata
Print-Jobs have to contain a `shipping_address` as well as a `shipping_level`.
Lulu offers five different service levels that differ in speed and traceability.
### Additional Metadata
A few additional metadata fields can be specified in the Print-Job as well:
* `contact_email` for questions related to the Print-Job itself,
* `production_delay` allows you to specify a delay (between 60 minutes and 2,880 minutes) before the Print-Job goes to production,
* `external_id` allows you to link the Print-Job to an internal order number or other reference.
## File Handling and Normalization
If there is an existing printable for the given `printable_id` the already processed and normalized files
are used for production. If there are are problems with the `printable_id`, the PrintJob will be rejected
or cancelled and an error message will be displayed.
## Automation and Payment
After a Print-Job has been created successfully, it will remain in an `UNPAID` state
until it is paid for through the developer portal. However, you can automate the process by putting
a credit card on file. Then, the Print-Job will automatically transition to the `PRODUCTION_DELAY`
status and your card will charged when the Print-Job is sent to production.
operationId: Print-Jobs_reprint
requestBody:
content:
application/json:
schema:
description: The job resource that represents a print order
properties:
contact_email:
description: Email address that should be contacted if questions regarding the Print-Job arise. Lulu recommends
to use the email of a person who is responsible for placing the Print-Job like a developer or business
owner.
format: email
type: string
costs:
description: Summary of the costs of a Print-Job
properties:
line_item_costs:
description: Costs for a Print-Job line item
properties:
cost_excl_discounts:
description: Per unit cost without any discounts applied as a decimal string
readOnly: true
type: string
discounts:
description: Discounts applied to this line item
items:
properties:
amount:
description: The deducted amount as a decimal string
readOnly: true
type: string
description:
description: Description of the discount
readOnly: true
type: string
required:
- amount
- description
type: object
readOnly: true
type: array
quantity:
description: The quantity of printables to base the calculations on
format: int32
readOnly: true
type: number
tax_rate:
description: The tax rate applied to the line as a decimal string
readOnly: true
type: string
total_cost_excl_discounts:
description: The total line price without any discounts applied as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: The total line price including discounts excluding tax as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: The total line price including discounts and taxes as a decimal string
readOnly: true
type: string
total_tax:
description: The total line tax amount as a decimal string
readOnly: true
type: string
unit_tier_cost:
description: Per unit cost with tier discount applied, null for list price (non-tier) customers
readOnly: true
type: string
required:
- quantity
- cost_excl_discounts
- cost_excl_tax
- tax_rate
- discounts
- total_cost_excl_discounts
- total_tax
- total_cost_excl_tax
- total_cost_incl_tax
type: object
shipping_cost:
description: Summary of the shipping costs
properties:
tax_rate:
description: Tax rate that was applied on shipping costs as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: Total shipping costs excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total shipping costs including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on shipping as a decimal string
readOnly: true
type: string
readOnly: true
type: object
total_cost_excl_tax:
description: Total costs of the job excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total costs of the job including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on the job as a decimal string
readOnly: true
type: string
readOnly: true
type: object
estimated_shipping_dates:
description: The estimated ship and delivery dates for a Print-Job
properties:
arrival_max:
description: The slowest estimated delivery date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
arrival_min:
description: The fastest estimated delivery date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_max:
description: The slowest estimated ship date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_min:
description: The fastest estimated ship date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
readOnly: true
type: object
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it to an order number,
a purchase order or whatever else works for your particular use case.
type: string
id:
format: int64
readOnly: true
type: number
line_items:
description: The line items of a Print-Job, defining it's Printables and their quantities. The property
name 'items' can be used instead.
items:
description: The line item of a Print-Job, defining it's printable and quantity
properties:
cover:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the cover source definition. If used together with 'interior' , it can replace
'printable_normalization', Alternatively to both options, a 'printable_id' of an existing printable
can be provided.
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it to an order
number, a purchase order or whatever else works for your particular use case
type: string
id:
format: int64
readOnly: true
type: number
interior:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the interior source definition. If used together with 'cover' , it can replace
'printable_normalization'. Alternatively to both options, a 'printable_id' of an existing printable
can be provided.
page_count:
description: The page count of the printable
format: int32
readOnly: true
type: number
pod_package_id:
description: The id of the PodPackage of the printable of this line item
maxLength: 27
type: string
printable_id:
description: Id of the Printable of of this line item. It can be used instead of 'printable_normalization'
/ 'interior' / 'cover'
format: uuid
type: string
printable_normalization:
description: Can be omitted if a valid 'printable_id' of an existing printable is provided.
properties:
cover:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the cover source files
interior:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the interior source files
required:
- interior
- cover
type: object
quantity:
description: Quantity of printed books for this line item
format: int32
type: number
status:
default:
messages: {}
name: CREATED
description: Status object that contains the actual line item processing status as well as additional
status related data
properties:
messages:
description: A map of status related messages / data
properties:
delay:
description: Expected delay in hours for error status'
maxLength: 64
readOnly: true
type: string
error:
description: General status error message
readOnly: true
type: string
info:
description: General info message on the status
readOnly: true
type: string
printable_normalization:
description: A map of printable normalization related messages / data
properties:
cover:
description: Array of messages related to the cover file normalization
items:
readOnly: true
type: string
type: array
interior:
description: Array of messages related to the interior file normalization
items:
readOnly: true
type: string
type: array
readOnly: true
type: object
timestamp:
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp of last status change'
maxLength: 64
readOnly: true
type: string
url:
anyOf:
- type: string
- items:
type: string
type: array
description: Tracking url(s)
readOnly: true
type: object
name:
default: CREATED
description: The actual processing status of the Print-Job.
enum:
- CREATED
- ACCEPTED
- REJECTED
- IN_PRODUCTION
- ERROR
- SHIPPED
type: string
readOnly: true
required:
- name
type: object
title:
description: The title of the line item. Should be on the cover. This field will become mandatory
on October 1, 2019!
maxLength: 255
type: string
tracking_id:
description: A list of tracking ids for this line item's shipment
readOnly: true
type: string
tracking_urls:
description: A list of tracking urls for this line item's shipment.
items:
type: string
readOnly: true
type: array
required:
- id
- status
- quantity
type: object
type: array
order_id:
description: Reference to the order, which this PrintJob has created
readOnly: true
type: string
production_delay:
default: 60
description: "Delay before a newly created Print-Job is sent to production. Minimum is 60 minutes, maximum
is 2880 minutes (=48 hours). As most cancellation requests occur right after an order has been placed,
it makes sense to wait for some time before sending an order to production. Once production has started,
orders cannot be canceled anymore.\n"
format: int32
maximum: 2880
minimum: 60
type: integer
production_due_time:
description: Target timestamp of when this job will move into production ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
format: date-time
readOnly: true
type: string
shipping_address:
description: The shipping address of the customer.
properties:
city:
type: string
country_code:
description: '[ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) country code'
maxLength: 2
minLength: 2
type: string
email:
format: email
type: string
description: "Shipping carriers require an email address for notifications or handling delivery issues.
If no email is given, the default email in the user profile will be used.\n"
is_business:
default: false
description: Only relevant for US addresses. Some US carriers don't deliver to business-addresses on
Saturday.
type: boolean
name:
description: Full name of the person, including first and last name.
type: string
organization:
description: Name of an organization. Required if no person name is given.
type: string
phone_number:
description: Shipping carriers require a phone number for handling delivery issues. If no phone number
is given, the default in the API user profile will be used. Validation Regex Pattern for phone numbers
`^\+?[\d\s\-.\/()]{8,20}$`
maxLength: 20
type: string
postcode:
description: Required for most countries
maxLength: 64
type: string
state_code:
description: 2 or 3 letter state codes (officially called [ISO-3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2)).
They are required for some countries (e.g. US, MX, CA, AU)
type: string
street1:
description: First address line
type: string
street2:
description: Second address line
type: string
title:
enum:
- MR
- MISS
- MRS
- MS
- DR
type: string
warnings:
description: Warnings found during address validation
readOnly: true
type: array
items:
properties:
type:
description: Type of warning
type: string
readOnly: true
code:
description: Warning code which describe what was suggested by validation
type: string
readOnly: true
path:
description: Describes the validation origin of warning
type: string
readOnly: true
message:
description: Warning message with suggested change
type: string
readOnly: true
suggested_address:
description: Suggested address returned by shipping address validation
readOnly: true
type: object
properties:
country_code:
description: Suggested country code
type: string
readOnly: true
state_code:
description: Suggested state code
type: string
readOnly: true
postcode:
description: Suggested postal code
type: string
readOnly: true
city:
description: Suggested city
type: string
readOnly: true
street1:
description: Suggested first address line
type: string
readOnly: true
street2:
description: Suggested second address line
type: string
readOnly: true
required:
- name
- street1
- city
- country_code
- postcode
- phone_number
- email
type: object
shipping_level:
description: The shipping level that this Print-Job is shipped with
enum:
- MAIL
- PRIORITY_MAIL
- GROUND_HD
- GROUND_BUS
- GROUND
- EXPEDITED
- EXPRESS
type: string
tax_country:
description: '[ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the
tax country determined for this job'
maxLength: 2
readOnly: true
type: string
required:
- id
- status
- line_items
- shipping_address
- contact_email
- shipping_level
type: object
example:
contact_email: test@test.com
external_id: demo-time
line_items:
- external_id: item-reference-1
printable_normalization:
cover:
source_url: https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1
interior:
source_url: https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 30
title: My Book
production_delay: 120
shipping_address:
city: Lübeck
country_code: GB
name: Hans Dampf
phone_number: 844-212-0689
postcode: PO1 3AX
state_code: ''
street1: Holstenstr. 48
shipping_level: MAIL
example:
contact_email: test@test.com
external_id: demo-time
line_items:
- external_id: item-reference-1
printable_id: 11606ab3-9355-46d3-ae90-338db6f5d271
quantity: 30
title: My Book
production_delay: 120
shipping_address:
city: Lübeck
country_code: GB
name: Hans Dampf
phone_number: 844-212-0689
postcode: PO1 3AX
state_code: ''
street1: Holstenstr. 48
shipping_level: MAIL
responses:
201:
content:
application/json:
schema:
description: The job resource that represents a print order
properties:
contact_email:
description: "Email address that should be contacted if questions regarding the Print-Job arise. Lulu
recommends to use the email of a person who is responsible for placing the Print-Job like a developer
or business owner.\n"
format: email
type: string
costs:
description: Summary of the costs of a Print-Job
properties:
line_item_costs:
description: Costs for a Print-Job line item
properties:
cost_excl_discounts:
description: Per unit cost without any discounts applied as a decimal string
readOnly: true
type: string
discounts:
description: Discounts applied to this line item
items:
properties:
amount:
description: The deducted amount as a decimal string
readOnly: true
type: string
description:
description: Description of the discount
readOnly: true
type: string
required:
- amount
- description
type: object
readOnly: true
type: array
quantity:
description: The quantity of printables to base the calculations on
format: int32
readOnly: true
type: number
tax_rate:
description: The tax rate applied to the line as a decimal string
readOnly: true
type: string
total_cost_excl_discounts:
description: The total line price without any discounts applied as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: The total line price including discounts excluding tax as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: The total line price including discounts and taxes as a decimal string
readOnly: true
type: string
total_tax:
description: The total line tax amount as a decimal string
readOnly: true
type: string
unit_tier_cost:
description: Per unit cost with tier discount applied, null for list price (non-tier) customers
readOnly: true
type: string
required:
- quantity
- cost_excl_discounts
- cost_excl_tax
- tax_rate
- discounts
- total_cost_excl_discounts
- total_tax
- total_cost_excl_tax
- total_cost_incl_tax
type: object
shipping_cost:
description: Summary of the shipping costs
properties:
tax_rate:
description: Tax rate that was applied on shipping costs as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: Total shipping costs excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total shipping costs including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on shipping as a decimal string
readOnly: true
type: string
readOnly: true
type: object
total_cost_excl_tax:
description: Total costs of the job excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total costs of the job including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on the job as a decimal string
readOnly: true
type: string
readOnly: true
type: object
estimated_shipping_dates:
description: The estimated ship and delivery dates for a Print-Job
properties:
arrival_max:
description: The slowest estimated delivery date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
arrival_min:
description: The fastest estimated delivery date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_max:
description: The slowest estimated ship date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
dispatch_min:
description: The fastest estimated ship date for a Print-Job in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format
readOnly: true
type: string
readOnly: true
type: object
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it to an order
number, a purchase order or whatever else works for your particular use case.
type: string
id:
format: int64
readOnly: true
type: number
line_items:
description: The line items of a Print-Job, defining it's Printables and their quantities. The property
name 'items' can be used instead.
items:
description: The line item of a Print-Job, defining it's printable and quantity
properties:
cover:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the cover source definition. If used together with 'interior' , it can
replace 'printable_normalization', Alternatively to both options, a 'printable_id' of an existing
printable can be provided.
external_id:
description: Arbitrary string to identify and connect a print job to your systems. Set it to an
order number, a purchase order or whatever else works for your particular use case
type: string
id:
format: int64
readOnly: true
type: number
interior:
oneOf:
- properties:
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
- description: The url of the interior source file.
type: string
writeOnly: true
writeOnly: true
description: Shorthand of the interior source definition. If used together with 'cover' , it can
replace 'printable_normalization'. Alternatively to both options, a 'printable_id' of an existing
printable can be provided.
page_count:
description: The page count of the printable
format: int32
readOnly: true
type: number
pod_package_id:
description: The id of the PodPackage of the printable of this line item
maxLength: 27
type: string
printable_id:
description: Id of the Printable of of this line item. It can be used instead of 'printable_normalization'
/ 'interior' / 'cover'
format: uuid
type: string
printable_normalization:
description: Represents the normalization processes of the interior and cover source files. Alternatively,
'interior' and 'cover' can be set as a shorthand for creation or a 'printable_id' of an existing
printable can be provided.
properties:
cover:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the cover source files
interior:
properties:
job_id:
description: The id of the normalization job (either a InteriorNormalizationJob or a CoverNormalizationJob)
format: int32
type: number
normalized_file:
description: The resulting normalized file
properties:
file_id:
format: int64
readOnly: true
type: number
filename:
description: Filename of the normalized file
readOnly: true
type: string
readOnly: true
type: object
source_md5_sum:
description: A md5 hash of the source file to check it's integrity
type: string
source_url:
description: The url of the source file.
type: string
required:
- source_url
type: object
description: Represents the normalization process of the interior source files
required:
- interior
- cover
type: object
quantity:
description: Quantity of printed books for this line item
format: int32
type: number
status:
default:
messages: {}
name: CREATED
description: Status object that contains the actual line item processing status as well as additional
status related data
properties:
messages:
description: A map of status related messages / data
properties:
delay:
description: Expected delay in hours for error status'
maxLength: 64
readOnly: true
type: string
error:
description: General status error message
readOnly: true
type: string
info:
description: General info message on the status
readOnly: true
type: string
printable_normalization:
description: A map of printable normalization related messages / data
properties:
cover:
description: Array of messages related to the cover file normalization
items:
readOnly: true
type: string
type: array
interior:
description: Array of messages related to the interior file normalization
items:
readOnly: true
type: string
type: array
readOnly: true
type: object
timestamp:
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp of last status
change'
maxLength: 64
readOnly: true
type: string
url:
anyOf:
- type: string
- items:
type: string
type: array
description: Tracking url(s)
readOnly: true
type: object
name:
default: CREATED
description: The actual processing status of the Print-Job.
enum:
- CREATED
- ACCEPTED
- REJECTED
- IN_PRODUCTION
- ERROR
- SHIPPED
type: string
readOnly: true
required:
- name
type: object
title:
description: The title of the line item. Should be on the cover. This field will become mandatory
on October 1, 2019!
maxLength: 255
type: string
tracking_id:
description: A list of tracking ids for this line item's shipment
readOnly: true
type: string
tracking_urls:
description: A list of tracking urls for this line item's shipment.
items:
type: string
readOnly: true
type: array
required:
- id
- status
- quantity
type: object
type: array
order_id:
description: Reference to the order, which this PrintJob has created
readOnly: true
type: string
production_delay:
default: 60
description: "Delay before a newly created Print-Job is sent to production. Minimum is 60 minutes, maximum
is 2880 minutes (=48 hours). As most cancellation requests occur right after an order has been placed,
it makes sense to wait for some time before sending an order to production. Once production has started,
orders cannot be canceled anymore.\n"
format: int32
maximum: 2880
minimum: 60
type: integer
production_due_time:
description: Target timestamp of when this job will move into production ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
format: date-time
readOnly: true
type: string
shipping_address:
description: The shipping address of the customer.
properties:
city:
type: string
country_code:
description: '[ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) country code'
maxLength: 2
minLength: 2
type: string
email:
format: email
type: string
description: "Shipping carriers require an email address for notifications or handling delivery issues.
If no email is given, the default email in the user profile will be used.\n"
is_business:
default: false
description: Only relevant for US addresses. Some US carriers don't deliver to business-addresses
on Saturday.
type: boolean
name:
description: Full name of the person, including first and last name.
type: string
organization:
description: Name of an organization. Required if no person name is given.
type: string
phone_number:
description: "Shipping carriers require a phone number for handling delivery issues. If no phone number
is given, the default in the API user profile will be used. Validation Regex Pattern for phone numbers
`^\\+?[\\d\\s\\-.\\/()]{8,20}$`\n"
maxLength: 20
type: string
postcode:
description: Required for most countries
maxLength: 64
type: string
state_code:
description: 2 or 3 letter state codes (officially called [ISO-3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2)).
They are required for some countries (e.g. US, MX, CA, AU)
type: string
street1:
description: First address line
type: string
street2:
description: Second address line
type: string
title:
enum:
- MR
- MISS
- MRS
- MS
- DR
type: string
warnings:
description: Warnings found during address validation
readOnly: true
type: array
items:
properties:
type:
description: Type of warning
type: string
readOnly: true
code:
description: Warning code which describe what was suggested by validation
type: string
readOnly: true
path:
description: Describes the validation origin of warning
type: string
readOnly: true
message:
description: Warning message with suggested change
type: string
readOnly: true
suggested_address:
description: Suggested address returned by shipping address validation
readOnly: true
type: object
properties:
country_code:
description: Suggested country code
type: string
readOnly: true
state_code:
description: Suggested state code
type: string
readOnly: true
postcode:
description: Suggested postal code
type: string
readOnly: true
city:
description: Suggested city
type: string
readOnly: true
street1:
description: Suggested first address line
type: string
readOnly: true
street2:
description: Suggested second address line
type: string
readOnly: true
required:
- name
- street1
- city
- country_code
- postcode
- phone_number
- email
type: object
shipping_level:
description: The shipping level that this Print-Job is shipped with
enum:
- MAIL
- PRIORITY_MAIL
- GROUND_HD
- GROUND_BUS
- GROUND
- EXPEDITED
- EXPRESS
type: string
tax_country:
description: '[ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the
tax country determined for this job'
maxLength: 2
readOnly: true
type: string
required:
- id
- status
- line_items
- shipping_address
- contact_email
- shipping_level
type: object
example:
contact_email: test@test.com
costs:
line_item_costs:
shipping_cost:
total_cost_excl_tax:
total_cost_incl_tax:
total_tax:
date_created: '2017-08-07T08:47:26.485456Z'
date_modified: '2017-08-07T08:47:26.485490Z'
estimated_shipping_dates:
arrival_max: '2017-08-12'
arrival_min: '2017-08-10'
dispatch_max: '2017-08-09'
dispatch_min: '2017-08-07'
external_id: demo-time
id: 1
line_items:
- external_id: item-reference-1
id: 1
printable_id: 11606ab3-9355-46d3-ae90-338db6f5d271
printable_normalization:
quantity: 20
status:
messages:
info: Line-item is currently being validated
name: CREATED
title: My Book
production_delay: 120
production_due_time:
shipping_address:
city: Lübeck
country_code: DE
is_business: false
name: Hans Dampf
phone_number: 844-212-0689
postcode: '23552'
state_code: ''
street1: Holstenstr. 40
street2: ''
warnings:
type: validation_warning
path: external
code: REPLACED
message: 'street1: Holstenstr. 40 -> Holstenstraße 40'
suggested_address:
country_code: DE
state_code:
postcode: 23552
city: Lübeck
street1: Holstenstraße 40"
street2:
shipping_level: MAIL
shipping_option_level: MAIL
status:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job is currently being validated
name: CREATED
example:
contact_email: test@test.com
costs:
line_item_costs:
shipping_cost:
total_cost_excl_tax:
total_cost_incl_tax:
total_tax:
date_created: '2017-08-07T08:47:26.485456Z'
date_modified: '2017-08-07T08:47:26.485490Z'
estimated_shipping_dates:
arrival_max: '2017-08-12'
arrival_min: '2017-08-10'
dispatch_max: '2017-08-09'
dispatch_min: '2017-08-07'
external_id: demo-time
id: 1
line_items:
- external_id: item-reference-1
id: 1
printable_id: 11606ab3-9355-46d3-ae90-338db6f5d271
printable_normalization:
quantity: 20
status:
messages:
info: Line-item is currently being validated
name: CREATED
title: My Book
production_delay: 120
production_due_time:
shipping_address:
city: Lübeck
country_code: DE
is_business: false
name: Hans Dampf
phone_number: 844-212-0689
postcode: '23552'
state_code: ''
street1: Holstenstr. 48
street2: ''
shipping_level: MAIL
shipping_option_level: MAIL
status:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job is currently being validated
name: CREATED
description: Created
400:
content:
application/json:
schema:
example:
attribute_1:
- This field is required.
attribute_2:
- This field is required.
title: Bad Request
example:
attribute_1:
- This field is required.
attribute_2:
- This field is required.
description: Bad Request
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
security:
- oauth2: []
summary: Create a new Print-Job (as Reprint)
tags:
- Print-Jobs
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/print-jobs/"
payload = json.dumps({
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "Lübeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/print-jobs/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "Lübeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/print-jobs/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "Lübeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/print-jobs/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"contact_email\": \"test@test.com\",\n \"external_id\": \"demo-time\",\n \"line_items\": [\n {\n \"external_id\": \"item-reference-1\",\n \"printable_normalization\": {\n \"cover\": {\n \"source_url\": \"https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1\"\n },\n \"interior\": {\n \"source_url\": \"https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1\"\n },\n \"pod_package_id\": \"0600X0900BWSTDPB060UW444MXX\"\n },\n \"quantity\": 30,\n \"title\": \"My Book\"\n }\n ],\n \"production_delay\": 120,\n \"shipping_address\": {\n \"city\": \"L\\u00fcbeck\",\n \"country_code\": \"GB\",\n \"name\": \"Hans Dampf\",\n \"phone_number\": \"844-212-0689\",\n \"postcode\": \"PO1 3AX\",\n \"state_code\": \"\",\n \"street1\": \"Holstenstr. 48\"\n },\n \"shipping_level\": \"MAIL\"\n}")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "Lübeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-jobs/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/print-jobs/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data-raw '{
"contact_email": "test@test.com",
"external_id": "demo-time",
"line_items": [
{
"external_id": "item-reference-1",
"printable_normalization": {
"cover": {
"source_url": "https://www.dropbox.com/s/7bv6mg2tj0h3l0r/lulu_trade_perfect_template.pdf?dl=1&raw=1"
},
"interior": {
"source_url": "https://www.dropbox.com/s/r20orb8umqjzav9/lulu_trade_interior_template-32.pdf?dl=1&raw=1"
},
"pod_package_id": "0600X0900BWSTDPB060UW444MXX"
},
"quantity": 30,
"title": "My Book"
}
],
"production_delay": 120,
"shipping_address": {
"city": "L\u00fcbeck",
"country_code": "GB",
"name": "Hans Dampf",
"phone_number": "844-212-0689",
"postcode": "PO1 3AX",
"state_code": "",
"street1": "Holstenstr. 48"
},
"shipping_level": "MAIL"
}'
/print-jobs/statistics/:
get:
operationId: Print-Jobs_statistics
parameters:
- description: 'Result page, default: 1'
in: query
name: page
schema:
type: integer
- description: The default is 100.
in: query
name: page_size
schema:
type: integer
- description: Filter by creation timestamp after the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp.
in: query
name: created_after
required: false
schema:
type: string
- description: Filter by creation timestamp before the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp.
in: query
name: created_before
required: false
schema:
type: string
- description: Filter by modification timestamp after the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
timestamp.
in: query
name: modified_after
required: false
schema:
type: string
- description: Filter by modification timestamp before the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime))
timestamp.
in: query
name: modified_before
required: false
schema:
type: string
- description: Filter by status
in: query
name: status
required: false
schema:
type: string
- description: Filter by id
in: query
name: id
required: false
schema:
type: string
- description: Which field to use when ordering the results.
in: query
name: ordering
required: false
schema:
type: string
responses:
200:
content:
application/json:
schema:
description: status name and the amount of corresponding print jobs
properties:
count:
description: Amount of printjobs
format: int64
readOnly: true
type: number
status:
default: CREATED
description: |
The actual processing status of the Print-Job.
Valid status transitions:
* `CREATED` -> `UNPAID`, `REJECTED` `CANCELED`, `PRODUCTION_READY`
* `UNPAID` -> `PAYMENT_IN_PROGRESS`, `CANCELED`, `PRODUCTION_DELAYED`
* `PAYMENT_IN_PROGRESS` -> `UNPAID`, `PRODUCTION_DELAYED`
* `PRODUCTION_DELAYED` -> `PRODUCTION_READY`, `CANCELED`
* `PRODUCTION_READY` -> `IN_PRODUCTION`, `PRODUCTION_DELAYED`
* `IN_PRODUCTION` -> `SHIPPED`, `ERROR`
enum:
- CREATED
- REJECTED
- UNPAID
- PAYMENT_IN_PROGRESS
- PRODUCTION_READY
- PRODUCTION_DELAYED
- IN_PRODUCTION
- ERROR
- SHIPPED
- CANCELED
type: string
example:
count: 3
status: PAYMENT_IN_PROGRESS
example:
count: 3
status: PAYMENT_IN_PROGRESS
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
security:
- oauth2: []
summary: Retrieve the number of Print-Jobs in each status
tags:
- Print-Jobs
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/print-jobs/statistics/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/print-jobs/statistics/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/print-jobs/statistics/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/print-jobs/statistics/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-jobs/statistics/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/print-jobs/statistics/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
/print-jobs/{id}/:
get:
description: Retrieve a single Print-Job by id.
operationId: Print-Jobs_read
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: string
responses:
200:
content:
application/json:
schema:
description: The extended version of a Print-Job resource that is returned by the detail endpoint
properties:
child_job_ids:
description: The ids of reprints of this Print-Job. Requires role 'print.print-job-reprint'
items:
format: int64
type: number
readOnly: true
type: array
items:
description: The line items of a Print-Job, defining it's Printables and their quantities. The property
name 'line_items' can be used instead.
items:
description: The extended version of a Print-JobLineItem resource that is returned by the detail endpoint
properties:
reprint:
description: This object contains additional informations in case the job is a reprint of another
Print-Job. Require the role 'print.print-job-reprint'
properties:
defect:
description: The categorical reason for the reprint, according to our internal list.
maxLength: 100
readOnly: true
type: string
required:
- defect
type: object
required:
- id
- status
- quantity
type: object
readOnly: true
type: array
line_items:
description: The line items of a Print-Job, defining it's Printables and their quantities. The property
name 'items' can be used instead.
items:
description: The extended version of a Print-JobLineItem resource that is returned by the detail endpoint
properties:
reprint:
description: This object contains additional information in case the job is a reprint of another
Print-Job. Require the role 'print.print-job-reprint'
properties:
defect:
description: The categorical reason for the reprint, according to our internal list.
maxLength: 100
readOnly: true
type: string
required:
- defect
type: object
required:
- id
- status
- quantity
type: object
readOnly: true
type: array
parent_job_id:
description: If this Print-Job is a reprint, this is the id of the original job. Requires role 'print.print-job-reprint'
format: int64
readOnly: true
type: number
required:
- id
- status
- line_items
- shipping_address
- contact_email
- shipping_level
type: object
example:
child_job_ids:
- 2019
contact_email: test@test.com
costs:
currency: USD
line_item_costs:
- cost_excl_discounts: '1.48'
cost_excl_tax: '0.74'
discounts:
- amount: '14.80'
description: Volume Discount 50%
line_item_external_id: item-reference-1
line_item_id: 1
quantity: 20
tax_rate: '0.070000'
total_cost_excl_discounts: '29.60'
total_cost_excl_tax: '14.80'
total_cost_incl_tax: '15.84'
total_tax: '1.04'
shipping_cost:
tax_rate: '0.070000'
total_cost_excl_tax: '65.99'
total_cost_incl_tax: '70.61'
total_tax: '4.62'
total_cost_excl_tax: '80.79'
total_cost_incl_tax: '86.45'
total_discount_amount: '14.80'
total_tax: '5.66'
date_created: '2017-08-07T08:47:26.485456Z'
date_modified: '2017-08-07T08:47:26.485490Z'
estimated_shipping_dates:
arrival_max: '2017-08-12'
arrival_min: '2017-08-10'
dispatch_max: '2017-08-09'
dispatch_min: '2017-08-07'
external_id: demo-time
id: 1
line_items:
- external_id: item-reference-1
id: 1
printable_id: 48efe280-d2e9-4334-b745-b0540fb628b4
printable_normalization:
cover:
job_id: 2
normalized_file:
file_id: 7
filename: 139056_cover.pdf
page_count: 1
source_file:
file_id: 6
filename: 139056_cover.pdf
source_md5sum: e78512c777e7f5841fe8f1992cefb898
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1
interior:
job_id: 2
normalized_file:
file_id: 8
filename: thesis2.pdf
page_count: 210
source_file:
file_id: 5
filename: thesis2.pdf
source_md5sum: 7f8af20c296747689756f8e310135d79
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 20
reprint:
cost_center: PRINTER
defect: Customer File/Source Defect
description: They didn't leave enough margin and it got cut off
printer_at_fault: BNB
status:
messages: {}
name: ACCEPTED
title: My Book
order_id: '1234'
parent_job_id: 1921
production_delay: 120
production_due_time:
shipping_address:
city: Lübeck
country_code: DE
is_business: false
name: Hans Dampf
phone_number: 844-212-0689
postcode: '23552'
state_code: ''
street1: Holstenstr. 40
street2: ''
warnings:
type: validation_warning
path: external
code: REPLACED
message: 'street1: Holstenstr. 40 -> Holstenstraße 40'
suggested_address:
country_code: DE
state_code:
postcode: 23552
city: Lübeck
street1: Holstenstraße 40"
street2:
shipping_level: MAIL
shipping_option_level: MAIL
status:
changed: '2017-08-07T08:48:00.529399Z'
message: Print-job was accepted and needs to be paid
name: UNPAID
tax_country: DE
example:
child_job_ids:
- 2019
contact_email: test@test.com
costs:
currency: USD
line_item_costs:
- cost_excl_discounts: '1.48'
cost_excl_tax: '0.74'
discounts:
- amount: '14.80'
description: Volume Discount 50%
line_item_external_id: item-reference-1
line_item_id: 1
quantity: 20
tax_rate: '0.070000'
total_cost_excl_discounts: '29.60'
total_cost_excl_tax: '14.80'
total_cost_incl_tax: '15.84'
total_tax: '1.04'
shipping_cost:
tax_rate: '0.070000'
total_cost_excl_tax: '65.99'
total_cost_incl_tax: '70.61'
total_tax: '4.62'
fulfillment_cost:
total_cost_excl_tax: '0.75'
total_cost_incl_tax: '0.81'
total_tax: '0.06'
tax_rate: '0.080000'
total_cost_excl_tax: '80.79'
total_cost_incl_tax: '86.45'
total_discount_amount: '14.80'
total_tax: '5.66'
fees:
- currency: USD
fee_type: HANDLING_FEE
sku: HANDLING_FEE_6
tax_rate: '0.088750'
total_cost_excl_tax: '4.00'
total_cost_incl_tax: '4.36'
total_tax: '0.36'
date_created: '2017-08-07T08:47:26.485456Z'
date_modified: '2017-08-07T08:47:26.485490Z'
estimated_shipping_dates:
arrival_max: '2017-08-12'
arrival_min: '2017-08-10'
dispatch_max: '2017-08-09'
dispatch_min: '2017-08-07'
external_id: demo-time
id: 1
line_items:
- external_id: item-reference-1
id: 1
printable_id: 48efe280-d2e9-4334-b745-b0540fb628b4
printable_normalization:
cover:
job_id: 2
normalized_file:
file_id: 7
filename: 139056_cover.pdf
page_count: 1
source_file:
file_id: 6
filename: 139056_cover.pdf
source_md5sum: e78512c777e7f5841fe8f1992cefb898
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1
interior:
job_id: 2
normalized_file:
file_id: 8
filename: thesis2.pdf
page_count: 210
source_file:
file_id: 5
filename: thesis2.pdf
source_md5sum: 7f8af20c296747689756f8e310135d79
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 20
reprint:
cost_center: PRINTER
defect: Customer File/Source Defect
description: They didn't leave enough margin and it got cut off
printer_at_fault: BNB
status:
messages: {}
name: ACCEPTED
title: My Book
order_id: '1234'
parent_job_id: 1921
production_delay: 120
production_due_time:
shipping_address:
city: Lübeck
country_code: DE
is_business: false
name: Hans Dampf
phone_number: 844-212-0689
postcode: '23552'
state_code: ''
street1: Holstenstr. 40
street2: ''
warnings:
type: validation_warning
path: external
code: REPLACED
message: 'street1: Holstenstr. 40 -> Holstenstraße 40'
suggested_address:
country_code: DE
state_code:
postcode: 23552
city: Lübeck
street1: Holstenstraße 40"
street2:
shipping_level: MAIL
shipping_option_level: MAIL
status:
changed: '2017-08-07T08:48:00.529399Z'
message: Print-job was accepted and needs to be paid
name: UNPAID
tax_country: DE
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
security:
- oauth2: []
summary: Retrieve a single Print-Job
tags:
- Print-Jobs
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/print-jobs/{id}/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/print-jobs/{id}/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/print-jobs/{id}/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/print-jobs/{id}/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-jobs/{id}/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff 'https://api.lulu.com/print-jobs/{id}/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
/print-jobs/{id}/costs/:
get:
description: Sub-resource to retrieve only the costs of a Print-Job
operationId: Print-Jobs_costs
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: string
responses:
200:
content:
application/json:
schema:
description: Summary of the costs of a Print-Job
properties:
line_item_costs:
description: List of cost summaries for each line item
items:
description: Costs for a Print-Job line item
properties:
line_item_external_id:
description: External id of the line item
readOnly: true
type: string
line_item_id:
description: ID of the line item of this cost summary
format: int64
readOnly: true
type: number
required:
- line_item_id
- line_item_external_id
type: object
readOnly: true
type: array
shipping_cost:
description: Summary of the combined shipping and handling costs
properties:
tax_rate:
description: Tax rate that was applied on shipping and handling costs as a decimal string
readOnly: true
type: string
total_cost_excl_tax:
description: Total shipping and handling costs excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total shipping and handling costs including taxes as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on shipping and handling as a decimal string
readOnly: true
type: string
readOnly: true
type: object
fulfillment_cost:
description: Summary of the fulfillment fee costs
type: object
readOnly: true
properties:
total_cost_excl_tax:
description: Total fulfillment fee costs excluding taxes as a decimal string
type: string
readOnly: true
total_cost_incl_tax:
description: Total fulfillment fee costs including taxes as a decimal string
type: string
readOnly: true
total_tax:
description: Total amount of taxes on fulfillment fee as a decimal string
type: string
readOnly: true
tax_rate:
description: Tax rate that was applied on fulfillment fee costs as a decimal string
total_cost_excl_tax:
description: Total costs of the job excluding taxes as a decimal string
readOnly: true
type: string
total_cost_incl_tax:
description: Total costs of the job including taxes as a decimal string
readOnly: true
type: string
total_discount_amount:
description: The total discount amount as a decimal string
readOnly: true
type: string
total_tax:
description: Total amount of taxes on the job as a decimal string
readOnly: true
type: string
currency:
description: Currency for the costs
readOnly: true
type: string
fees:
description: All fees applied to Print Job
readOnly: true
type: array
items:
properties:
currency:
description: Print Job Fee currency
type: string
readOnly: true
fee_type:
description: Print Job Fee type
type: string
readOnly: true
sku:
description: Print Job Fee unique sku
type: string
readOnly: true
tax_rate:
type: string
description: The tax rate applied to the fee as a decimal string
readOnly: true
total_cost_excl_tax:
type: string
description: The total fee rate excluding tax as a decimal string
readOnly: true
total_cost_incl_tax:
type: string
description: The total fee rate including tax as a decimal string
readOnly: true
total_tax:
type: string
description: The total fee rate tax amount as a decimal string
readOnly: true
readOnly: true
required:
- shipping_cost
- line_item_costs
- total_cost_excl_tax
- total_cost_incl_tax
- total_discount_amount
- total_tax
- currency
type: object
example:
currency: USD
line_item_costs:
- cost_excl_discounts: '1.48'
cost_excl_tax: '0.74'
discounts:
- amount: '14.80'
description: Volume Discount 50%
line_item_external_id: item-reference-1
line_item_id: 1
quantity: 20
tax_rate: '0.070000'
total_cost_excl_discounts: '29.60'
total_cost_excl_tax: '14.80'
total_cost_incl_tax: '15.84'
total_tax: '1.04'
shipping_cost:
tax_rate: '0.070000'
total_cost_excl_tax: '65.99'
total_cost_incl_tax: '70.61'
total_tax: '4.62'
total_cost_excl_tax: '80.79'
total_cost_incl_tax: '86.45'
total_discount_amount: '14.80'
total_tax: '5.66'
example:
currency: USD
line_item_costs:
- cost_excl_discounts: '1.48'
cost_excl_tax: '0.74'
discounts:
- amount: '14.80'
description: Volume Discount 50%
line_item_external_id: item-reference-1
line_item_id: 1
quantity: 20
tax_rate: '0.070000'
total_cost_excl_discounts: '29.60'
total_cost_excl_tax: '14.80'
total_cost_incl_tax: '15.84'
total_tax: '1.04'
shipping_cost:
tax_rate: '0.070000'
total_cost_excl_tax: '65.99'
total_cost_incl_tax: '70.61'
total_tax: '4.62'
fulfillment_cost:
total_cost_excl_tax: '0.75'
total_cost_incl_tax: '0.81'
total_tax: '0.06'
tax_rate: '0.080000'
total_cost_excl_tax: '80.79'
total_cost_incl_tax: '86.45'
total_discount_amount: '14.80'
total_tax: '5.66'
fees:
- currency: USD
fee_type: HANDLING_FEE
sku: HANDLING_FEE_6
tax_rate: '0.088750'
total_cost_excl_tax: '4.00'
total_cost_incl_tax: '4.36'
total_tax: '0.36'
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
security:
- oauth2: []
summary: Retrieve Print-Job Costs
tags:
- Print-Jobs
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/print-jobs/{id}/costs/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/print-jobs/{id}/costs/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/print-jobs/{id}/costs/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/print-jobs/{id}/costs/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-jobs/{id}/costs/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff 'https://api.lulu.com/print-jobs/{id}/costs/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
/print-jobs/{id}/status/:
get:
description: Sub-resource that represents the status of a Print-Job
operationId: Print-Jobs_status_read
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: string
responses:
200:
content:
application/json:
schema:
default:
changed: '[creation timestamp]'
name: CREATED
description: Status object that contains the actual PrintJob processing status as well as some additional
status related data
properties:
changed:
default: '[status update timestamp]'
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime)) Timestamp of the latest status change'
format: date-time
readOnly: true
type: string
message:
description: Status related message
readOnly: true
type: string
name:
default: CREATED
description: |
The actual processing status of the Print-Job.
Valid status transitions:
* `CREATED` -> `UNPAID`, `REJECTED` `CANCELED`, `PRODUCTION_READY`
* `UNPAID` -> `PAYMENT_IN_PROGRESS`, `CANCELED`, `PRODUCTION_DELAYED`
* `PAYMENT_IN_PROGRESS` -> `UNPAID`, `PRODUCTION_DELAYED`
* `PRODUCTION_DELAYED` -> `PRODUCTION_READY`, `CANCELED`
* `PRODUCTION_READY` -> `IN_PRODUCTION`, `PRODUCTION_DELAYED`
* `IN_PRODUCTION` -> `SHIPPED`, `ERROR`
enum:
- CREATED
- REJECTED
- UNPAID
- PAYMENT_IN_PROGRESS
- PRODUCTION_READY
- PRODUCTION_DELAYED
- IN_PRODUCTION
- ERROR
- SHIPPED
- CANCELED
type: string
required:
- name
- changed
type: object
example:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job is currently being validated
name: CREATED
example:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job is currently being validated
name: CREATED
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
security:
- oauth2: []
summary: Retrieve Print-Job Status
tags:
- Print-Jobs
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/print-jobs/{id}/status/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/print-jobs/{id}/status/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/print-jobs/{id}/status/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/print-jobs/{id}/status/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-jobs/{id}/status/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff 'https://api.lulu.com/print-jobs/{id}/status/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
put:
description: Cancel a single Print-Job by id.
operationId: Print-Jobs_status_cancel
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
properties:
name:
type: string
description: Status to change to
enum: [CANCELED]
example:
name: CANCELED
responses:
200:
content:
application/json:
schema:
default:
changed: '[creation timestamp]'
name: CREATED
description: Status object that contains the actual PrintJob processing status as well as some additional
status related data
properties:
changed:
default: '[status update timestamp]'
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime)) Timestamp of the latest status change'
format: date-time
readOnly: true
type: string
message:
description: Status related message
readOnly: true
type: string
name:
default: CREATED
description: |
The actual processing status of the Print-Job.
Valid status transitions:
* `CREATED` -> `UNPAID`, `REJECTED` `CANCELED`, `PRODUCTION_READY`
* `UNPAID` -> `PAYMENT_IN_PROGRESS`, `CANCELED`, `PRODUCTION_DELAYED`
* `PAYMENT_IN_PROGRESS` -> `UNPAID`, `PRODUCTION_DELAYED`
* `PRODUCTION_DELAYED` -> `PRODUCTION_READY`, `CANCELED`
* `PRODUCTION_READY` -> `IN_PRODUCTION`, `PRODUCTION_DELAYED`
* `IN_PRODUCTION` -> `SHIPPED`, `ERROR`
enum:
- CREATED
- REJECTED
- UNPAID
- PAYMENT_IN_PROGRESS
- PRODUCTION_READY
- PRODUCTION_DELAYED
- IN_PRODUCTION
- ERROR
- SHIPPED
- CANCELED
type: string
required:
- name
- changed
type: object
example:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job was canceled
name: CANCELED
example:
changed: '2017-08-07T08:47:26.480493Z'
message: Print-job was canceled
name: CANCELED
description: OK
400:
content:
application/json:
schema:
example: [Invalid transition from PRODUCTION_READY to CANCELED requested]
description: Bad Request
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
security:
- oauth2: []
summary: Cancel Print-Job
tags:
- Print-Jobs
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/print-jobs/{id}/status/"
payload = json.dumps({
"name": "CANCELED"
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/print-jobs/{id}/status/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"name": "CANCELED"
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/print-jobs/{id}/status/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"name": "CANCELED"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/print-jobs/{id}/status/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"CANCELED\"\n}")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"name": "CANCELED"
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/print-jobs/{id}/status/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff 'https://api.lulu.com/print-jobs/{id}/status/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{
"name": "CANCELED"
}'
/shipping-options/:
post:
security:
- {} # public, no authorization required
- oauth2:
- print-fulfillment.shipping-option
summary: Retrieve List of Shipping Options
description: |
When integrating the Print API with your own shop, you might want to give customers an option to select among different shipping levels.
This endpoint allows you to request available shipping methods (including cost) with minimal input data:
* `country`
* `page_count`
* `quantity`
* `pod_package_id`
* `currency` only required if you don't want USD
A valid `state_code` must be included in the shipping address to receive accurate shipping information.
<details close>
<summary>Countries that require valid state code (ISO 3166-1 alpha-2 code in parentheses)</summary>
* United Arab Emirates (AE)
* American Samoa (AS)
* Australia (AU)
* Brazil (BR)
* Canada (CA)
* China (CN)
* Colombia (CO)
* Costa Rica (CR)
* Cayman Islands (KY)
* Spain (ES)
* Micronesia (FM)
* Hong Kong (HK)
* Honduras (HN)
* Indonesia (ID)
* India (IN)
* Iraq (IQ)
* Italy (IT)
* Jamaica (JM)
* Japan (JP)
* Saint Kitts and Nevis (KN)
* Korea (KR)
* Mexico (MX)
* Marshall Islands (MH)
* Northern Mariana Islands (MP)
* Nauru (NR)
* Palau (PW)
* Papua New Guinea (PG)
* French Polynesia (PF)
* Russian Federation (RU)
* El Salvador (SV)
* Somalia (SO)
* Taiwan (TW)
* United States Minor Outlying Islands (UM)
* United States (US)
* Venezuela (VE)
* Virgin Islands, U.S. (VI)
</details>
You can further restrict shipping options that support post box delivery by adding `is_postbox=true` to your shipping address data.
tags:
- Shipping Options
operationId: retrieve-shipping-options
requestBody:
content:
application/json:
schema:
type: object
properties:
currency:
description: Currency to base cost calculations on, defaults to USD. Available currencies are AUD, CAD,
EUR, GBP, and USD.
type: string
example: USD
line_items:
description: The line items that should be calculated
type: array
items:
properties:
page_count:
description: The page count of the book
type: integer
example: 200
pod_package_id:
description: The id of the PodPackage of the book
type: string
example: 0550X0850FCPREPB080CW444GXX
quantity:
description: The quantity of books to base the calculations on
type: number
example: 1
required:
- quantity
- pod_package_id
- page_count
shipping_address:
description: The shipping address for which shipping options will be found
type: object
properties:
country:
description: '[ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) country code'
maxLength: 2
minLength: 2
type: string
city:
type: string
is_business:
default: false
description: Only relevant for US addresses. Some US carriers don't deliver to business-addresses on
Saturday.
type: boolean
is_postbox:
default: false
type: boolean
name:
description: Full name of the person, including first and last name.
type: string
organization:
description: Name of an organization. Required if no person name is given.
type: string
phone_number:
description: 'Validation Regex Pattern: `^\+?[\d\s\-.\/()]{8,20}$`'
maxLength: 20
type: string
postcode:
maxLength: 64
type: string
state:
description: 2 or 3 letter state codes (officially called [ISO-3166-2 subdivision codes](https://en.wikipedia.org/wiki/ISO_3166-2)).
type: string
street1:
description: First address line
type: string
street2:
description: Second address line
type: string
required:
- country
example:
currency: USD
line_items:
- page_count: 32
pod_package_id: 0600X0900BWSTDPB060UW444MXX
quantity: 1
- page_count: 324
pod_package_id: 0850X1100FCSTDPB060UW444MXX
quantity: 2
shipping_address:
city: Washington
country: US
postcode: '20540'
state_code: DC
street1: 101 Independence Ave SE
required:
- line_items
- shipping_address
responses:
200:
content:
application/json:
schema:
type: array
items:
description: A shipping option defines a concrete shipping configuration that an order can be shipped with
properties:
business_only:
default: false
description: Delivery only on working days
readOnly: true
type: boolean
cost_excl_tax:
description: The shipping cost excluding taxes as a decimal string. This attribute will only be set
on the detail endpoint representation, and only if the query parameters 'quantity' and 'currency'
are provided
readOnly: true
type: string
currency:
description: Currency of `cost_excl_tax`
type: string
home_only:
default: false
description: Delivery also on non working days
readOnly: true
type: boolean
id:
format: int64
readOnly: true
type: number
level:
default: MAIL
enum:
- MAIL
- PRIORITY_MAIL
- GROUND_HD
- GROUND_BUS
- GROUND
- EXPEDITED
- EXPRESS
readOnly: true
type: string
max_delivery_date:
description: Latest estimated delivery date in ([ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format. When no `pod_package_id` is provided in the request, the estimate is based on product types
with the longest estimated production time (usually hardcover books).
readOnly: true
type: string
max_dispatch_date:
description: Latest estimated dispatch (handover to carrier) date in ([ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format. When no `pod_package_id` is provided in the request, the estimate is based on product types
with the longest estimated production time (usually hardcover books).
readOnly: true
type: string
min_delivery_date:
description: Earliest estimated delivery date in ([ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format. When no `pod_package_id` is provided in the request, the estimate is based on product types
with the shortest estimated production time (usually non-hardcover books).
readOnly: true
type: string
min_dispatch_date:
description: Earliest estimated dispatch (handover to carrier) date in ([ISO 8601](https://en.wikipedia.org/wiki/ISO_8601))
format. When no `pod_package_id` is provided in the request, the estimate is based on product types
with the shortest estimated production time (usually non-hardcover books).
readOnly: true
type: string
postbox_ok:
default: false
description: Support of delivery to postboxes
readOnly: true
type: boolean
total_days_max:
description: Highest estimate of total business days from start of production to delivery. When no `pod_package_id`
is provided in the request, the estimate is based on product types with the longest estimated production
time (usually hardcover books).
format: int32
readOnly: true
type: number
total_days_min:
description: Lowest estimate of total business days from start of production to delivery. When no `pod_package_id`
is provided in the request, the estimate is based on product types with the shortest estimated production
time (usually non-hardcover books).
format: int32
readOnly: true
type: number
traceable:
default: false
description: If this shipping provides the possibility to create a tracking link
readOnly: true
type: boolean
transit_time:
default: 0
description: Average transit time in days
format: int32
readOnly: true
type: number
required:
- id
- level
- postbox_ok
- home_only
- business_only
- traceable
- transit_time
- shipping_buffer
- min_delivery_date
- max_delivery_date
type: object
example:
business_only: false
cost_excl_tax:
currency: EUR
home_only: false
id: 21
level: EXPRESS
max_delivery_date: '2018-02-01'
max_dispatch_date: '2018-01-28'
min_delivery_date: '2018-01-29'
min_dispatch_date: '2018-01-25'
postbox_ok: false
shipping_buffer: 0
total_days_max: 8
total_days_min: 6
traceable: true
transit_time: 4
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.sandbox.lulu.com/shipping-options/"
payload = json.dumps({
"currency": "USD",
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 1
},
{
"page_count": 324,
"pod_package_id": "0850X1100FCSTDPB060UW444MXX",
"quantity": 2
}
],
"shipping_address": {
"city": "Washington",
"country": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE"
}
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.sandbox.lulu.com/shipping-options/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"currency": "USD",
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 1
},
{
"page_count": 324,
"pod_package_id": "0850X1100FCSTDPB060UW444MXX",
"quantity": 2
}
],
"shipping_address": {
"city": "Washington",
"country": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE"
}
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.sandbox.lulu.com/shipping-options/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"currency": "USD",
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 1
},
{
"page_count": 324,
"pod_package_id": "0850X1100FCSTDPB060UW444MXX",
"quantity": 2
}
],
"shipping_address": {
"city": "Washington",
"country": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE"
}
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.sandbox.lulu.com/shipping-options/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"currency\": \"USD\",\n \"line_items\": [\n {\n \"page_count\": 32,\n \"pod_package_id\": \"0600X0900BWSTDPB060UW444MXX\",\n \"quantity\": 1\n },\n {\n \"page_count\": 324,\n \"pod_package_id\": \"0850X1100FCSTDPB060UW444MXX\",\n \"quantity\": 2\n }\n ],\n \"shipping_address\": {\n \"city\": \"Washington\",\n \"country\": \"US\",\n \"postcode\": \"20540\",\n \"state_code\": \"DC\",\n \"street1\": \"101 Independence Ave SE\"\n }\n}")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"currency": "USD",
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 1
},
{
"page_count": 324,
"pod_package_id": "0850X1100FCSTDPB060UW444MXX",
"quantity": 2
}
],
"shipping_address": {
"city": "Washington",
"country": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE"
}
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.sandbox.lulu.com/shipping-options/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.sandbox.lulu.com/shipping-options/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{
"currency": "USD",
"line_items": [
{
"page_count": 32,
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"quantity": 1
},
{
"page_count": 324,
"pod_package_id": "0850X1100FCSTDPB060UW444MXX",
"quantity": 2
}
],
"shipping_address": {
"city": "Washington",
"country": "US",
"postcode": "20540",
"state_code": "DC",
"street1": "101 Independence Ave SE"
}
}'
/webhooks/:
post:
security:
- oauth2: []
summary: Subscribe to webhooks
description: |
Subscribe to Print API webhooks by passing a list of topics that you want to subscribe to and the URL where
webhooks should be sent.
tags:
- Webhooks
operationId: subscribe-webhooks
requestBody:
content:
application/json:
schema:
type: object
properties:
topics:
description: List of webhook topics
type: array
items:
type: string
enum:
- PRINT_JOB_STATUS_CHANGED
example: [PRINT_JOB_STATUS_CHANGED]
url:
description: URL where webhook should be sent
type: string
example: https://www.webhooks-consumer.com/
example:
topics: [PRINT_JOB_STATUS_CHANGED]
url: https://www.webhooks-consumer.com/
required:
- topics
- url
responses:
201:
content:
application/json:
schema:
type: object
properties:
id:
description: Webhook ID
readOnly: true
format: uuid
type: string
is_active:
description: Indicates if webhook is active
readOnly: false
type: boolean
topics:
description: List of subscribed topics
type: array
readOnly: false
items:
type: string
enum:
- PRINT_JOB_STATUS_CHANGED
url:
description: Webhook URL
readOnly: false
type: string
required:
- id
- is_active
- topics
- url
example:
id: f370d09b-912a-4667-9890-ed9bd0c32166
is_active: true
topics: [PRINT_JOB_STATUS_CHANGED]
url: https://www.webhooks-consumer.com/
description: OK
400:
content:
application/json:
schema:
example:
url:
- Enter a valid URL.
topics:
- No matching enum type.
title: Bad Request
example:
url:
- Enter a valid URL.
topics:
- No matching enum type.
description: Bad Request
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/webhooks/"
payload = json.dumps({
"topics": [
"PRINT_JOB_STATUS_CHANGED"
],
"url": "https://www.webhooks-consumer.com/"
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/webhooks/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"topics": [
"PRINT_JOB_STATUS_CHANGED"
],
"url": "https://www.webhooks-consumer.com/"
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/webhooks/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"topics": [
"PRINT_JOB_STATUS_CHANGED"
],
"url": "https://www.webhooks-consumer.com/"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/webhooks/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"topics\": [\"PRINT_JOB_STATUS_CHANGED\"],\n \"url\": \"https://www.webhooks-consumer.com/\"\n}")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"topics": [
"PRINT_JOB_STATUS_CHANGED"
],
"url": "https://www.webhooks-consumer.com/"
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/webhooks/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/webhooks/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{
"topics": ["PRINT_JOB_STATUS_CHANGED"],
"url": "https://www.webhooks-consumer.com/"
}'
get:
security:
- oauth2: []
summary: Retrieve list of webhooks
description: |
Retrieve a list of all owned webhooks.
tags:
- Webhooks
operationId: retrieve-webhooks
responses:
200:
content:
application/json:
schema:
type: object
properties:
count:
example: 3
type: integer
next:
example: https://api.lulu.com/resources/?page=3&page_size=1
type: string
previous:
example: https://api.lulu.com/resources/?page=1&page_size=1
type: string
results:
type: array
items:
type: object
properties:
id:
description: Webhook ID
readOnly: true
format: uuid
type: string
is_active:
description: Indicates if webhook is active
readOnly: false
type: boolean
topics:
description: List of subscribed topics
type: array
readOnly: false
items:
type: string
enum:
- PRINT_JOB_STATUS_CHANGED
url:
description: Webhook URL
readOnly: false
type: string
required:
- id
- is_active
- topics
- url
example:
id: f370d09b-912a-4667-9890-ed9bd0c32166
is_active: true
topics: [PRINT_JOB_STATUS_CHANGED]
url: https://www.webhooks-consumer.com/
required:
- results
- count
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/webhooks/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/webhooks/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/webhooks/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/webhooks/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/webhooks/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/webhooks/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
/webhooks/{id}/:
get:
security:
- oauth2: []
summary: Retrieve single webhook
tags:
- Webhooks
operationId: retrieve-webhook
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: string
responses:
200:
content:
application/json:
schema:
type: object
properties:
id:
description: Webhook ID
readOnly: true
format: uuid
type: string
is_active:
description: Indicates if webhook is active
readOnly: false
type: boolean
topics:
description: List of subscribed topics
type: array
readOnly: false
items:
type: string
enum:
- PRINT_JOB_STATUS_CHANGED
url:
description: Webhook URL
readOnly: false
type: string
required:
- id
- is_active
- topics
- url
example:
id: f370d09b-912a-4667-9890-ed9bd0c32166
is_active: true
topics: [PRINT_JOB_STATUS_CHANGED]
url: https://www.webhooks-consumer.com/
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/webhooks/{id}/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/webhooks/{id}/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/webhooks/{id}/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/webhooks/{id}/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/webhooks/{id}/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff 'https://api.lulu.com/webhooks/{id}/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
patch:
security:
- oauth2: []
summary: Update webhook
description: |
Update owned webhook data: URL, list of subscribed topics. You can also activate or deactivate it.
tags:
- Webhooks
operationId: update-webhook
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
topics:
description: List of webhook topics
type: array
items:
type: string
enum:
- PRINT_JOB_STATUS_CHANGED
example: [PRINT_JOB_STATUS_CHANGED]
url:
description: URL where webhook should be sent
type: string
example: https://www.webhooks-consumer.com/updated/
is_active:
description: Activate or deactivate webhook
type: boolean
example: true
example:
url: https://www.webhooks-consumer.com/updated/
responses:
200:
content:
application/json:
schema:
type: object
properties:
id:
description: Webhook ID
readOnly: true
format: uuid
type: string
is_active:
description: Indicates if webhook is active
readOnly: false
type: boolean
topics:
description: List of subscribed topics
type: array
readOnly: false
items:
type: string
enum:
- PRINT_JOB_STATUS_CHANGED
url:
description: Webhook URL
readOnly: false
type: string
required:
- id
- is_active
- topics
- url
example:
id: f370d09b-912a-4667-9890-ed9bd0c32166
is_active: true
topics: [PRINT_JOB_STATUS_CHANGED]
url: https://www.webhooks-consumer.com/updated/
description: OK
400:
content:
application/json:
schema:
example:
url:
- Enter a valid URL.
topics:
- No matching enum type.
title: Bad Request
example:
url:
- Enter a valid URL.
topics:
- No matching enum type.
description: Bad Request
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/webhooks/{id}/"
payload = json.dumps({
"url": "https://www.webhooks-consumer.com/updated/"
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("PATCH", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/webhooks/{id}/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"url": "https://www.webhooks-consumer.com/updated/"
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'PATCH',
'url': 'https://api.lulu.com/webhooks/{id}/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"url": "https://www.webhooks-consumer.com/updated/"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.patch("https://api.lulu.com/webhooks/{id}/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://www.webhooks-consumer.com/updated/\"\n}")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"url": "https://www.webhooks-consumer.com/updated/"
});
var requestOptions = {
method: 'PATCH',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/webhooks/{id}/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff --request PATCH 'https://api.lulu.com/webhooks/{id}/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{
"url": "https://www.webhooks-consumer.com/updated/"
}'
delete:
security:
- oauth2: []
summary: Delete webhook
tags:
- Webhooks
operationId: delete-webhook
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: string
responses:
204:
description: No Content
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/webhooks/{id}/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("DELETE", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/webhooks/{id}/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'DELETE',
'url': 'https://api.lulu.com/webhooks/{id}/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.delete("https://api.lulu.com/webhooks/{id}/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'DELETE',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/webhooks/{id}/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff --request DELETE 'https://api.lulu.com/webhooks/{id}/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
/webhooks/{id}/test-submission/{topic}/:
post:
security:
- oauth2: []
summary: Test webhook topic submission
description: Sends payload with selected topic test data to webhook URL.
tags:
- Webhooks
operationId: test-webhook-submission
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: string
- description: Topic to test
in: path
name: topic
required: true
schema:
type: string
responses:
200:
content:
application/json:
schema:
type: string
example: Test webhook submission queued
description: OK
400:
content:
application/json:
schema:
example: ["Invalid topic. Subscribed topics are: ['PRINT_JOB_STATUS_CHANGED']."]
title: Bad Request
example: ["Invalid topic. Subscribed topics are: ['PRINT_JOB_STATUS_CHANGED']."]
description: Bad Request
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/webhooks/{id}/test-submission/{topic}/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/webhooks/{id}/test-submission/{topic}/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/webhooks/{id}/test-submission/{topic}/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/webhooks/{id}/test-submission/{topic}/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'POST',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/webhooks/{id}/test-submission/{topic}/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff --request POST 'https://api.lulu.com/webhooks/{id}/test-submission/{topic}/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
/webhook-submissions/:
get:
security:
- oauth2: []
summary: Retrieve list of webhook submissions
parameters:
- description: 'Result page, default: 1'
in: query
name: page
schema:
type: integer
- description: The default is 100.
in: query
name: page_size
schema:
type: integer
- description: Filter by creation timestamp after the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp.
in: query
name: created_after
required: false
schema:
type: string
- description: Filter by creation timestamp before the given ([ISO 8601](https://www.w3.org/TR/NOTE-datetime)) timestamp.
in: query
name: created_before
required: false
schema:
type: string
- description: Filter by is_success
name: is_success
in: query
required: false
schema:
type: boolean
- description: Filter by submission response code
in: query
name: response_code
required: false
schema:
type: string
- description: Filter by webhook ID
in: query
name: webhook_id
required: false
schema:
format: uuid
type: string
description: Retrieve a list of all submissions of owned webhooks.
tags:
- Webhooks
operationId: retrieve-webhook-submissions
responses:
200:
content:
application/json:
schema:
type: object
properties:
count:
example: 3
type: integer
next:
example: https://api.lulu.com/resources/?page=3&page_size=1
type: string
previous:
example: https://api.lulu.com/resources/?page=1&page_size=1
type: string
results:
type: array
items:
type: object
properties:
date_created:
type: string
readOnly: true
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime) creation timestamp'
format: date-time
example: 2023-05-31T10:00:00.414000Z
date_modified:
type: string
readOnly: true
description: '[ISO 8601](https://www.w3.org/TR/NOTE-datetime) modification timestamp'
format: date-time
example: 2023-05-31T10:00:00.414000Z
payload:
type: object
readOnly: true
description: Payload sent in webhook submission body
example: {}
topic:
type: string
enum:
- PRINT_JOB_STATUS_CHANGED
readOnly: true
description: Submission topic
example: PRINT_JOB_STATUS_CHANGED
is_success:
type: boolean
readOnly: true
description: Indicates if submission succeeded or not
example: true
response_code:
type: number
readOnly: true
description: Response code of submission
example: 200
attempts:
type: number
readOnly: true
description: Count of submission attempts
example: 1
webhook:
type: object
readOnly: true
description: Related webhook data
properties:
id:
description: Webhook ID
readOnly: true
format: uuid
type: string
is_active:
description: Indicates if webhook is active
readOnly: false
type: boolean
topics:
description: List of subscribed topics
type: array
readOnly: false
items:
type: string
enum:
- PRINT_JOB_STATUS_CHANGED
url:
description: Webhook URL
readOnly: false
type: string
required:
- id
- is_active
- topics
- url
example: {}
required:
- date_created
- date_modified
- payload
- topic
- is_success
- attempts
- webhook
example:
date_created: '2023-05-31T10:00:00.414Z'
date_modified: '2023-05-31T10:00:00.414Z'
payload:
data: {}
topic: PRINT_JOB_STATUS_CHANGED
topic: PRINT_JOB_STATUS_CHANGED
is_success: true
response_code: 200
attempts: 1
webhook:
id: f370d09b-912a-4667-9890-ed9bd0c32166
is_active: true
topics: [PRINT_JOB_STATUS_CHANGED]
url: https://www.webhooks-consumer.com/
required:
- results
- count
description: OK
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/webhook-submissions/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/webhook-submissions/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/webhook-submissions/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/webhook-submissions/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/webhook-submissions/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/webhook-submissions/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
/validate-interior/:
post:
summary: Validate interior file
description: This endpoint allows you to validate interior file
security:
- oauth2: []
tags:
- Files validation
operationId: Validate-Interior_create
requestBody:
content:
application/json:
schema:
type: object
properties:
source_url:
description: Public url of the interior source file
type: string
pod_package_id:
description: POD Package ID of the book. Required to run extended validation.
type: string
required:
- source_url
example:
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1
responses:
201:
description: Created
content:
application/json:
schema:
type: object
properties:
id:
type: integer
readOnly: true
source_url:
description: The url of the source file.
type: string
readOnly: true
page_count:
description: Detected page count of the file.
type: string
readOnly: true
errors:
description: List of errors detected in the file.
type: array
readOnly: true
items:
type: string
status:
description: Status of source file
type: string
enum:
- VALIDATING
- VALIDATED
- ERROR
readOnly: true
valid_pod_package_ids:
description: List of detected valid POD package IDs for source file.
type: array
items:
type: string
readOnly: true
required:
- id
- source_url
example:
id: 1
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1
page_count: 210
errors:
status: VALIDATING
valid_pod_package_ids:
400:
$ref: '#/components/responses/BadRequest'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/validate-interior/"
payload = json.dumps({
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1"
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/validate-interior/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1"
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/validate-interior/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/validate-interior/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"source_url\": \"https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1\"\n}")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1"
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/validate-interior/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/validate-interior/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1"
}'
/validate-interior/{id}/:
get:
summary: Retrieve a single file validation record
description: Retrieve a single file validation record
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: integer
example: 1
security:
- oauth2: []
tags:
- Files validation
operationId: Validate-Interior_read
responses:
200:
description: OK
content:
application/json:
schema:
type: object
properties:
id:
type: integer
readOnly: true
source_url:
description: The url of the source file.
type: string
readOnly: true
page_count:
description: Detected page count of the file.
type: string
readOnly: true
errors:
description: List of errors detected in the file.
type: array
readOnly: true
items:
type: string
status:
description: Status of source file
type: string
enum:
- VALIDATING
- VALIDATED
- ERROR
readOnly: true
valid_pod_package_ids:
description: List of detected valid POD package IDs for source file.
type: array
items:
type: string
readOnly: true
required:
- id
- source_url
example:
id: 1
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1
page_count: 210
errors:
status: VALIDATING
valid_pod_package_ids:
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/validate-interior/{id}/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/validate-interior/{id}/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/validate-interior/{id}/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/validate-interior/{id}/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/validate-interior/{id}/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff 'https://api.lulu.com/validate-interior/{id}/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
/cover-dimensions/:
post:
summary: Calculate cover dimensions
description: This endpoint allows you to calculate required cover dimensions basing on interior data.
security:
- oauth2: []
tags:
- Files validation
operationId: Cover-Dimensions_create
requestBody:
content:
application/json:
schema:
type: object
properties:
pod_package_id:
description: POD Package ID of the book.
type: string
interior_page_count:
type: integer
unit:
description: Requested unit of cover dimensions. Defaults to print points.
type: string
enum:
- pt
- mm
- inch
required:
- interior_page_count
- pod_package_id
example:
pod_package_id: 0600X0900BWSTDPB060UW444MXX
interior_page_count: 210
responses:
201:
description: Created
content:
application/json:
schema:
type: object
properties:
width:
type: string
height:
type: string
unit:
type: string
enum:
- pt
- mm
- inch
required:
- width
- height
- unit
example:
width: '920.000'
height: '666.000'
unit: pt
400:
$ref: '#/components/responses/BadRequest'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/cover-dimensions/"
payload = json.dumps({
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/cover-dimensions/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/cover-dimensions/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/cover-dimensions/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"page_count\": 210,\n \"pod_package_id\": \"0600X0900BWSTDPB060UW444MXX\"\n}").asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/cover-dimensions/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/cover-dimensions/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
}'
/validate-cover/:
post:
summary: Validate cover file
description: This endpoint allows you to validate cover file
security:
- oauth2: []
tags:
- Files validation
operationId: Validate-Cover_create
requestBody:
content:
application/json:
schema:
type: object
properties:
source_url:
description: Public url of the cover source file
type: string
pod_package_id:
description: POD Package ID of the book.
type: string
interior_page_count:
type: integer
required:
- source_url
- pod_package_id
- interior_page_count
example:
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1
pod_package_id: 0600X0900BWSTDPB060UW444MXX
interior_page_count: 210
responses:
201:
description: Created
content:
application/json:
schema:
type: object
properties:
id:
type: integer
readOnly: true
source_url:
description: The url of the source file.
type: string
readOnly: true
errors:
description: List of errors detected in the file.
type: array
readOnly: true
items:
type: string
status:
description: Status of source file
type: string
enum:
- NORMALIZING
- NORMALIZED
- ERROR
readOnly: true
required:
- id
- source_url
example:
id: 1
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1
page_count: 210
errors:
status: NORMALIZING
400:
$ref: '#/components/responses/BadRequest'
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
x-code-samples:
- lang: Python
source: |
import requests
import json
url = "https://api.lulu.com/validate-cover/"
payload = json.dumps({
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1",
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
})
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "json"
require "net/http"
url = URI("https://api.lulu.com/validate-cover/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1",
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
})
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.lulu.com/validate-cover/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1",
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://api.lulu.com/validate-cover/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.body("{\n \"source_url\": \"https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1\",\n \"page_count\": 210,\n \"pod_package_id\": \"0600X0900BWSTDPB060UW444MXX\"\n}").asString();
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1",
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.lulu.com/validate-cover/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location 'https://api.lulu.com/validate-cover/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{
"source_url": "https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1",
"pod_package_id": "0600X0900BWSTDPB060UW444MXX",
"interior_page_count": 210
}'
/validate-cover/{id}/:
get:
summary: Retrieve a single cover validation record
description: Retrieve a single cover validation record
parameters:
- description: Id of the resource
in: path
name: id
required: true
schema:
type: integer
example: 1
security:
- oauth2: []
tags:
- Files validation
operationId: Validate-Cover_read
responses:
200:
description: OK
content:
application/json:
schema:
type: object
properties:
id:
type: integer
readOnly: true
source_url:
description: The url of the source file.
type: string
readOnly: true
errors:
description: List of errors detected in the file.
type: array
readOnly: true
items:
type: string
status:
description: Status of source file
type: string
enum:
- NORMALIZING
- NORMALIZED
- ERROR
readOnly: true
required:
- id
- source_url
example:
id: 1
source_url: https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1
page_count: 210
errors:
status: NORMALIZING
401:
$ref: '#/components/responses/Unauthorized'
403:
$ref: '#/components/responses/Forbidden'
404:
$ref: '#/components/responses/NotFound'
x-code-samples:
- lang: Python
source: |
import requests
url = "https://api.lulu.com/validate-cover/{id}/"
payload = {}
headers = {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
- lang: Ruby
source: |
require "uri"
require "net/http"
url = URI("https://api.lulu.com/validate-cover/{id}/")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Check Authentication menu"
request["Cache-Control"] = "no-cache"
response = https.request(request)
puts response.read_body
- lang: Node
source: |
var request = require('request');
var options = {
'method': 'GET',
'url': 'https://api.lulu.com/validate-cover/{id}/',
'headers': {
'Authorization': 'Check Authentication menu',
'Cache-Control': 'no-cache'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
- lang: Java
source: |
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://api.lulu.com/validate-cover/{id}/")
.header("Authorization", "Check Authentication menu")
.header("Cache-Control", "no-cache")
.asString();
- lang: Javascript
source: |
var myHeaders = new Headers();
myHeaders.append("Authorization", "Check Authentication menu");
myHeaders.append("Cache-Control", "no-cache");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://api.lulu.com/validate-cover/{id}/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
- lang: cURL
source: |
curl --location --globoff 'https://api.lulu.com/validate-cover/{id}/' \
--header 'Authorization: Check Authentication menu' \
--header 'Cache-Control: no-cache'
components:
responses:
BadRequest:
description: Bad Request
content:
application/json:
schema:
example:
attribute_1:
- This field is required.
attribute_2:
- This field is required.
title: Bad Request
example:
attribute_1:
- This field is required.
attribute_2:
- This field is required.
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
example:
detail: Authentication credentials were not provided.
properties:
detail:
type: string
required:
- detail
title: Unauthorized
example:
detail: Authentication credentials were not provided.
Forbidden:
description: Forbidden
content:
application/json:
schema:
example:
detail: You do not have permission to perform this action.
properties:
detail:
type: string
required:
- detail
title: Forbidden
example:
detail: You do not have permission to perform this action.
NotFound:
description: Not Found
content:
application/json:
schema:
example:
detail: Not found.
properties:
detail:
type: string
required:
- detail
title: Not Found
example:
detail: Not found.
securitySchemes:
oauth2:
description: |
Get access to data while protecting your account credentials.
OAuth2 is also a safer and more secure way to give you access.
flows:
clientCredentials:
scopes: {}
tokenUrl: https://api.lulu.com/auth/realms/glasstree/protocol/openid-connect/token
implicit:
authorizationUrl: https://api.lulu.com/auth/realms/glasstree/protocol/openid-connect/auth?nonce=jwt_login
scopes: {}
password:
scopes: {}
tokenUrl: https://api.lulu.com/auth/realms/glasstree/protocol/openid-connect/token
type: oauth2
tags: []
security:
- oauth2: []