Skip to content

Generating Projects

API Type

PWA Backend API - Uses access keys in X-Albumstory header. See Authentication.

Generate photobook projects and launch the PWA editor webview.

Environment URLs:

  • Development: https://pwa-api-dev.photobook.ai/v2/*
  • Production: https://pwa-api.photobook.ai/v2/*

Generate Project

Creates a new photobook project and returns a URL to launch the PWA editor in a webview.

Endpoint

POST https://pwa-api{-env}.photobook.ai/v2/generate

Authentication

See Authentication - PWA Backend

Request Parameters

json
{
  "language": "en-US",
  "sku": "PB001",
  "psp": "PrinterName",
  "marketId": 0,
  "email": "user@example.com",
  "photos": [
    "https://example.com/photo1.jpg",
    "https://example.com/photo2.jpg"
  ],
  "metadata": {
    "basePrice": 29.99,
    "basePages": 24,
    "extraCostPerPage": 0.50
  },
  "callback": "https://your-app.com/api/order-callback"
}
ParameterTypeRequiredDescription
emailstringYes*User's email address (plaintext, lowercase). XOR with userId - provide either email or userId, not both
userIdstringYes*End user's identifier. Must match pattern: [-_]?(?:[A-Za-z0-9]+[-_]?)+. XOR with email - provide either email or userId, not both
languagestringNoLanguage code. Accepts both full codes (e.g., en-US, fr-FR) or 2-character codes (e.g., en, fr). Defaults to en
skustring/numberYesProduct SKU from Products API (sku or renderOptions.productId)
pspstringYesPrinter name from Products API (specifications.psp.name or renderOptions.psp)
marketIdstring/numberYesTarget market ID. Can be integer (e.g., 0) or string identifier (e.g., "printer.region")
photosarrayNoArray of publicly accessible, high-resolution photo URLs
metadataobjectNoCustom pricing and product metadata. Coordinate with PBAI team for specific fields
layoutTypestringNoLayout algorithm. Valid values: fastbook, smartbook
eCommercePluginbooleanNoSet to true if integrating with eCommerce plugin
callbackstringNoYour endpoint URL for order completion callbacks (POST method)
customobject/arrayNoCustom data structure. Coordinate with PBAI team for usage

* Required Constraint: Must provide either email OR userId (not both, not neither).

⚠️ Photo Requirements

  • URLs must be publicly accessible for downloading
  • Photos should be high-resolution (suitable for printing)
  • Ensure proper CORS headers if hosting on your own domain

User Identification

Provide either email or userId to identify the user:

  • Use email if you want the PWA to send transactional emails directly to the user
  • Use userId if you handle user identification and communications yourself

Response

json
{
  "url": "https://{frontend}.photobook.ai/editor?id=p-xyz789"
}
FieldTypeDescription
urlstringURL to launch in webview

Implementation Guide

1. Gather Required Data

Before calling this API, you need:

  • Product details: SKU, PSP name, and market ID
  • User identification: email address OR user ID
  • (Optional) User's selected photos (high-res URLs)
  • (Optional) Custom metadata for pricing or other fields

2. Prepare the Request

javascript
async function generateProject(product, photos, userEmail, marketId) {
  const requestData = {
    language: 'en', // Can also use full codes like 'en-US'
    sku: product.sku,
    psp: product.specifications.psp.name,
    marketId: marketId,
    email: userEmail, // Provide email OR userId, not both
    photos: photos,
    callback: 'https://your-app.com/api/order-callback'
  };
  
  // Optional: Add metadata for custom pricing
  if (product.customPricing) {
    requestData.metadata = {
      basePrice: product.basePrice,
      basePages: product.basePages,
      extraCostPerPage: product.extraCostPerPage
    };
  }
  
  const response = await fetch('https://pwa-api-dev.photobook.ai/v2/generate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Albumstory': JSON.stringify({
        accessKey: process.env.PWA_ACCESS_KEY,
        accessSecret: process.env.PWA_ACCESS_SECRET
      })
    },
    body: JSON.stringify(requestData)
  });
  
  const data = await response.json();
  return data.url;
}

3. Launch the Webview/iFrame

After receiving the URL:

  1. Open the URL in a webview
  2. Hide address bars for a seamless experience
  3. Implement navigation handling
  4. Listen for channel messages to track user progress

Webview Configuration

For Mobile Apps:

javascript
// React Native WebView example
<WebView
  source={{ uri: editorUrl }}
  onMessage={handleChannelMessage}
  javaScriptEnabled={true}
  domStorageEnabled={true}
/>

For Web Applications:

javascript
// iframe example
const iframe = document.createElement('iframe');
iframe.src = editorUrl;
iframe.style.width = '100%';
iframe.style.height = '100vh';
iframe.style.border = 'none';
iframe.allow = 'fullscreen; clipboard-read; clipboard-write; web-share';

// Listen for messages
window.addEventListener('message', handleChannelMessage);

document.body.appendChild(iframe);

Callback Endpoint

If you provide a callback URL, the PWA will POST to it when an order is completed.

Callback Request

The PWA will send a POST request with order details:

json
{
  "orderId": "12345",
  "email": "user@example.com",
  "status": "completed",
  "projectId": "abc123"
}

Your Callback Handler

javascript
app.post('/api/order-callback', (req, res) => {
  const { orderId, email, status, projectId } = req.body;
  
  // Handle order completion
  // - Update your database
  // - Send notifications
  // - Redirect user to confirmation page
  
  res.status(200).json({ success: true });
});

Suggested Practices

  1. Validate Photos: Ensure all photo URLs are accessible before calling the API (if providing photos)
  2. User Feedback: Show loading indicators while loading the project URL
  3. Cache Prevention: Add unique identifiers to photo URLs to prevent caching issues
  4. Product Coordination: Ensure SKU, PSP, and marketId are known to PBAI beforehand
  5. Metadata Usage: Coordinate with PBAI team before using custom metadata or custom fields

Common Issues

Photos Not Loading

  • Ensure URLs are publicly accessible
  • Check CORS headers on your CDN
  • Verify URLs return actual image data

Invalid Product Configuration

  • Double-check SKU matches exactly
  • Verify PSP name is correct
  • Ensure marketId is consistent across API calls

User Identification Errors

  • Provide either email or userId, not both
  • Ensure the identifier is consistent across API calls for the same user

photobook.ai Developer Documentation