← all adapters

printful-style

simulates Printful API v2

restadapter v0.1.013 routes

verification

VMVM tier — no SDK suite yet· surface 13 · not implemented 5 · differs 3

use it

# add to stunt.yaml
services:
  printful:
    adapter: embedded:printful-style

# then
$ stunt up

The embedded: source extracts this adapter from the binary — no git clone, fully offline.

how to mock the Printful API locally

Install stunt, paste the service block above into stunt.yaml, run stunt up — then point your client at localhost instead of Printful API. It works offline, keeps state across requests and restarts, and every response is synthetic: the route shapes, status codes, pagination, and webhook delivery follow the real Printful API v2 surface — the data is fake, the behavior is real.

backing stores

productsorders

api surface (13)

generated from the adapter manifest — exactly what boots, nothing more · covers 9% of the real API's 55 routes (derived from spec Printful OpenAPI @ 1.0)

13 routes
GET/v2/store/products
POST/v2/store/products
GET/v2/store/products/{product_id}
POST/orders
GET/orders/{order_id}
GET/v2/store/orders
POST/v2/store/orders
POST/v2/store/orders/{order_id}
POST/v2/shipping/rates
GET/webhooks
POST/webhooks
PUT/webhooks
DELETE/webhooks

VM-verified behaviors (22)

  • a missing or non-Bearer Authorization is the 401 error envelope
  • any non-empty bearer key is accepted — the dev-key model
  • a sync product mints a sequential id; variants read back verbatim
  • unknown products get the 404 error envelope
  • an unpaged list is a bare data array with no paging object
  • limit/offset pages walk the paging envelope without repeats
  • a malformed offset cursor is the 400 error envelope
  • v1 create is result-wrapped with an integer id and draft status
  • v1 GET round-trips the result; unknown ids are 404
  • the v2 list serves one canonical order doc per order, from both create surfaces
  • the status csv filter applies before paging
  • a status update flips the canonical doc both surfaces read
  • order timestamps are sequence-derived, not wall-clock (documented mock choice)
  • STANDARD and EXPRESS quotes scale with the item count
  • an unset configuration reads as an empty result
  • POST sets and PUT replaces the single config; the secret stays masked
  • DELETE returns success, empties the read, and silences delivery
  • a config without a url is the 400 error envelope
  • deliveries are HMAC-SHA256-signed over the exact delivered bytes
  • the types filter delivers only subscribed topics
  • an empty types list subscribes to every event type
  • a v1-created order emits the v1 result shape as the event data

Not implemented (5)

  • No package_shipped, package_returned, product_synced, or order_hold events
  • No product update or delete (PUT/DELETE /v2/store/products/{product_id})
  • No order confirm or cancel (POST /orders/{id}/confirm, DELETE /orders/{id})
  • No catalog endpoints (catalog variants, print files, mockup generator)
  • No reference endpoints (countries, taxes, store info)

Differs from the real API (3)

  • Webhook set without a secret signs with built-in mock secret stunt_mock_pful_webhook_secret
  • v2 responses are bare data/resources; real Printful wraps every response in {code, result}
  • Timestamps are sequence-derived synthetic values, never wall-clock
want more of the Printful API surface? adapters are YAML + Starlark — the authoring guide covers adding routes, fixtures, and state machines. Open an issue for anything big first, or just file a PR — merged routes ship in the next release.