API quickstart
From artwork to a human-approved, vendor-routed print order. Test mode simulates payments and vendors with production-identical flows — test keys can never contact a real vendor.
1 · Upload artwork
JPG, PNG, PDF, or TIFF. Files are validated by content, hashed, and stored immutably — every correction becomes a new version.
curl https://printvine-hqy9d6el1-bouncinsoul17s-projects.vercel.app/api/v1/files \ -H "Authorization: Bearer pv_test_sk_demo_5UQyoyLEV2EBmYTkBoAtvahU" \ -F file=@poster.png
2 · Run product-aware preflight
A file is only “good” for a specific product. Preflight checks trim, effective DPI, sides, bleed, and color against the variant, then produces a versioned production candidate.
curl https://printvine-hqy9d6el1-bouncinsoul17s-projects.vercel.app/api/v1/preflight_jobs \
-H "Authorization: Bearer pv_test_sk_demo_5UQyoyLEV2EBmYTkBoAtvahU" \
-H "Content-Type: application/json" \
-d '{"file_id": "file_...", "variant_id": "var_poster_18x24"}'
# -> report.outcome, report.issues[], production_file_id3 · Create a quote
Quotes price the production candidate across eligible vendors and apply your pricing policy. They expire; totals include your margin.
curl https://printvine-hqy9d6el1-bouncinsoul17s-projects.vercel.app/api/v1/quotes \
-H "Authorization: Bearer pv_test_sk_demo_5UQyoyLEV2EBmYTkBoAtvahU" \
-H "Content-Type: application/json" \
-d '{
"line_items": [{"variant_id": "var_poster_18x24", "quantity": 1,
"files": {"front": "file_prod_..."}}],
"ship_to": {"name": "Sam Example", "line1": "123 Main St",
"city": "Santa Monica", "state": "CA",
"postal_code": "90401", "country": "US"}
}'
curl https://printvine-hqy9d6el1-bouncinsoul17s-projects.vercel.app/api/v1/quotes/q_.../select_shipping \
-H "Authorization: Bearer pv_test_sk_demo_5UQyoyLEV2EBmYTkBoAtvahU" -H "Content-Type: application/json" \
-d '{"shipping_option_id": "sinalite_ground"}'4 · Create the order & pay
Orders are idempotent — send Idempotency-Key and retries can never double-charge or double-print. Payment truth comes from the payment provider's webhook, never a redirect.
curl https://printvine-hqy9d6el1-bouncinsoul17s-projects.vercel.app/api/v1/orders \
-H "Authorization: Bearer pv_test_sk_demo_5UQyoyLEV2EBmYTkBoAtvahU" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-$(uuidgen)" \
-d '{"quote_id": "q_...", "customer_email": "sam@example.com"}'
# -> checkout.url (simulated checkout in test mode)5 · Human review, then production
Every paid job crosses the operations board. A reviewer approves the exact production file — the approval is fingerprinted to file hashes, quantity, address, quote, and vendor route. Then Printvine submits idempotently, tracks vendor status, and normalizes shipping events.
# your integration listens: order.paid → order.review_pending → order.approved → vendor_submission.accepted → order.in_production → shipment.created → shipment.delivered # or polls: curl https://printvine-hqy9d6el1-bouncinsoul17s-projects.vercel.app/api/v1/orders/ord_... -H "Authorization: Bearer pv_test_sk_demo_5UQyoyLEV2EBmYTkBoAtvahU" curl https://printvine-hqy9d6el1-bouncinsoul17s-projects.vercel.app/api/v1/events -H "Authorization: Bearer pv_test_sk_demo_5UQyoyLEV2EBmYTkBoAtvahU"
Webhooks
Register an HTTPS endpoint; events are signed (HMAC-SHA256), retried with backoff, and deduplicated by event id.
curl https://printvine-hqy9d6el1-bouncinsoul17s-projects.vercel.app/api/v1/webhook_endpoints \
-H "Authorization: Bearer pv_test_sk_demo_5UQyoyLEV2EBmYTkBoAtvahU" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/webhooks/printvine", "events": ["*"]}'
# verify: printvine-signature: t=<unix>,v1=HMAC_SHA256(secret, t + "." + body)Errors
Stable envelope: type, machine-readable code, human message, offending param, and a request id for support. Common codes: PREFLIGHT_REQUIRED, QUOTE_EXPIRED, UNSUPPORTED_QUANTITY, IDEMPOTENCY_CONFLICT, APPROVAL_REVOKED, MARGIN_BELOW_FLOOR.
{
"error": {
"type": "preflight_error",
"code": "PREFLIGHT_REQUIRED",
"message": "Files must pass product-aware preflight before they can be quoted.",
"param": "line_items[0].files.front",
"request_id": "req_..."
}
}Simulator scenarios (test mode)
Trigger vendor failure paths by putting markers in ship_to.name:
SIMULATE REJECT— vendor rejects the submission (exception + operator retry path)SIMULATE TIMEOUT— vendor accepts but the response is lost (unknown outcome → reconcile finds it; no duplicate)SIMULATE LOST— request never arrives (reconcile confirms not received → clean resubmit)SIMULATE DRIFT— vendor price rises 8% before release (drift guard revokes approval, requires requote)