curl --request POST \
--url https://api.print.app/v2/print-options/quote \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"config": {},
"optionSetId": "<string>",
"quotes": [
{
"selections": {},
"file": {
"pages": 1,
"colorPages": 1,
"monoPages": 1
}
}
]
}
'import requests
url = "https://api.print.app/v2/print-options/quote"
payload = {
"config": {},
"optionSetId": "<string>",
"quotes": [
{
"selections": {},
"file": {
"pages": 1,
"colorPages": 1,
"monoPages": 1
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
config: {},
optionSetId: '<string>',
quotes: [{selections: {}, file: {pages: 1, colorPages: 1, monoPages: 1}}]
})
};
fetch('https://api.print.app/v2/print-options/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.print.app/v2/print-options/quote",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'config' => [
],
'optionSetId' => '<string>',
'quotes' => [
[
'selections' => [
],
'file' => [
'pages' => 1,
'colorPages' => 1,
'monoPages' => 1
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.print.app/v2/print-options/quote"
payload := strings.NewReader("{\n \"config\": {},\n \"optionSetId\": \"<string>\",\n \"quotes\": [\n {\n \"selections\": {},\n \"file\": {\n \"pages\": 1,\n \"colorPages\": 1,\n \"monoPages\": 1\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.print.app/v2/print-options/quote")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"config\": {},\n \"optionSetId\": \"<string>\",\n \"quotes\": [\n {\n \"selections\": {},\n \"file\": {\n \"pages\": 1,\n \"colorPages\": 1,\n \"monoPages\": 1\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.print.app/v2/print-options/quote")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"config\": {},\n \"optionSetId\": \"<string>\",\n \"quotes\": [\n {\n \"selections\": {},\n \"file\": {\n \"pages\": 1,\n \"colorPages\": 1,\n \"monoPages\": 1\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"object": "option_set_quote",
"currency": "USD",
"quotes": [
{
"selections": {
"size": "a4"
},
"quantity": 1,
"total": 15,
"unitPrice": 15,
"unavailable": false,
"unavailableReason": null,
"sku": null,
"lines": [
{
"label": "Base price",
"amount": 10,
"stage": "base",
"source": "base"
},
{
"label": "A4",
"amount": 5,
"stage": "additive",
"source": "size:a4"
}
],
"issues": []
}
],
"fields": [
{
"id": "size",
"label": "Size",
"type": "select-one",
"role": "size",
"source": {
"role": "size"
},
"reference": "po:role/size",
"sends": "choice id as value, label as text",
"choices": [
{
"value": "a5",
"label": "A5",
"selected": true
},
{
"value": "a4",
"label": "A4",
"selected": false
}
]
}
],
"warnings": []
}{
"error": true,
"code": "invalid_request",
"message": "width is required.",
"param": "width",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "unauthorized",
"message": "Missing or invalid secret key. Send it as \"Authorization: Bearer sk_…\".",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "account_suspended",
"message": "This account is suspended. Settle the outstanding invoice in the Print.App dashboard.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "not_found",
"message": "Not found.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "folder_not_empty",
"message": "The folder still holds designs. Remove them from it (or delete them) first.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "payload_too_large",
"message": "The file at url is larger than 50 MB.",
"param": "url",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "unsupported_media_type",
"message": "Send the request body as JSON, with \"Content-Type: application/json\".",
"requestId": "FZn-uhymjoEEJow="
}{
"message": "Too Many Requests"
}{
"error": true,
"code": "internal_error",
"message": "Something went wrong on our side. Retry the request; if it keeps failing, contact support with the requestId.",
"requestId": "FZn-uhymjoEEJow="
}Price choices on an option set
Checks an option set and prices up to 25 sets of choices on it, line by line, with the engine that prices the cart: an option set being built (config) or one of the store’s (optionSetId). Choices left out take the set’s defaults. Writes nothing. With config it works for any account.
curl --request POST \
--url https://api.print.app/v2/print-options/quote \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"config": {},
"optionSetId": "<string>",
"quotes": [
{
"selections": {},
"file": {
"pages": 1,
"colorPages": 1,
"monoPages": 1
}
}
]
}
'import requests
url = "https://api.print.app/v2/print-options/quote"
payload = {
"config": {},
"optionSetId": "<string>",
"quotes": [
{
"selections": {},
"file": {
"pages": 1,
"colorPages": 1,
"monoPages": 1
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
config: {},
optionSetId: '<string>',
quotes: [{selections: {}, file: {pages: 1, colorPages: 1, monoPages: 1}}]
})
};
fetch('https://api.print.app/v2/print-options/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.print.app/v2/print-options/quote",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'config' => [
],
'optionSetId' => '<string>',
'quotes' => [
[
'selections' => [
],
'file' => [
'pages' => 1,
'colorPages' => 1,
'monoPages' => 1
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.print.app/v2/print-options/quote"
payload := strings.NewReader("{\n \"config\": {},\n \"optionSetId\": \"<string>\",\n \"quotes\": [\n {\n \"selections\": {},\n \"file\": {\n \"pages\": 1,\n \"colorPages\": 1,\n \"monoPages\": 1\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.print.app/v2/print-options/quote")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"config\": {},\n \"optionSetId\": \"<string>\",\n \"quotes\": [\n {\n \"selections\": {},\n \"file\": {\n \"pages\": 1,\n \"colorPages\": 1,\n \"monoPages\": 1\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.print.app/v2/print-options/quote")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"config\": {},\n \"optionSetId\": \"<string>\",\n \"quotes\": [\n {\n \"selections\": {},\n \"file\": {\n \"pages\": 1,\n \"colorPages\": 1,\n \"monoPages\": 1\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"object": "option_set_quote",
"currency": "USD",
"quotes": [
{
"selections": {
"size": "a4"
},
"quantity": 1,
"total": 15,
"unitPrice": 15,
"unavailable": false,
"unavailableReason": null,
"sku": null,
"lines": [
{
"label": "Base price",
"amount": 10,
"stage": "base",
"source": "base"
},
{
"label": "A4",
"amount": 5,
"stage": "additive",
"source": "size:a4"
}
],
"issues": []
}
],
"fields": [
{
"id": "size",
"label": "Size",
"type": "select-one",
"role": "size",
"source": {
"role": "size"
},
"reference": "po:role/size",
"sends": "choice id as value, label as text",
"choices": [
{
"value": "a5",
"label": "A5",
"selected": true
},
{
"value": "a4",
"label": "A4",
"selected": false
}
]
}
],
"warnings": []
}{
"error": true,
"code": "invalid_request",
"message": "width is required.",
"param": "width",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "unauthorized",
"message": "Missing or invalid secret key. Send it as \"Authorization: Bearer sk_…\".",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "account_suspended",
"message": "This account is suspended. Settle the outstanding invoice in the Print.App dashboard.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "not_found",
"message": "Not found.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "folder_not_empty",
"message": "The folder still holds designs. Remove them from it (or delete them) first.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "payload_too_large",
"message": "The file at url is larger than 50 MB.",
"param": "url",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "unsupported_media_type",
"message": "Send the request body as JSON, with \"Content-Type: application/json\".",
"requestId": "FZn-uhymjoEEJow="
}{
"message": "Too Many Requests"
}{
"error": true,
"code": "internal_error",
"message": "Something went wrong on our side. Retry the request; if it keeps failing, contact support with the requestId.",
"requestId": "FZn-uhymjoEEJow="
}Authorizations
A secret key from Print.App admin → Domains → Secret keys, sent as Authorization: Bearer sk_…. Server-side only.
Body
An option set, and the choices to price on it.
An option set to check and price (one being built). Or give optionSetId.
One of the store's option sets.
1 - 64Each set of choices to price. Default: one quote, of the defaults.
1 - 25 elementsShow child attributes
Show child attributes
Response
OK.
Prices for each set of choices, as the cart would charge them.
"option_set_quote"Show child attributes
Show child attributes
Its fields as connectors address them: give a field's source as a connector's source.
Show child attributes
Show child attributes
Things that will not stop it working but may not be meant.
Show child attributes
Show child attributes