Picsha Fulfillment API (1.0.0-draft)

Download OpenAPI specification:

Pete Traversy — Picsha, a Graphx company: petert@graphx.com License: LicenseRef-Proprietary

Submit fulfillment orders to Picsha and receive print-ready output from Picsha storefronts.

Draft v1.0 — published for partner technical review. Endpoint names, fields, and payloads are stable in intent but open to feedback before the spec is frozen.

The Picsha Fulfillment API has two integration surfaces:

  • Part A — Order Submission (partner → Picsha). Your platform submits photos and product options; Picsha performs the AI work and returns finished, print-ready output. Retouch is available at launch; AI photo books by API arrive in v1.1.
  • Part B — Fulfillment Feed (Picsha → partner). Orders placed on a retailer's Picsha storefront are pushed to your platform via signed webhooks (see the Webhooks section), with time-limited download URLs for the print-ready assets. A pull queue endpoint covers reconciliation and polling-only integrations.

Conventions

  • Every order is scoped to a store (a retailer), identified by storeId — the same slug as the retailer's storefront subdomain.
  • All processing is asynchronous: submit, then receive a webhook or poll.
  • Finished output is delivered as presigned URLs valid for 60 minutes; re-fetch the order at any time for a fresh URL. Outputs are retained 90 days, source assets 30 days.
  • Rate limits: 60 requests/minute per key for order submission, 600/minute for reads. Higher limits on request.

Idempotency

POST /orders accepts an Idempotency-Key header; retrying with the same key returns the original result rather than creating a duplicate order.

Assets

Upload customer photos before referencing them in orders.

Get a presigned upload URL for a photo

Returns a presigned URL to PUT the file bytes to directly. Accepted: JPEG, PNG, TIFF, HEIC, up to 30 MB. The asset is usable in orders once the PUT completes.

Authorizations:
bearerAuth
Request Body schema: application/json
required
storeId
required
string (StoreId) ^[a-z0-9-]{2,30}$

The retailer's Picsha store identifier (same slug as their storefront subdomain).

filename
required
string
contentType
required
string
Enum: "image/jpeg" "image/png" "image/tiff" "image/heic"

Responses

Request samples

Content type
application/json
{
  • "storeId": "theprintrefineryky",
  • "filename": "scan-001.jpg",
  • "contentType": "image/jpeg"
}

Response samples

Content type
application/json
{
  • "assetId": "ast_9f1c2ab4",
  • "uploadUrl": "http://example.com",
  • "expiresAt": "2019-08-24T14:15:22Z"
}

Ingest a photo from a URL

Picsha fetches the file from sourceUrl at submission time. The URL must be HTTPS and reachable by Picsha; expiring signed URLs are fine.

Authorizations:
bearerAuth
Request Body schema: application/json
required
storeId
required
string (StoreId) ^[a-z0-9-]{2,30}$

The retailer's Picsha store identifier (same slug as their storefront subdomain).

sourceUrl
required
string <uri>

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "assetId": "ast_9f1c2ab4"
}

Orders

Part A: submit orders to Picsha and retrieve status and output.

Submit a fulfillment order

Submits an order for Picsha fulfillment. Returns 202 Accepted immediately; processing is asynchronous. Typical retouch processing time is one to two minutes per photo.

product: book (AI-designed photo books from 20–200 photos) is v1.1 roadmap and is documented here so partners can plan for it; sandbox and production accept product: retouch at launch.

Authorizations:
bearerAuth
header Parameters
Idempotency-Key
string <= 64 characters

Retrying with the same key returns the original result.

Request Body schema: application/json
required
storeId
required
string (StoreId) ^[a-z0-9-]{2,30}$

The retailer's Picsha store identifier (same slug as their storefront subdomain).

product
required
string
Enum: "retouch" "book"

book is v1.1 roadmap.

externalRef
string <= 128 characters

Your platform's own order/line identifier; echoed on every status response and webhook.

assets
required
Array of strings (AssetId) [ 1 .. 200 ] items [ items^ast_[a-z0-9]+$ ]
object

Product options. For retouch, addons. For book (v1.1), sizeId and style.

object (Customer)

Included only where the retailer's production workflow requires it.

webhookUrl
string <uri>

Overrides your default webhook endpoint for this order.

Responses

Request samples

Content type
application/json
{
  • "storeId": "theprintrefineryky",
  • "product": "retouch",
  • "externalRef": "string",
  • "assets": [
    ],
  • "options": {
    },
  • "customer": {
    },
  • "webhookUrl": "http://example.com"
}

Response samples

Content type
application/json
{
  • "orderId": "ord_6f39eb74",
  • "status": "received"
}

Get order status and output

Returns the current state of an order. When status is ready, outputs contains presigned download URLs valid for 60 minutes; re-fetch for a fresh URL. Polling is supported, but webhooks are strongly recommended.

Authorizations:
bearerAuth
path Parameters
orderId
required
string (OrderId) ^ord_[a-z0-9]+$
Examples: ord_6f39eb74

Responses

Response samples

Content type
application/json
{
  • "orderId": "ord_6f39eb74",
  • "externalRef": "string",
  • "storeId": "theprintrefineryky",
  • "product": "retouch",
  • "status": "received",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "completedAt": "2019-08-24T14:15:22Z",
  • "failureReason": "string",
  • "outputs": [
    ]
}

Fulfillment feed

Part B: receive Picsha storefront orders into your production workflow.

Report production progress (status round-trip)

Optional in v1; strongly encouraged. Lets the partner platform report production progress on a feed order so the retailer and customer see status in one place.

Authorizations:
bearerAuth
path Parameters
orderId
required
string (OrderId) ^ord_[a-z0-9]+$
Examples: ord_6f39eb74
Request Body schema: application/json
required
status
required
string
Enum: "in_production" "shipped" "completed" "problem"
note
string

Optional free-text detail (e.g. tracking number, problem description).

Responses

Request samples

Content type
application/json
{
  • "status": "in_production",
  • "note": "string"
}

Response samples

Content type
application/json
{
  • "error": {
    }
}

List storefront orders awaiting production

Pull-based access to the fulfillment feed. Use for reconciliation, recovery after webhook downtime, or as a simple polling integration if your platform cannot receive webhooks.

Authorizations:
bearerAuth
path Parameters
storeId
required
string (StoreId) ^[a-z0-9-]{2,30}$
Examples: theprintrefineryky

The retailer's Picsha store identifier (same slug as their storefront subdomain).

query Parameters
status
string
Default: "ready"
Enum: "ready" "in_production" "shipped" "completed" "problem"

Responses

Response samples

Content type
application/json
{
  • "orders": [
    ]
}

Order has started processing Webhook

All webhook deliveries carry X-Picsha-Signature: t=<unix-ts>,v1=<hex> — an HMAC-SHA256 of "<t>.<raw body>" using your webhook secret. Reject deliveries with a bad signature or a timestamp older than 5 minutes. Deliveries are retried with exponential backoff for up to 24 hours; respond 2xx to acknowledge.

Authorizations:
bearerAuth
Request Body schema: application/json
event
required
string
Enum: "order.processing" "order.ready" "order.failed"
orderId
required
string (OrderId) ^ord_[a-z0-9]+$
externalRef
string
storeId
required
string (StoreId) ^[a-z0-9-]{2,30}$

The retailer's Picsha store identifier (same slug as their storefront subdomain).

product
required
string
Enum: "retouch" "book"
createdAt
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "event": "order.processing",
  • "orderId": "ord_6f39eb74",
  • "externalRef": "string",
  • "storeId": "theprintrefineryky",
  • "product": "retouch",
  • "createdAt": "2019-08-24T14:15:22Z"
}

Order is ready — print-ready output available Webhook

Sent when AI processing (and, for storefront orders, payment) is complete. outputs contains presigned download URLs valid for 60 minutes; fetch the order or the fulfillment queue for a fresh URL at any time.

Authorizations:
bearerAuth
Request Body schema: application/json
event
required
string
Value: "order.ready"
orderId
required
string (OrderId) ^ord_[a-z0-9]+$
storeId
required
string (StoreId) ^[a-z0-9-]{2,30}$

The retailer's Picsha store identifier (same slug as their storefront subdomain).

source
required
string
Value: "storefront"
product
required
string
Enum: "retouch" "book"
createdAt
required
string <date-time>
object (Customer)

Included only where the retailer's production workflow requires it.

required
Array of objects (Line)
required
Array of objects (Output)

Responses

Request samples

Content type
application/json
{
  • "event": "order.ready",
  • "orderId": "ord_6f39eb74",
  • "storeId": "theprintrefineryky",
  • "source": "storefront",
  • "product": "retouch",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "customer": {
    },
  • "lines": [
    ],
  • "outputs": [
    ]
}

Order failed Webhook

Authorizations:
bearerAuth
Request Body schema: application/json
event
required
string
Enum: "order.processing" "order.ready" "order.failed"
orderId
required
string (OrderId) ^ord_[a-z0-9]+$
externalRef
string
storeId
required
string (StoreId) ^[a-z0-9-]{2,30}$

The retailer's Picsha store identifier (same slug as their storefront subdomain).

product
required
string
Enum: "retouch" "book"
createdAt
string <date-time>
failureReason
required
string

Responses

Request samples

Content type
application/json
{
  • "event": "order.processing",
  • "orderId": "ord_6f39eb74",
  • "externalRef": "string",
  • "storeId": "theprintrefineryky",
  • "product": "retouch",
  • "createdAt": "2019-08-24T14:15:22Z",
  • "failureReason": "asset_unreadable"
}