BlotPrints API
Al onze producten kun je bestellen via onze API. Gemaakt voor developers en voor AI-agents.
Introductie
De basis-URL is:
https://www.blotprints.com/api/v1
- Requests en responses zijn JSON (
Content-Type: application/json). - Je hebt geen API-key nodig. Per IP-adres geldt een limiet op het aantal calls (zie Limieten).
- Datums en tijden zijn in ISO 8601, in UTC, zoals
2026-10-25T12:00:00Z. - Er is geen testmodus: een offerte is gratis en verandert niets, en een bestelling wordt pas echt als hij betaald is.
Voorbeeldbestelling
Een hardcover boek bestellen uit pdf’s die online staan.
1. Vraag een offerte aan
curl -X POST https://www.blotprints.com/api/v1/quotes \
-H "Content-Type: application/json" \
-d '{
"items": [{
"product": "hardcover",
"size": "a5-portrait",
"options": { "cover": "matte", "paper": "matte_standard" },
"quantity": 1,
"files": {
"interior": { "url": "https://example.com/book-interior.pdf" },
"cover": { "url": "https://example.com/book-cover.pdf" }
}
}],
"shipping": { "country": "NL", "method": "standard" }
}'
2. Plaats de bestelling, met de quoteId uit het antwoord. Heeft de offerte waarschuwingen, zet er dan "acceptWarnings": true bij (zie 3. Offerte aanvragen).
curl -X POST https://www.blotprints.com/api/v1/orders \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5f1c2d3e-my-unique-key" \
-d '{
"quoteId": "quo_8hQ2kV7xLm3pR9tY",
"acceptTerms": true,
"email": "[email protected]",
"shippingAddress": {
"name": "Jane Doe",
"line1": "Keizersgracht 123",
"postalCode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
}
}'
3. Betaal de bestelling: open de paymentUrl uit het antwoord in een browser.
Een bestelling plaatsen
1. Product kiezen
In de producten zie je wat je kunt bestellen: per product de formaten, opties en prijzen, en welke bestanden we nodig hebben. Gebruik de namen die je hier vindt (product, size, de waarden van de opties) in je offerte.
Alle producten
GET https://www.blotprints.com/api/v1/products
Alles wat je kunt bestellen, met formaten, opties en prijzen.
{
"products": [
{
"product": "hardcover",
"name": "Hardcover book",
"sizes": [
{
"size": "a5-portrait",
"width": 148,
"height": 210,
"pages": { "min": 24, "max": 400, "step": 2 },
"files": {
"interior": { "fileTypes": ["pdf"], "width": 154, "height": 216, "bleed": 3 },
"cover": { "fileTypes": ["pdf", "jpg", "png"], "width": 354, "height": 255, "bleed": 19 }
},
"price": { "base": 15.99, "perExtraPage": 0.40 },
"options": {
"cover": {
"values": [
{ "value": "matte", "name": "Hardcover matte", "price": 5.99 },
{ "value": "glossy", "name": "Hardcover glossy", "price": 0 }
],
"default": "matte"
},
"paper": {
"values": [
{ "value": "matte_standard", "name": "Standard matte", "price": 0, "perExtraPage": 0 },
{ "value": "matte_heavy", "name": "Heavy matte", "price": 1.44, "perExtraPage": 0.07 }
],
"default": "matte_standard"
}
}
},
{
"size": "a5-landscape",
"width": 210,
"height": 148,
"pages": { "min": 24, "max": 400, "step": 2 },
"files": {
"interior": { "fileTypes": ["pdf"], "width": 216, "height": 154, "bleed": 3 },
"cover": { "fileTypes": ["pdf", "jpg", "png"], "width": 470, "height": 193, "bleed": 19 }
},
"price": { "base": 15.99, "perExtraPage": 0.40 },
"options": {
"cover": {
"values": [
{ "value": "matte", "name": "Hardcover matte", "price": 5.99 },
{ "value": "glossy", "name": "Hardcover glossy", "price": 0 }
],
"default": "matte"
},
"paper": {
"values": [
{ "value": "matte_standard", "name": "Standard matte", "price": 0, "perExtraPage": 0 },
{ "value": "matte_heavy", "name": "Heavy matte", "price": 1.44, "perExtraPage": 0.07 }
],
"default": "matte_standard"
}
}
}
]
}
]
}
| Veld | Omschrijving |
|---|---|
product |
De naam om mee te bestellen, zoals hardcover. |
name |
De naam van het product, om aan iemand te laten zien. |
sizes[].size |
De naam om mee te bestellen. Staand en liggend zijn aparte formaten: a5-portrait en a5-landscape, 30x40 en 40x30. Een vierkant formaat heeft er maar één, zoals 21x21. |
sizes[].width |
De breedte van het eindproduct, in millimeter. |
sizes[].height |
De hoogte van het eindproduct, in millimeter. |
sizes[].pages |
Alleen bij producten met pagina’s (boeken, tijdschriften, kalenders): het minimum en maximum aantal pagina’s, en de stap (2 betekent een even aantal). |
sizes[].files |
De bestanden die je meestuurt, op naam, met hun bestandstypen en hun maat in millimeter inclusief afloop. Een boek heeft een interior en meestal een cover, een poster of paneel heeft één design. |
sizes[].price.base |
De prijs van het formaat, zonder opties. Bij producten met pagina’s: met het minimum aantal pagina’s. |
sizes[].price.perExtraPage |
Alleen bij producten met pagina’s: wat elke pagina boven het minimum erbij kost. |
sizes[].options |
De opties van het formaat (zoals cover, paper of hanging): de mogelijke waarden, en welke de default is. Dat kan per formaat verschillen: een A0-poster heeft geen lijst, en de prijzen hangen af van het formaat. |
sizes[].options.{option}.values[].value |
De waarde om mee te bestellen, zoals matte. |
sizes[].options.{option}.values[].name |
De naam van de waarde, om aan iemand te laten zien. |
sizes[].options.{option}.values[].price |
Wat de waarde bij de prijs optelt; 0 als hij erbij inbegrepen is. |
sizes[].options.{option}.values[].perExtraPage |
Alleen bij waarden die per pagina meer kosten (het papier van een boek): wat ze erbij optellen voor elke pagina boven het minimum. |
Eén product
GET https://www.blotprints.com/api/v1/products/{product}
Hetzelfde als één product uit de lijst.
2. Bestanden toevoegen
Je bestanden zijn wat we drukken: het ontwerp van een poster of paneel, of het binnenwerk en de omslag van een boek, als pdf, jpg of png. Welke bestanden een formaat nodig heeft, staat in zijn files (zie 1. Product kiezen). Elk bestand kun je op twee manieren aanleveren: als link waar wij het downloaden, of door het naar ons te uploaden.
Downloadlink
Geef een URL op die we kunnen downloaden, met https. Handig voor bestanden die al online staan.
{ "url": "https://example.com/book-interior.pdf" }
De link moet werken zonder in te loggen op het moment dat je de offerte aanvraagt: dan downloaden we het bestand. Links die na een tijdje verlopen (zoals presigned links van een opslagdienst) zijn prima.
Een bestand uploaden
Voor bestanden op je eigen computer (of die van een agent) vraag je een uploadadres aan, en stuur je het bestand daarheen.
POST https://www.blotprints.com/api/v1/uploads
Je hoeft geen body mee te sturen. Het antwoord:
{
"uploadId": "upl_3vN8qR2xKt5mW7yZ",
"uploadUrl": "https://…",
"expiresAt": "2026-10-25T14:30:00Z"
}
| Veld | Omschrijving |
|---|---|
uploadId |
De upload, om in je offerte te gebruiken zodra het bestand verstuurd is. |
uploadUrl |
Waar je het bestand naartoe stuurt, met een PUT. |
expiresAt |
Tot wanneer uploadUrl werkt (een uur). |
Stuur dan het bestand:
curl -T book-interior.pdf "<uploadUrl>"
En gebruik de upload in je offerte:
{ "uploadId": "upl_3vN8qR2xKt5mW7yZ" }
- Bestandstypen: pdf, jpg en png, voor zover het product ze toestaat. We kijken naar wat er echt in het bestand zit, niet naar de naam of extensie: al het andere weigeren we (
unsupported_file_type). - Maximaal 200 MB per bestand.
- Een upload die we weigeren (een ander type, of te groot) verwijderen we meteen: upload dan het juiste bestand opnieuw.
- Een uploadadres werkt een uur; een upload bewaren we een dag.
3. Offerte aanvragen
Een offerte is de stap vóór een bestelling: je stuurt wat je wilt laten drukken, met de bestanden, en wij controleren de bestanden en vertellen je wat het kost, inclusief verzending. Er is dan nog niets besteld of betaald. Ziet het er goed uit, dan plaats je de bestelling met de offerte.
POST https://www.blotprints.com/api/v1/quotes
{
"items": [
{
"product": "poster",
"size": "a3-landscape",
"options": { "paper": "matte", "hanging": "photo_frame_black" },
"quantity": 2,
"files": { "design": { "uploadId": "upl_3vN8qR2xKt5mW7yZ" } }
}
],
"shipping": { "country": "NL", "method": "standard" }
}
| Veld | Omschrijving |
|---|---|
items |
Verplicht. Wat er gedrukt moet worden: een of meer items, allemaal in één bestelling. |
items[].product |
Verplicht. Het product, zoals hardcover (zie 1. Product kiezen). |
items[].size |
Verplicht. Het formaat, zoals a5-portrait of 40x30. |
items[].options |
Optioneel. Per optie van het product een waarde, zoals { "cover": "matte" }. Een optie die je weglaat, krijgt zijn default. |
items[].quantity |
Optioneel. 1 tot 50, standaard 1. |
items[].files |
Verplicht. De bestanden, op naam, zoals interior en cover, of design: de namen uit files van het formaat in het product. |
items[].files.{name}.url |
Een link naar het bestand. Geef dit of uploadId op: zie 2. Bestanden toevoegen. |
items[].files.{name}.uploadId |
Een upload van het bestand. Geef dit of url op: zie 2. Bestanden toevoegen. |
shipping |
Verplicht. Waarheen en hoe we verzenden. |
shipping.country |
Verplicht. Elk land van de EU, met de landcode van twee letters, zoals NL, DE of IT. |
shipping.method |
Optioneel. standard (standaard) of express. Express kan niet bij elk product: dan verzendt de offerte standaard, en staat dat in shipping.note. |
Het antwoord:
{
"quoteId": "quo_8hQ2kV7xLm3pR9tY",
"expiresAt": "2026-10-26T12:00:00Z",
"previewUrl": "https://www.blotprints.com/preview/quo_8hQ2kV7xLm3pR9tY",
"items": [
{
"product": "poster",
"size": "a3-landscape",
"options": { "paper": "matte", "hanging": "photo_frame_black" },
"quantity": 2,
"unitPrice": 25.98,
"price": 51.96,
"vat": 9.02,
"warnings": [
{
"code": "design_adjusted",
"file": "design",
"message": "The design is a different size or shape than the size needs. We zoom it in to fit, so 9.1% is cut off at the edges. Check the preview.",
"values": { "cutOffPercent": 9.1 }
}
],
"previews": [
{
"file": "design",
"url": "https://www.blotprints.com/api/v1/quotes/quo_8hQ2kV7xLm3pR9tY/previews/0-design.jpg",
"width": 1200,
"height": 853,
"description": "The design as it's printed. The red line is where it's cut."
}
]
}
],
"shipping": {
"method": "standard",
"price": 5.00,
"vat": 0.87,
"estimatedDelivery": { "from": "2026-10-28", "to": "2026-10-29" },
"note": null
},
"shippingOptions": [
{
"method": "standard",
"price": 5.00,
"vat": 0.87,
"estimatedDelivery": { "from": "2026-10-28", "to": "2026-10-29" }
},
{
"method": "express",
"price": 12.50,
"vat": 2.17,
"estimatedDelivery": { "from": "2026-10-27", "to": "2026-10-27" }
}
],
"total": 56.96,
"vat": 9.89,
"currency": "EUR",
"termsUrl": "https://www.blotprints.com/terms"
}
| Veld | Omschrijving |
|---|---|
quoteId |
De offerte, om de bestelling mee te plaatsen. |
expiresAt |
Tot wanneer je de offerte kunt bestellen (24 uur). |
previewUrl |
Een pagina die de bestanden laat zien zoals wij ze drukken, hetzelfde voorbeeld als op onze website: waar het wordt afgesneden, de rug van een boek, elke pagina. Laat die aan de klant zien voordat je bestelt. De pagina is in hun eigen taal, en alleen wie de link heeft, kan hem zien. |
items[].pageCount |
Alleen bij producten met pagina’s: het aantal pagina’s dat we in je bestand hebben geteld, waar de prijs op gebaseerd is. |
items[].unitPrice |
De prijs van één exemplaar, met de opties. |
items[].price |
De prijs van alle exemplaren van het item samen. |
items[].vat |
De btw die in de price van het item zit. |
items[].warnings |
Dingen die we bij het drukken aanpassen en die je moet weten, zoals een ontwerp met een andere verhouding dat een stukje wordt afgesneden. Leeg als er niets is. Wil je toch bestellen, zet dan acceptWarnings bij het plaatsen van de bestelling. |
items[].warnings[].code |
Wat voor waarschuwing het is, zoals design_adjusted, pages_adjusted of cover_adjusted (een bestand met een andere maat, ingezoomd zodat het past), of low_resolution (een afbeelding die misschien onscherp wordt). Er zijn er meer: laat de message aan de klant zien. |
items[].warnings[].file |
Over welk bestand van het item het gaat. |
items[].warnings[].message |
Wat er aan de hand is, om aan iemand te laten zien. |
items[].warnings[].values |
De getallen uit de melding, zodat je het op je eigen manier kunt zeggen. cutOffPercent bij design_adjusted, pages_adjusted, cover_adjusted en scaled: hoeveel er wordt afgesneden (bij pagina’s: het meeste van alle pagina’s), met difference: wat er anders is (landscape of portrait: het ligt de andere kant op; wider of taller: een andere verhouding; smaller of larger: een andere maat, en dan ook fileSize en printSize, zoals "210 × 297 mm"). dpi en minimumDpi bij low_resolution: met hoeveel dpi de afbeelding gedrukt wordt, en vanaf welke waarde hij scherp is. Andere waarschuwingen kunnen andere waarden hebben, zoals pageCount. |
items[].previews |
Een afbeelding van elk bestand zoals we het drukken: een jpg van 1200 pixels aan de lange kant, met een rode lijn waar het wordt afgesneden. Bij een boek: de hele omslag met de rug, en pagina 2 en 3 van het binnenwerk (de previewUrl laat elke pagina zien). Leeg als we ze niet konden maken; de offerte werkt ook zonder. |
items[].previews[].file |
Welk bestand van het item de afbeelding laat zien. |
items[].previews[].url |
De afbeelding. Alleen wie de link heeft, kan hem zien. |
items[].previews[].description |
Wat de afbeelding laat zien, en wat de lijnen betekenen. |
shipping.method |
Hoe het verzonden wordt: standard of express. Standaard als je om express vroeg en dat niet kan (zie note). |
shipping.price |
De verzendkosten. Standaard verzenden is gratis (0) als de items samen € 50 of meer kosten; express houdt zijn prijs. |
shipping.vat |
De btw die in de verzendkosten zit. |
shipping.estimatedDelivery |
Wanneer het naar verwachting aankomt, als periode van twee datums. Niet gegarandeerd. |
shipping.note |
Waarom het anders verzonden wordt dan je vroeg, om aan de klant te laten zien: express kan niet bij deze bestelling, dus het gaat standaard. Anders null. |
shippingOptions |
Alle manieren waarop deze bestelling naar dit land kan, elk met method, price, vat en estimatedDelivery, ook die van deze offerte. Om de klant te laten kiezen: laat deze zien, en vraag een nieuwe offerte aan met de shipping.method die ze kiezen. total en vat gelden voor de shipping van de offerte zelf. |
total |
Alles bij elkaar: de items en de verzending. |
vat |
De btw die in het total zit. |
termsUrl |
Onze voorwaarden, die gelden voor de bestelling. Lees ze voordat je ze accepteert bij het plaatsen van de bestelling. |
Een bestand dat we niet kunnen drukken (verkeerd type, te weinig pagina’s, onleesbaar) geeft een foutmelding: de offerte mislukt met 422, en problems noemt elk probleem van elk bestand, zodat je ze in één keer kunt oplossen. Zie Foutmeldingen.
Een offerte kun je één keer bestellen. Voor een volgende bestelling vraag je een nieuwe offerte aan.
4. Bestelling plaatsen
Een bestelling is een offerte die je hebt besloten te kopen, met het adres waar hij heen moet. Je krijgt een betaallink: zodra er betaald is, drukken en versturen we hem, en kun je de status volgen tot hij aankomt.
POST https://www.blotprints.com/api/v1/orders
{
"quoteId": "quo_8hQ2kV7xLm3pR9tY",
"acceptTerms": true,
"acceptWarnings": true,
"reference": "SHOP-2026-0042",
"email": "[email protected]",
"shippingAddress": {
"name": "Jane Doe",
"line1": "Keizersgracht 123",
"line2": "",
"postalCode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
}
}
| Veld | Omschrijving |
|---|---|
quoteId |
Verplicht. De offerte die je bestelt, uit 3. Offerte aanvragen. Een offerte kun je één keer bestellen. |
reference |
Optioneel. Je eigen kenmerk voor de bestelling, zoals je eigen ordernummer: maximaal 100 tekens. We sturen het mee terug met de bestelling, zodat je hem aan de jouwe kunt koppelen. |
acceptTerms |
Verplicht. true om onze voorwaarden te accepteren (de termsUrl van de offerte). Zonder dit weigeren we de bestelling met terms_not_accepted. Wie betaalt, accepteert ze ook nog op de betaalpagina. |
acceptWarnings |
Optioneel. true om een offerte met waarschuwingen te bestellen. Zonder dit weigeren we zo’n offerte met warnings_not_accepted. |
email |
Verplicht. Waar we de bevestiging en de track & trace naartoe sturen. |
shippingAddress |
Verplicht. Waar het heen moet. |
shippingAddress.name |
Verplicht. De naam van de ontvanger. |
shippingAddress.line1 |
Verplicht. De eerste adresregel: meestal straat en huisnummer. |
shippingAddress.line2 |
Optioneel. Een tweede adresregel, zoals een appartement of een bedrijfsnaam. |
shippingAddress.postalCode |
Verplicht. De postcode. |
shippingAddress.city |
Verplicht. De plaats. |
shippingAddress.country |
Verplicht. Het land van de offerte. |
| Header | Omschrijving |
|---|---|
Idempotency-Key |
Optioneel, maar aangeraden. Een willekeurige unieke tekst, zoals een UUID, zodat een nieuwe poging niet dubbel bestelt. Zie Idempotentie. |
Het antwoord (201):
{
"orderId": "1042-x7Kq2mV9pL4tR8wN3bY6zA",
"reference": "SHOP-2026-0042",
"status": "awaiting_payment",
"paymentUrl": "https://www.blotprints.com/pay/1042-x7Kq2mV9pL4tR8wN3bY6zA",
"total": 56.96,
"currency": "EUR"
}
| Veld | Omschrijving |
|---|---|
orderId |
De bestelling. Bewaar hem goed: het is de enige manier om de bestelling op te vragen, en hij is geheim, want iedereen die hem heeft, kan de bestelling zien. |
reference |
Je eigen kenmerk, zoals je het stuurde; null als je er geen gaf. |
status |
awaiting_payment: geplaatst, wacht op betaling. Alle statussen staan bij 6. Bestelling volgen. |
paymentUrl |
De pagina waar iemand de bestelling betaalt. Zie 5. Betalen. |
5. Betalen
Open de paymentUrl in een browser. Daar staat de bestelling, en wordt er gevraagd om te betalen (iDEAL, kaart en de andere betaalmethoden van het land). Zodra er betaald is, gaan we drukken. Een bestelling die niet binnen 7 dagen betaald is, vervalt.
6. Bestelling volgen
GET https://www.blotprints.com/api/v1/orders/{orderId}
{
"orderId": "1042-x7Kq2mV9pL4tR8wN3bY6zA",
"reference": "SHOP-2026-0042",
"status": "shipped",
"createdAt": "2026-10-25T12:00:00Z",
"paidAt": "2026-10-25T12:05:00Z",
"items": [
{
"product": "poster",
"size": "a3-landscape",
"options": { "paper": "matte", "hanging": "photo_frame_black" },
"quantity": 2,
"unitPrice": 25.98,
"price": 51.96,
"vat": 9.02
}
],
"shipping": {
"method": "standard",
"price": 5.00,
"vat": 0.87,
"trackingUrl": "https://…"
},
"shippingAddress": {
"name": "Jane Doe",
"line1": "Keizersgracht 123",
"line2": "",
"postalCode": "1015 CJ",
"city": "Amsterdam",
"country": "NL"
},
"total": 56.96,
"vat": 9.89,
"currency": "EUR",
"paymentUrl": null
}
| Veld | Omschrijving |
|---|---|
status |
Waar de bestelling is, zie hieronder. |
items, shipping, total, vat |
Zoals in de offerte waar de bestelling van gemaakt is. |
paidAt |
Wanneer er betaald is; tot die tijd null. |
shipping.trackingUrl |
Waar je het pakket kunt volgen; null zolang die er nog niet is. Hij kan pas een tijdje nadat de bestelling als verzonden staat beschikbaar komen. |
shippingAddress |
Waar het heen gaat, zoals je het stuurde bij het plaatsen van de bestelling, netjes gemaakt (zoals de spatie in de postcode). |
paymentUrl |
Waar je betaalt; null zodra er betaald is of de bestelling vervallen is. |
status is een van:
| Status | Betekenis |
|---|---|
awaiting_payment |
Geplaatst, wacht op betaling. |
paid |
Betaald. |
preparing |
Wordt klaargemaakt voor de drukker. |
in_production |
Wordt gedrukt. |
shipped |
Onderweg. |
cancelled |
Niet op tijd betaald, of geannuleerd. |
Naslag
Foutmeldingen
Een foutmelding heeft een HTTP-status en een body zoals deze:
{
"error": {
"code": "file_check_failed",
"message": "The interior has 18 pages. It needs at least 24. The cover isn't a file type we print.",
"item": 0,
"file": "interior",
"problems": [
{
"item": 0,
"file": "interior",
"code": "too_few_pages",
"message": "The interior has 18 pages. It needs at least 24.",
"values": { "pageCount": 18, "min": 24 }
},
{
"item": 0,
"file": "cover",
"code": "unsupported_file_type",
"message": "The cover isn't a file type we print."
}
]
}
}
| Veld | Omschrijving |
|---|---|
error.code |
Wat er misging, als vaste code om in je eigen code op te controleren (zie de tabel hieronder). |
error.message |
Wat er mis is en hoe je het oplost, geschreven om aan iemand te laten zien of door een agent te laten lezen. |
error.item |
Alleen bij een fout over een item van een offerte: welk item, geteld vanaf 0. |
error.file |
Alleen bij een fout over een bestand: welk bestand van het item, zoals interior, cover of design. Bij meerdere problemen: dat van het eerste. |
error.problems |
Alleen bij file_check_failed: elk probleem, van elk bestand en item, elk met item, file, code (zoals too_few_pages, pdf_only, file_too_large of file_unreadable), message, en de getallen uit de melding (values). |
error.docs |
Het deel van deze documentatie over de fout. |
| Status | Code | Wanneer |
|---|---|---|
400 |
invalid_request |
De JSON klopt niet, of er ontbreekt een veld. |
404 |
not_found |
Dat product, die upload, offerte of bestelling bestaat niet. |
409 |
quote_already_ordered |
De offerte is al besteld. Vraag een nieuwe aan voor een volgende bestelling. |
409 |
idempotency_key_reused |
De Idempotency-Key is al eerder gebruikt, voor een ander request. Gebruik een nieuwe key. |
410 |
quote_expired |
De offerte is ouder dan 24 uur. Vraag een nieuwe aan. |
422 |
file_check_failed |
Er zijn bestanden die we niet kunnen drukken. problems noemt ze allemaal. |
422 |
file_unreachable |
We konden een bestandslink niet downloaden. |
422 |
country_mismatch |
shippingAddress.country is niet het land van de offerte. |
422 |
terms_not_accepted |
Zet acceptTerms om onze voorwaarden te accepteren. |
422 |
warnings_not_accepted |
De offerte heeft waarschuwingen: zet acceptWarnings. |
429 |
rate_limited |
Te veel requests. Wacht Retry-After seconden. |
500 |
server_error |
Er ging bij ons iets mis. Probeer het later opnieuw. |
Idempotentie
Netwerken haperen, en scripts en agents proberen het dan opnieuw. Om zeker te weten dat een bestelling nooit twee keer geplaatst wordt, stuur je bij POST /orders een Idempotency-Key-header mee: een willekeurige unieke tekst, zoals een UUID.
Stuur je binnen 24 uur dezelfde key nog eens, dan krijg je dezelfde bestelling terug in plaats van een nieuwe. Gebruik voor elke nieuwe bestelling een nieuwe key.
Limieten
Per IP-adres:
| Wat | Limiet |
|---|---|
| Alle calls | 60 per minuut |
POST /quotes |
30 per uur |
POST /orders |
10 per uur |
Kom je boven een limiet, dan krijg je 429 met een Retry-After-header: het aantal seconden dat je moet wachten.
Voor AI-agents
Deze documentatie staat ook als platte Markdown op /api/docs.md, in het Engels: lees die om de API te leren kennen. AI-tools vinden hem ook via /llms.txt, met de tips hieronder.
MCP-server. AI-assistenten die het Model Context Protocol ondersteunen (Claude, ChatGPT, Copilot, …) kunnen BlotPrints toevoegen als connector, op:
https://www.blotprints.com/mcp
Inloggen is niet nodig. De assistent krijgt dan de stappen van deze pagina als tools: list_products, get_product, create_upload, get_quote, place_order en get_order.
OpenAPI. De API is ook beschreven in OpenAPI 3.1, op /api/openapi.json: voor tools die dat lezen, zoals codegenerators of de actions van een custom GPT.
Tips voor agents:
- Begin met
GET /productsom te zien wat er kan, en kies formaten en opties daaruit: gok geen namen. - Gebruik voor bestanden op de computer van de gebruiker een upload:
curl -T bestand.pdf "<uploadUrl>". - Laat de gebruiker het voorbeeld van de offerte (
previewUrl), de prijs, de waarschuwingen en de voorwaarden (termsUrl) zien voordat je de bestelling plaatst, en vraag of het voorbeeld klopt. - Geef de gebruiker de
paymentUrlom te betalen: zelf betalen kun je niet. - Bewaar de
orderId, om de bestelling later op te vragen.
Veelgestelde vragen
Hoe pas ik een offerte aan?
Een offerte kun je niet aanpassen. Vraag een nieuwe aan met wat je nu wilt: dat is gratis en duurt maar even. De oude verloopt na 24 uur vanzelf.
Hoe vervang ik een bestand?
Voordat je bestelt: upload of link het nieuwe bestand, en vraag er een nieuwe offerte mee aan.
Na het bestellen, maar voordat er betaald is: de paymentUrl opent onze kassa, waar je de bestelling nog kunt aanpassen. Met Wijzigen naast een item open je het op onze website, met de bestanden, om een ander te kiezen.
Is er betaald, dan kan er niets meer veranderen: we drukken het speciaal voor jou.
Hoe pas ik een bestelling aan, zoals het adres of het aantal?
Daar is geen API-call voor. Zolang er niet betaald is, opent de paymentUrl onze kassa, waar wie betaalt het adres en de aantallen nog kan aanpassen, bestanden kan vervangen of items kan weghalen. GET /orders/{orderId} laat daarna de bestelling zien zoals hij nu is.
Je kunt hem ook laten voor wat hij is en een nieuwe bestelling plaatsen met een nieuwe offerte: een bestelling die niet betaald wordt, vervalt na 7 dagen vanzelf.
Is er betaald, dan kan er niets meer veranderen: we drukken het speciaal voor jou.
Hoe annuleer ik een bestelling?
Betaal hem gewoon niet: een onbetaalde bestelling vervalt na 7 dagen vanzelf, en de status wordt cancelled. Er wordt niets gedrukt en niets afgeschreven.
Een betaalde bestelling kun je niet annuleren of retourneren: we drukken hem speciaal voor jou (zie onze voorwaarden).
Kan ik de API testen zonder te bestellen?
Er is geen testmodus, en die heb je ook niet nodig: producten, uploads en offertes zijn gratis en veranderen niets. Een offerte controleert je bestanden en laat de voorbeelden zien, dus alles tot aan het bestellen kun je testen.
Je kunt zelfs een bestelling plaatsen: zolang die niet betaald is, wordt er niets gedrukt, en na 7 dagen vervalt hij.
Wie betaalt er, en kan ik op factuur betalen?
Elke bestelling wordt apart betaald via zijn eigen paymentUrl, met iDEAL, kaart of een andere betaalmethode van het land: door jou, of door je klant als je de link doorstuurt. Op factuur of per maand betalen kan nog niet.
Een AI-agent kan niet betalen: die geeft de paymentUrl aan de gebruiker.
Kunnen jullie rechtstreeks naar mijn klant verzenden?
Ja. Zet het adres van je klant in shippingAddress. Het email krijgt de bevestiging en de track & trace: gebruik dat van je klant, of je eigen adres als je dat liever zelf houdt.
Eén bestelling gaat naar één adres. Moet het naar meerdere adressen, vraag dan per adres een offerte aan en plaats per adres een bestelling.
Naar welke landen versturen jullie?
Naar elk land van de EU, met track & trace: geef de landcode van twee letters op in shipping.country, zoals NL, DE of IT. De offerte geeft de verzendkosten en de verwachte bezorgdatum, die afhangen van hoe ver het moet. Standaard verzenden is gratis vanaf € 50; express is sneller, bij de producten waar dat kan. In shippingOptions van de offerte staan alle verzendmanieren, met prijs en datums.
Hoe weet ik wanneer een bestelling betaald of verzonden is?
Webhooks zijn er nog niet. Vraag de bestelling af en toe op met GET /orders/{orderId}, bijvoorbeeld om de paar uur: de status vertelt waar hij is, en shipping.trackingUrl waar het pakket is zodra het verzonden is. Het email van de bestelling krijgt ook een bevestiging en de track & trace.
Mijn offerte heeft waarschuwingen. Wat moet ik doen?
Kijk eerst naar de previewUrl: daar zie je hoe we de bestanden drukken. Een waarschuwing betekent dat we bij het drukken iets aanpassen, zoals inzoomen op een ontwerp met een andere verhouding, waardoor de randen eraf gaan.
Ziet het er goed uit? Bestel dan met "acceptWarnings": true. Zo niet, pas dan het bestand aan en vraag een nieuwe offerte aan. De values van de waarschuwing zeggen hoeveel, zoals cutOffPercent of dpi.
Waarom is mijn bestand geweigerd?
Een bestand dat we niet kunnen drukken, laat de offerte mislukken met file_check_failed, en problems noemt elk probleem met het bijbehorende bestand, zodat je ze in één keer kunt oplossen. Vaak gaat het om het type (het binnenwerk van een boek moet een pdf zijn), het aantal pagina's, of een bestand van meer dan 200 MB. Een link die we niet kunnen downloaden, geeft file_unreachable: controleer of hij werkt zonder in te loggen.
De maten, aantallen pagina's en bestandstypen die elk product nodig heeft, staan in zijn files.
Zijn de prijzen hetzelfde als op de website?
Ja, en inclusief btw. Het gaat om de btw van het land waar het heen gaat, en de offerte laat die per item en voor de verzending zien. Prijzen kunnen veranderen: de prijzen van een offerte gelden de 24 uur dat hij geldig is.
Heb ik een API-key nodig? En als de limieten te laag zijn?
Een key is niet nodig. De limieten gelden per IP-adres, en zijn ruim genoeg voor de meeste shops en agents. Heb je meer nodig, laat het ons weten.
Wat doen jullie met mijn bestanden?
We gebruiken ze alleen om je bestelling te drukken. Alleen wie de links heeft, kan ze zien: de previewUrl, de voorbeelden en de orderId zijn niet te raden. Uploads en offertes verwijderen we na 7 dagen, de bestanden van een bestelling 90 dagen na verzending.
Er is iets mis met wat er is aangekomen. Bij wie moet ik zijn?
Laat het ons weten met het bestelnummer (het deel van de orderId vóór het streepje) en het e-mailadres van de bestelling, en een foto als dat helpt. We lossen het op.