🖨️ Print-on-Demand API
Anbieter: FLYERALARM, Vistaprint, Gelato, Printful
Use Case: Exposé-Druck, Marketing-Material
Status: 🟡 B2B-Vertrag erforderlich
Übersicht
Print-on-Demand Integration für automatischen Druck von:
- Exposés - Immobilien-Broschüren
- Flyer - Marketing-Flyer
- Plakate - Baustellenschilder
- Visitenkarten - Makler-Karten
- Mappen - Präsentationsmappen
Anbieter-Vergleich
| Anbieter |
API |
B2B |
White-Label |
Lieferzeit |
| FLYERALARM |
REST (B2B) |
✅ |
✅ |
1-5 Tage |
| Vistaprint |
ProShop API |
✅ |
✅ |
2-7 Tage |
| Gelato |
REST |
✅ |
✅ |
3-5 Tage |
| Printful |
REST |
✅ |
✅ |
2-5 Tage |
Unified API
Wir abstrahieren alle Anbieter unter einer einheitlichen API:
Products
| Methode |
Endpunkt |
Beschreibung |
Cache TTL |
GET |
/api/print/products |
Produktkatalog |
24h |
GET |
/api/print/products/:id |
Produkt Details |
24h |
GET |
/api/print/products/:id/pricing |
Preisberechnung |
1h |
GET |
/api/print/products/:id/specs |
Druckspezifikationen |
24h |
Orders
| Methode |
Endpunkt |
Beschreibung |
Cache TTL |
POST |
/api/print/orders |
Bestellung erstellen |
- |
GET |
/api/print/orders |
Alle Bestellungen |
5 min |
GET |
/api/print/orders/:id |
Bestellung Details |
5 min |
GET |
/api/print/orders/:id/status |
Status-Tracking |
5 min |
DELETE |
/api/print/orders/:id |
Bestellung stornieren |
- |
Files
| Methode |
Endpunkt |
Beschreibung |
Cache TTL |
POST |
/api/print/files/upload |
Druckdatei hochladen |
- |
GET |
/api/print/files/:id/preview |
Vorschau generieren |
1h |
GET |
/api/print/files/:id/preflight |
Druckdatei prüfen |
- |
Shipping
| Methode |
Endpunkt |
Beschreibung |
Cache TTL |
POST |
/api/print/shipping/rates |
Versandkosten berechnen |
1h |
GET |
/api/print/shipping/methods |
Versandmethoden |
24h |
Produkt-Typen für Immobilien
Exposé-Broschüren
// POST /api/print/orders
{
"productId": "brochure-a4-saddle-stitch",
"provider": "flyeralarm",
"quantity": 50,
"options": {
"pages": 8,
"paper": "170gsm-glossy",
"binding": "saddle-stitch",
"finishing": "none"
},
"files": {
"content": "file-uuid-12345"
},
"shipping": {
"method": "standard",
"address": {
"name": "Immobilien GmbH",
"street": "Musterstraße 1",
"city": "München",
"postcode": "80331",
"country": "DE"
}
}
}
Verfügbare Produkte
| Kategorie |
Produkte |
| Exposés |
Broschüren (A4, A5), Faltblätter, Booklets |
| Schilder |
Bauschilder, Verkaufsschilder, Steckschilder |
| Marketing |
Flyer, Postkarten, Visitenkarten |
| Präsentation |
Mappen, Ringordner, Sammelboxen |
| Werbetechnik |
Roll-Ups, Banner, Beachflags |
Request-Beispiel
// Exposé drucken
async function printExpose(propertyId: string, quantity: number) {
// 1. PDF generieren
const pdf = await generateExposePDF(propertyId);
// 2. Datei hochladen
const fileUpload = await fetch('/api/print/files/upload', {
method: 'POST',
body: pdf,
headers: { 'Content-Type': 'application/pdf' }
});
const { fileId } = await fileUpload.json();
// 3. Preflight Check
const preflight = await fetch(`/api/print/files/${fileId}/preflight`);
const { valid, warnings } = await preflight.json();
if (!valid) {
throw new Error('Druckdatei nicht valide');
}
// 4. Bestellung erstellen
const order = await fetch('/api/print/orders', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
productId: 'brochure-a4-saddle-stitch-8p',
quantity: quantity,
files: { content: fileId },
shipping: {
method: 'express',
address: await getPropertyAddress(propertyId)
}
})
});
return order.json();
}
// Response
{
"orderId": "ORD-2024-12345",
"status": "PROCESSING",
"provider": "flyeralarm",
"items": [
{
"product": "Broschüre A4, 8 Seiten, Klammerheftung",
"quantity": 50,
"unitPrice": 0.89,
"totalPrice": 44.50
}
],
"shipping": {
"method": "express",
"cost": 9.90,
"estimatedDelivery": "2025-01-02"
},
"totalPrice": 54.40,
"currency": "EUR",
"createdAt": "2024-12-30T12:00:00Z"
}
TypeScript Types
interface PrintProduct {
id: string;
name: string;
category: 'brochure' | 'flyer' | 'poster' | 'sign' | 'card' | 'folder';
provider: 'flyeralarm' | 'vistaprint' | 'gelato' | 'printful';
options: PrintProductOptions;
pricing: PrintPricing;
specs: PrintSpecs;
}
interface PrintProductOptions {
sizes: string[];
papers: { id: string; name: string; weight: number }[];
finishings: string[];
bindings?: string[];
pageOptions?: number[];
}
interface PrintOrder {
id: string;
status: 'PENDING' | 'PROCESSING' | 'PRINTING' | 'SHIPPED' | 'DELIVERED' | 'CANCELLED';
provider: string;
items: PrintOrderItem[];
shipping: PrintShipping;
totalPrice: number;
currency: string;
trackingUrl?: string;
createdAt: string;
updatedAt: string;
}
interface PrintOrderItem {
productId: string;
productName: string;
quantity: number;
options: Record<string, string>;
unitPrice: number;
totalPrice: number;
fileId: string;
}
interface PrintShipping {
method: 'standard' | 'express' | 'overnight';
address: PrintAddress;
cost: number;
estimatedDelivery: string;
trackingNumber?: string;
}
interface PrintPreflightResult {
valid: boolean;
warnings: PrintPreflightWarning[];
errors: PrintPreflightError[];
pageCount: number;
dimensions: { width: number; height: number; unit: 'mm' };
colorMode: 'CMYK' | 'RGB';
resolution: number;
}
Workflow: Exposé-Automatisierung
┌─────────────────────────────────────────────────────────────────┐
│ 1. Immobilie verkauft → Trigger │
│ ↓ │
│ 2. Exposé-Template laden │
│ ↓ │
│ 3. Property-Daten + Bilder einfügen │
│ ↓ │
│ 4. PDF generieren (CMYK, 300dpi) │
│ ↓ │
│ 5. Preflight Check │
│ ↓ │
│ 6. Bestellung bei Print-Provider │
│ ↓ │
│ 7. Tracking-Nummer an Makler senden │
│ ↓ │
│ 8. Lieferung an Property-Adresse │
└─────────────────────────────────────────────────────────────────┘
Rate Limits
| Provider |
Limit |
Window |
| FLYERALARM |
100/h |
Per Account |
| Vistaprint |
60/min |
Per API Key |
| Gelato |
100/min |
Per API Key |
| Printful |
120/min |
Per Account |
Kosten-Optimierung
// Anbieter-Auswahl basierend auf Kriterien
async function selectProvider(order: PrintOrderRequest): Promise<string> {
const quotes = await Promise.all([
getQuote('flyeralarm', order),
getQuote('vistaprint', order),
getQuote('gelato', order)
]);
// Nach Preis oder Lieferzeit sortieren
const sorted = quotes.sort((a, b) => {
if (order.priority === 'price') {
return a.totalPrice - b.totalPrice;
}
return new Date(a.deliveryDate).getTime() - new Date(b.deliveryDate).getTime();
});
return sorted[0].provider;
}
B2B-Verträge erforderlich für API-Zugang