PhotoPrintAgent
Browse photo products, preview artwork, estimate prices and track orders. Full commerce and narrow OAuth endpoints for photo prints delivered in the USA.
Hosted MCP Server
npx add-mcp 'https://photoprintagent.com/mcp'Installs into Claude Code, Codex, Cursor and more
Documentation
Customer confidentiality
Use only PhotoPrintAgent branding in customer updates. Internal operational details are confidential; do not infer or disclose them from previous conversation context. Use only the customer-safe status fields. An accepted order is processing; it is not shipped until shipment is confirmed. Use the returned public product IDs without interpreting them.
PhotoPrintAgent MCP: complete a print and ship checkout
An agent can complete a print without a browser if it can: connect to
/mcp, authenticate (guest x402 or agent key), upload a print-ready image, quote, create order, settle payment, and poll status — all via MCP tools documented below.
Start with guest + Base USDC. No account or pre-minted API key is required. MCP coordinates checkout; image bytes travel in a separate authenticated HTTP upload. A signing wallet with approved spending authority is required for x402. Card checkout returns a private URL for the human buyer and requires their browser. Do not collect card numbers, wallet keys, passwords, or guest/account tokens in chat.
This document and the public JSON schemas are generated from the same definitions used to register and validate live MCP tools. tools/list is available without authentication and includes full input and output schemas. JSON contract and upload response schema. Discovery. Markdown. The older /agent-guide.md is a generated copy. Read current availability from list_products and list_payment_assets; examples are illustrative, not live prices or payment authorizations.
Required acceptance of order terms
Every create_print_order request must include termsAccepted: true. Present the order terms and obtain the buyer's acceptance or explicit authorization to accept on their behalf before sending this field. Do not infer acceptance from a previous order, an upload, or a quote. get_checkout_options and the JSON contract expose the current terms URL, version, and acceptance field.
The three acknowledgments have distinct purposes: consent: true on quote_prints permits PhotoPrintAgent to process the photos and address for printing and delivery; buyerApproved: true on create_print_order confirms approval of this order and price; termsAccepted: true confirms acceptance of the order terms. Send both order acknowledgments for card, crypto, and complimentary orders, including idempotent retries. Missing, false, null, and string values such as "true" are rejected before an order, payment checkout, or fulfillment submission is created.
REST clients must also include termsAccepted: true in POST /api/orders. The website sends the value of its existing terms checkbox. Each newly created order stores the authenticated account or guest owner, the acceptance timestamp, and the server's terms URL/version. A retry preserves the original acceptance record. Existing orders can still be read and paid without recreating them; prior acceptance is not fabricated for historical orders.
Example create_print_order arguments (replace example IDs; obtain approval first):
{
"quoteId": "33333333-3333-4333-8333-333333333333",
"idempotencyKey": "44444444-4444-4444-8444-444444444444",
"buyerApproved": true,
"termsAccepted": true,
"method": "card"
}
Image formats and conversion
Upload JPEG (.jpg, .jpeg, .jpe, .jfif), PNG/APNG, WebP, GIF, HEIC/HEIF (.heic, .heif, .hif), TIFF (.tif, .tiff), AVIF, BMP, or self-contained SVG/SVGZ. create_upload and list_products.product.specs return the authoritative MIME types, extensions, byte/pixel limits, and imageHandling policies. Use the matching image Content-Type or application/octet-stream if unknown. Upload raw file bytes; do not rename unsupported files to a supported extension.
One uploaded file produces one still print image. GIF and animated WebP use the first frame; APNG uses its default still image. TIFF uses the first page. HEIC/HEIF uses the primary image, falling back to the first. AVIF uses the first image. To choose another page/frame, extract and upload it separately. Live Photo video and audio are not printed. Transparency is composited on white; orientation is normalized; metadata is stripped; print output is an 8-bit sRGB JPEG. HDR/wide-gamut appearance can change during conversion. Obtain buyer approval of the resulting still image and crop.
Limits remain 15 MiB (15,728,640 bytes) per image. JPEG, PNG and TIFF permit up to 150 million input pixels; other formats permit 24 million, with a 24,000-pixel maximum edge. Read imageHandling for the current format-specific rules. Every image must decode successfully within processing limits. SVG must be self-contained; scripts, stylesheets, embedded images, and external resources are rejected. Unsupported compression variants, PDF, camera RAW, PSD, JPEG XL and JPEG 2000 need export to JPEG/PNG or another supported format before upload. A corrupt file can still fail despite a recognized extension. Upload responses optionally include sourceFormat and sourceImages; these are informational, not an instruction to create more orders. See Photo & ordering help.
The storefront uses /api/photo-preview to show converted stills without saving them. Agents should continue to use the authenticated /api/photos endpoint returned by create_upload; a preview does not return a printable photo ID.
Product selection
Call list_products before quoting. Its products array contains active, configured products; pass the chosen id as productId to quote_prints. Omitting productId selects the original photo-4x6 product for compatibility. Each item may specify its own productId. Compatible products can be combined in one order; incompatible combinations are rejected. The legacy product.specs describes the currently supported 4×6 image pipeline. Use products[] for every currently orderable size and design; unready products cannot accept orders. Prices always come from a current PhotoPrintAgent quote. Use the returned product IDs as opaque identifiers. Re-quote if the store reports that the product configuration changed.
Connection: copy and paste
Canonical endpoint: https://photoprintagent.com/mcp. https://photoprintagent.com/api/mcp is an equivalent alias, with the same authentication and content negotiation. Transport: stateless Streamable HTTP, JSON-RPC 2.0 over POST. GET returns 405 with Allow: POST; this server does not maintain an SSE session or require Mcp-Session-Id.
Every MCP POST needs:
Content-Type: application/json
Accept: application/json, text/event-stream
Both Accept media types are required, even though this server responds with JSON. Missing either returns HTTP 406. For protected tools, send Authorization: Bearer <credential> or the guestToken tool argument. Public discovery and session creation need no Authorization header; omit it entirely rather than sending an empty or fake key. Invalid Bearer credentials return HTTP 401 even for public tools. Never send both Bearer and guestToken.
Cursor-style remote HTTP configuration, also usable by clients accepting this mcpServers format:
{"mcpServers":{"photoprintagent":{"url":"https://photoprintagent.com/mcp","headers":{"Content-Type":"application/json","Accept":"application/json, text/event-stream"}}}}
Claude Code remote HTTP configuration:
{"mcpServers":{"photoprintagent":{"type":"http","url":"https://photoprintagent.com/mcp","headers":{"Content-Type":"application/json","Accept":"application/json, text/event-stream"}}}}
These configurations support guest checkout by passing the returned guestToken to protected tools. For an existing credential, configure the additional Authorization header using your client's secret/environment facility. Claude Code uses "Authorization":"Bearer ${PHOTOPRINTAGENT_API_KEY}"; Cursor uses "Authorization":"Bearer ${env:PHOTOPRINTAGENT_API_KEY}". Verify expansion resolves locally and is never sent literally. Do not commit a real key to a config file or paste one in chat. Some Claude products require a remote-connector UI rather than this JSON; the endpoint and headers are unchanged.
Initialize using the supported protocol revision shown below, then send notifications/initialized (HTTP 202, empty response). SDK clients do this automatically:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"print-agent","version":"1.0.0"}}}
The response includes result.protocolVersion, result.capabilities.tools, and result.serverInfo. Send the negotiated version in MCP-Protocol-Version on later requests. Stateless tools/call examples below are individually executable; no session ID is needed.
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
Authentication agents can use
Primary: guest + x402 (or card handoff)
Call start_guest_checkout without Authorization. Its success response returns token and the identical guestApiKey alias, prefixed ppg_. The secret is disclosed only when the session is minted, before upload; it is not minted again by create_print_order or get_order. Save it immediately in your secret store, alongside order references. It authorizes uploads, quotes, payment, and get_order for that guest only. No Firebase account or login is created. Use the same credential throughout the order.
New guest checkouts may be created for 24 hours (checkoutUntil); order reads remain available for 30 days (expiresAt). Both are Unix milliseconds. Separate guests cannot read one another's photos/orders. Guest tokens cannot access admin settings or account-key management. Guest checkout allows 15 new orders per session per UTC day. Checkout requests, quotes, payment attempts, and photo uploads have no additional request-count limits. Signed-in new accounts allow 15 new orders per UTC day; admin-assigned standard accounts allow 100; store admins have no daily order cap. Browser and agent access share the account’s order count. Daily-cap responses explain the reset time and direct buyers to support@photoprintagent.com for an increased allowance. Do not evade daily caps with new sessions.
The equivalent public mint API is POST /api/guest-sessions, JSON body {}, without Authorization. A lost token cannot be recovered through public APIs; contact support with the order reference after payment. Do not start a new guest session to retry an uncertain payment.
Account: machine-readable mint after Firebase login
At For agents, account holders can use Your agent keys. Programmatically, obtain an authorized Firebase ID token using Google OAuth/Firebase sign-in or verified email/password login, then call create_agent_key with that ID token in the Bearer header, or:
POST /api/agent-keys
Authorization: Bearer <FIREBASE_ID_TOKEN>
Content-Type: application/json
{}
Response (201): {"key":"ppa_<64 hex characters>","id":"<key record id>","expiresAt":<Unix milliseconds>}. The key is disclosed once, expires after 90 days, and grants the owner's photo and order operations (including quoting and payment). Scopes are fixed, not configurable. Keys cannot mint/revoke other keys or access admin settings. At most 10 active account keys; mint budget 5/day. List metadata with GET /api/agent-keys; revoke with a Firebase ID token using DELETE /api/agent-keys/<id>, returning {"ok":true}. Revocation is immediate for subsequent requests. Store credentials in an environment/secret store, never chat.
For an existing verified email/password account, fetch the public web apiKey from /firebase-config.json, then call Firebase directly using credentials supplied through a secure login flow:
POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<PUBLIC_FIREBASE_WEB_API_KEY>
Content-Type: application/json
{"email":"<ACCOUNT_EMAIL>","password":"<ACCOUNT_PASSWORD>","returnSecureToken":true}
Use the returned idToken in the mint request. Passwords go only to Firebase, never MCP; unverified email accounts receive 403 from this service. Google accounts use Google/Firebase OAuth, not a Google password. Standard MCP OAuth is available through the discovery metadata at /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server. Use authorization code + PKCE S256 with resource https://photoprintagent.com/mcp and the minimum required scopes (mcp:read, mcp:write, mcp:orders, mcp:payments). The legacy mcp scope remains supported for existing full-commerce integrations. The account holder reviews the application and explicitly allows or cancels the connection on site. Guest checkout remains available without an account. There is no device-code grant. get_checkout_options and /api/auth-options expose these paths as JSON.
Canonical happy path
The reference below includes complete JSON-RPC requests, success responses, and common tool errors for every tool. Replace all example IDs with actual returned values. Examples assume the guest token is held in the Authorization header; for clients with fixed headers, add guestToken to each protected tool's arguments. The binary upload always needs Bearer authentication.
- Discover product and create guest access. Call
list_products, thenstart_guest_checkoutand save the credential. RequireorderingAvailable: trueandx402Available: truebefore planning a crypto checkout. Read the selectedproducts[].artworkspecification; the legacyproduct.specsdescribes only the original 4x6 product. Final price isquote_required, because shipping, quantity, and tax affect the total. There is no advertised fixed per-print price. - Prepare and upload. Use the selected product’s artwork pixel dimensions and slot labels. For the original landscape 4×6 print the recommendation is 1800×1200 pixels (portrait 1200×1800), ideally sRGB. Recommended 300 DPI and artwork minimumDpi are quality guidance, not rejection thresholds; smaller valid images receive a reduced-quality warning. Call
create_uploadwith the desired crop. POST raw image bytes to the returneduploadUrlusing the returnedX-Photo-Optionsand a matching image Content-Type. Save the responseidasphotoId. This endpoint is an authenticated upload, not a presigned PUT; no storage is allocated by the helper. There is no base64-in-MCP or arbitrary remote-image-URL input. - Quote the approved photos/address. Call
quote_printswith uploaded photo IDs, quantities, shipping, andconsent: trueafter permission for PhotoPrintAgent to process images/address for printing and delivery. For an office address described asname, line1, line2?, city, state, postal, country, map the recipient's confirmed first/last names tofirstName/lastName, andpostaltozip. Includeemailandphoneinshipping. The API does not accept literalname/postalaliases; do not guess a person's name split or missing contact details. The returnedpricecontains subtotal, tax, shipping and total in integer USD cents;lineItemsidentifies photos/product/quantities. The provider supplies aggregate pricing, so per-line prices are not fabricated.expiresAtandvalidUntilare identical, 15 minutes from quote creation. Create the order before that quote expires. New orders then have a separate 24-hour payment window from order creation; use the returnedpaymentDeadline. Existing orders retain their saved deadline until explicitly renewed. On an expired private checkout page, click Continue to payment to check existing payment status and reopen checkout for 24 hours. The same private link and order reference are retained; renewal itself never charges the customer. An eligible unpaid crypto checkout renewed through coupon editing receives a new 24-hour window after price and payment-state checks. - Obtain human approval and terms acceptance. Show the photos/crops, quantities, delivery address, complete USD total including shipping and tax, and the order terms. Obtain explicit approval and terms acceptance before creating every order;
buyerApproved: trueandtermsAccepted: truerecord these separate requirements. Also obtain approval for the exact crypto amount if choosing a non-default token. A demo price in these docs is never approval. - Create once. Call
create_print_orderwith the quote ID,buyerApproved: true,termsAccepted: true, and a newly generated stable UUID asidempotencyKey. Keep these fields for retries of the same intent. Buyer contact and shipping are inherited from the quote. Default method isx402; no money moves at creation. It returns an unpaid order andpaymentUrl; it does not return HTTP 402 itself. One quote can create only one order. Do not create another order to recover an ambiguous payment. - Pay the existing order. Call
pay_print_orderwith justorderIdfor default Base USDC. The MCP response is HTTP 200 withstructuredContent.status: "payment_required",httpStatus: 402,payment_required, andpaymentRequiredHeader; it also includes the PAYMENT-REQUIRED HTTP header. Sign those exact v2 terms with the approved wallet, then retry the same tool/order withpaymentSignature(base64 JSON). Alternatively POST topaymentUrl: this REST path returns actual HTTP 402, then acceptsPAYMENT-SIGNATURE. Both paths execute the same verification, settlement, and fulfillment code. See the signing recipe below. - Poll the same order. Call
get_orderafter payment, on timeouts, and for subsequent status. Poll every 15–30 seconds initially and back off to minutes after order acceptance.paymentStatus: paidconfirms captured payment;fulfillmentStatus: accepted/status: processingmeans the order was accepted for processing. Tracking may be empty. Readprogress.productionStatusandprogress.shipmentStatusfor confirmed production and shipment updates; the original payment/order status fields remain backward compatible. Unknown information stays explicit. Do not infer shipment from acceptance or the presence of a tracking label.
Binary upload example, using the token already saved securely in the environment (do not run shell tracing):
curl --fail-with-body 'https://photoprintagent.com/api/photos' \
-H "Authorization: Bearer $PHOTOPRINTAGENT_API_KEY" \
-H 'Content-Type: image/jpeg' \
-H 'X-Photo-Options: {"fit":"cover","orientation":"landscape","x":50,"y":50}' \
--data-binary @print-ready.jpg
Success: HTTP 201, {"id":"22222222-2222-4222-8222-222222222222","width":1800,"height":1200,"quality":"high","expiresAt":1896048000000}. These IDs/timestamps are examples. JPEG, PNG/APNG, WebP, GIF, HEIC/HEIF, TIFF, AVIF, BMP and self-contained SVG accepted (see image handling rules above); maximum 15 MiB (15,728,640 bytes) and up to 150 million input pixels for JPEG, PNG and TIFF (24 million for other formats), with a 24,000-pixel maximum edge. Output is sRGB JPEG, metadata stripped after EXIF orientation, resized to the print dimensions. cover crops around x/y percentages (default 50/50); contain adds white borders. Non-3:2 inputs are processed according to that choice, not automatically rejected. Low-resolution valid photos are accepted with ordinary interpolation and a nonblocking reduced-quality warning; no AI enhancement is applied. Files expire after 30 days; active paid fulfillment reserves image access. An expired/unavailable photo blocks payment.
Upload errors are ordinary HTTP JSON: 401 missing/expired Bearer; 400 invalid or undecodable image/crop, or a format-specific pixel/edge limit exceeded; 413 body over 15 MiB. Never put the bytes into tools/call (MCP JSON limit 96 KiB).
x402 payment: exact signing and retry
The server uses x402 v2, exact. Do not send v1 X-PAYMENT, maxAmountRequired, or network base; v2 uses PAYMENT-SIGNATURE, amount, and CAIP-2 network identifiers. An unsigned REST payment POST returns the same challenge JSON in its body and the PAYMENT-REQUIRED header encoded as base64(UTF8(JSON)). The MCP equivalent exposes the same decoded object as payment_required. For signatures, paymentSignature is that same encoded header string, not the decoded object. For a given call, use the tool argument or the HTTP header, never both.
Default terms are Base mainnet eip155:8453, Circle USDC contract 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, six decimals. A $5.50 approved total means amount: "5500000". Read payTo from the live challenge and verify it against list_products.x402PayTo (or the selected token quote); never send funds to documentation example addresses. Default timeout is 300 seconds, additionally bounded by the order's payment deadline (24 hours from creation for new checkouts). USDC uses EIP-3009 with EIP-712 domain name USD Coin, version 2, chainId 8453, verifyingContract the USDC contract. Let the x402 SDK construct/sign the typed authorization; do not manually transfer USDC and expect an order to become paid.
The decoded signed v2 envelope has this shape (all example placeholders must be replaced by SDK output):
{"x402Version":2,"resource":{"url":"https://photoprintagent.com/api/orders/<ORDER_ID>/pay","description":"4×6 photo print order <ORDER_ID>","mimeType":"application/json"},"accepted":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"5500000","payTo":"<LIVE_MERCHANT_ADDRESS>","maxTimeoutSeconds":300,"extra":{"name":"USD Coin","version":"2"}},"payload":{"signature":"<EIP712_SIGNATURE>","authorization":{"from":"<BUYER_WALLET>","to":"<LIVE_MERCHANT_ADDRESS>","value":"5500000","validAfter":"<UNIX_SECONDS>","validBefore":"<UNIX_SECONDS>","nonce":"<RANDOM_32_BYTE_HEX>"}}}
Use the exact returned resource and accepted terms. Monetary API prices are cents, token amounts are atomic-unit strings, API expiry times are milliseconds, and EIP-3009 validity times are seconds. The server verifies authorization and settles through its facilitator; the agent does not need merchant facilitator credentials or call /settle itself. One claimed authorization cannot fund multiple orders. Successful settlement returns PAYMENT-RESPONSE (base64 JSON with success, transaction, network, possibly payer), and MCP also returns paymentResponse and paymentResponseHeader. Read the order even after success: payment may succeed while print submission needs review. A repeat payment call after processing returns the order, without a fresh settlement header and without another charge.
JavaScript signing recipe (MCP)
The installed server/client integration uses x402 2.25.x. Use @x402/core/client and @x402/evm/exact/client from a compatible x402 v2 release. The following runs only after buyer approval, with an authorized signer implementing address and signTypedData (for example viem or a managed wallet signer). Obtain the signer through your wallet/secret provider; never ask for its private key in chat. callTool is your authenticated MCP client's tool-call function, order is create_print_order's returned order, and products is list_products's response.
import { x402Client } from '@x402/core/client';
import { ExactEvmScheme } from '@x402/evm/exact/client';
const challengeResult = await callTool('pay_print_order', { orderId: order.id });
if (challengeResult.isError) throw new Error('Read get_order before retrying');
const challenge = challengeResult.structuredContent;
if (challenge.status !== 'payment_required') throw new Error('Read returned order status');
const required = challenge.payment_required;
const client = new x402Client()
.register('eip155:8453', new ExactEvmScheme(authorizedSigner))
.setSpendControls({ maxAmountPerPayment: '$' + (order.price.total / 100).toFixed(2) });
// The SDK default spend ceiling can be below a print order; set an exact approved cap.
client.onBeforePaymentCreation(async ({ selectedRequirements: r }) => {
if (r.scheme !== 'exact' || r.network !== 'eip155:8453' ||
r.asset.toLowerCase() !== '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913' ||
r.payTo.toLowerCase() !== products.x402PayTo.toLowerCase() ||
r.amount !== (BigInt(order.price.total) * 10000n).toString() ||
r.extra?.name !== 'USD Coin' || r.extra?.version !== '2') {
throw new Error('Challenge does not match approved checkout');
}
});
const payload = await client.createPaymentPayload(required);
const paymentSignature = Buffer.from(JSON.stringify(payload), 'utf8').toString('base64');
// Do not log the authorization. Send once; on timeout read get_order, not a new payment.
const settled = await callTool('pay_print_order', { orderId: order.id, paymentSignature });
const latest = await callTool('get_order', { orderId: order.id });
REST equivalent and other tokens/networks
Unsigned: POST /api/orders/<id>/pay, Bearer and JSON {} → HTTP 402, PAYMENT-REQUIRED plus challenge body. Signed retry: same URL/Bearer/body plus PAYMENT-SIGNATURE: <base64 payload> → HTTP 200 and PAYMENT-RESPONSE on new settlement. MCP pay_print_order always keeps the JSON-RPC response at HTTP 200 for tool results, including the structured challenge. Transport/auth failures still use their HTTP error status.
Call list_payment_assets to choose another asset, then quote_crypto_payment with orderId and a returned tokenId. It locks the server-calculated atomic amount for 60 seconds, never past the order's payment deadline. Include cryptoQuoteId in both unsigned and signed pay_print_order arguments (or both REST JSON bodies). Validate asset, amount, network and recipient against this quote before signing. Never reprice while signing. Refresh an expired token quote only when the same order is confirmed unpaid; obtain fresh approval of the new amount.
Solana challenges retain the original facilitator fee payer, blockhash, and payment terms for that token quote. Request the unsigned challenge before signing, then echo its complete accepted object unchanged. Do not reconstruct the terms or substitute a fee payer from another challenge. A new token quote needs a new challenge and signature. If payment is ambiguous, read the existing order before switching networks or attempting another payment.
Base ERC-20 tokens use EIP-3009 (USDC) or Permit2. There is no top-100 / market-cap restriction. The server catalog includes CoinGecko-listed Base tokens and Solana mints, with stable IDs for existing tokens. Newly discovered IDs use base:<contract> or solana:<mint>; always use the returned id as tokenId. Catalog entries are candidates: an authoritative crypto quote requires a verified on-chain contract/mint, matching decimals, a fresh positive token-address USD price, and a compatible receiving account. Catalog presence does not guarantee settlement; restricted tokens can be rejected by the facilitator. Native ETH, BTC and SOL require their supported wrapped token representation. No automatic wrapping, bridging or conversion to USDC occurs; the merchant keeps the selected token.
The catalog refreshes daily at 3:00 AM America/New_York. catalogUpdatedAt, catalogSource (bundled or refreshed) and catalogStale identify its freshness; a feed or storage failure retains the last good snapshot. New entries become discovery candidates, not automatic payment approvals. Each listed asset reports priceChecked: false and availability: quote_required for Base or receiving_ready for verified Solana receiving accounts. Both require quote_crypto_payment before payment.
list_payment_assets accepts optional search (name, symbol, or exact address), network, offset and limit (default 50, maximum 100). Continue with the returned nextOffset until null. REST uses the same fields as query parameters on /api/payment-assets. priceStatus: available means discovery is available; fresh price availability is checked by quote_crypto_payment, not by listing. A stale or missing price rejects the quote with 503. solanaPayTo advertises the configured merchant wallet; each Solana asset appears only after its receiving account is checked.
{"jsonrpc":"2.0","id":21,"method":"tools/call","params":{"name":"list_payment_assets","arguments":{"network":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","search":"USDC","limit":50}}}
For Base Permit2, a separate bounded token approval and Base ETH for gas may be required. Cap approval at the approved amount, never unlimited. Fresh USD pricing is rounded up to atomic units; the amount is locked for 60 seconds. Newly cataloged Base token settlement also checks the transaction's net token Transfer events into the merchant wallet. A transfer-tax shortfall or unverifiable receipt goes to needs_review, preserving the transaction ID and preventing another charge or automatic fulfillment.
Solana mainnet is solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp. Both standard SPL Token and compatible Token-2022 mints are supported. Existing IDs include solana-usdc (mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v, six decimals) and solana-wsol (mint So11111111111111111111111111111111111111112, nine decimals). Other mints are discovered from the catalog. Tokens with transfer fees, transfer hooks, confidential transfers or other extensions that alter exact transfer behavior are unavailable. Metadata-only extensions are allowed.
Use only Solana assets returned by list_payment_assets; solanaAvailable alone does not prove their receiving accounts exist. Use the x402 v2 Solana exact client and transaction signer, preserve the returned feePayer/terms, and compare case-sensitive mint/recipient with the quote. Its payload is a signed SPL or Token-2022 transaction. WSOL must already be wrapped. The merchant initializes receiving accounts in Admin → Payments → Solana receiving accounts, selecting up to six tokens per wallet-approved setup. Existing compatible associated accounts are discovered automatically; setup never imports a wallet key or signs on the server. Base receipts use https://basescan.org/tx/<transaction>; Solana signatures use https://solscan.io/tx/<transaction>.
x402Available: false means merchant setup/live billing is incomplete or disabled. Expect 503 rather than a usable payment challenge. There is no separate x402 order minimum; the print quote must have a positive total and may not exceed $1,000 USD. Product quantity/shipping pricing determines the actual minimum payable order (one print minimum).
Card path exposed by MCP
Apple Pay and Google Pay use method: "card" and the same private buyer checkout URL. New card and wallet orders use a Square payment modal within PhotoPrintAgent. They are browser wallet options, not additional MCP payment methods or crypto tokens. Buttons appear only when supported by the buyer's device and the payment provider's domain/account configuration. A wallet still requires the human buyer's approval; do not collect wallet credentials or try to authorize it through MCP.
Call create_print_order with method: "card", buyerApproved: true, and termsAccepted: true; give the human the returned private checkoutUrl, retaining its #access=ppc_… fragment. This is the specific order's checkout, not a generic instruction to browse the site. The buyer can open it without an account, review the total/address, and pay in the embedded Square modal. The server verifies the stored Square order, location, exact USD total, completed payment, and lack of refunds before submitting fulfillment through the order’s configured print service. Agents can subsequently call get_order; REST POST /api/orders/<id>/confirm with their credential also verifies that exact stored payment. Historical Stripe orders retain their original verification path. A client assertion that payment succeeded is never sufficient. Never collect card numbers through MCP. Card completion is a human browser handoff, not autonomous headless card charging.
Address, fulfillment and recovery
US destinations only (country: "US"). Required: firstName, lastName, email, phone, line1, city, uppercase two-letter state, and zip (five digits or ZIP+4); line2 defaults to empty. Names/address lines/city max 150 characters, email max 254. Phone punctuation is removed, optional leading US 1 removed, then exactly 10 digits required. The schema checks syntax; quote validation checks delivery serviceability. Two letters alone are not a guarantee a state/destination is deliverable. PO boxes are not categorically rejected locally, but delivery depends on the selected delivery option accepting that address; do not promise PO box eligibility without a successful quote. There is no guaranteed production or transit SLA exposed by this API. No estimated arrival date is returned.
| status | paymentStatus / fulfillmentStatus | Meaning / action |
|---|---|---|
| creating_checkout | unpaid / not_submitted | Card checkout is being prepared. Poll existing order. |
| awaiting_payment | unpaid / not_submitted | Unpaid; payment allowed only before its deadline. |
| verifying_payment | pending / not_submitted | Authorization validation in progress. Poll; do not sign again. |
| settling_payment | pending / not_submitted | Settlement in progress or unresolved. Poll; do not pay again. |
| paid | paid / not_submitted | Payment captured; print submission pending. |
| submitting | paid / submitting | Confirming the order; never recreate the order. |
| processing | paid / accepted | Order accepted for processing. This is not shipment confirmation. |
| needs_review | paid or needs_review / needs_review | paidAt confirms known payment; absent paidAt can mean unknown outcome, not safe-to-repay. Support investigates payment and order state. |
| expired | expired / not_submitted | Unpaid checkout deadline passed. Check the stored order before considering a new approved quote. |
paidAt, transaction, and network are nullable. trackingUrls is an array of HTTPS tracking links and may stay empty; no fabricated carrier, tracking number, ETA, shippedAt, or delivery state is returned. Current automatic reconciliation retries known paid fulfillment safely and flags ambiguous outcomes; production updates are synchronized where supported, while carrier delivery information may remain unknown. For unresolved paid orders contact support@photoprintagent.com with the order reference. Do not send credentials or signatures to support.
Errors agents encounter
MCP tool execution failures return HTTP 200, result.isError: true, and structuredContent.error: {httpStatus, message} plus the same JSON as text. Schema validation failures are also isError but may have text only (SDK validation occurs before the handler); check isError before interpreting success content. A payment challenge is a normal tool result, not isError. Top-level transport/auth failures are HTTP errors; JSON-RPC protocol errors use the standard error envelope. Never assume HTTP 200 means a paid or successful order.
| Failure | Where / response | Safe action |
|---|---|---|
| Missing/invalid Bearer | REST 401; invalid MCP header 401; protected MCP tool without credential has isError, error.httpStatus 401 | Start guest checkout without Authorization, then reuse its token. Refresh authorized account login for expired account credentials. |
| Incomplete Accept | MCP HTTP 406 | Send both application/json, text/event-stream, including on initialize/tools/list. |
| Wrong Content-Type | MCP HTTP 415, or JSON parsing 400 | Send application/json; upload uses a supported image MIME type or application/octet-stream instead. |
| SPA HTML on discovery/docs | Wrong deployment/proxy routing | /.well-known/mcp.json and /docs/mcp.json must parse as JSON; /docs/mcp and .md must be Markdown. Do not parse index.html or fabricate discovery. These paths are explicitly routed before SPA fallback. |
| Bad address, missing consent/contact, quantity | quote_prints isError (400 or SDK input error); REST 400 | Correct required fields; unique photo IDs, 1–99 each, 50 items, 200 distinct source photos, at most 500 complete products. Never guess contact/address details. |
| Low resolution / different aspect | Valid small images are accepted with reduced quality; aspect is cropped/padded according to chosen fit | Prefer a larger original and explicitly choose crop or white borders. |
| Photo missing/foreign/expired | 404 or 410 | Upload under the same credential; never pay for unavailable photos. |
| Quote expired/settings or price changed | create_print_order 409; payment deadline 410; changed terms 409 | Read existing order first. Requote only an unpaid unambiguous purchase; request approval again. |
| Token quote expired | pay_print_order/REST 409 or 410 | If unpaid, refresh the token quote and approve the new amount; never reuse its old signed terms. |
| Insufficient USDC / rejected authorization | Wallet signing may reject before transmission; server verify rejection 402 | Check wallet balance on the quoted network/asset. Read get_order first; only if definitively awaiting_payment may a corrected fresh authorization be attempted. A claimed rejected nonce cannot be reused. |
| Duplicate authorization | 409 | Poll the original order; do not try the same authorization on a new order. |
| Settlement failed/timed out | 409 or generic 500; order may be needs_review | Treat outcome as ambiguous. Poll/get support; do not recharge, resettle blindly, or submit another order. |
| Service unavailable | 503 | Check availability and retry discovery later. No fake payment success. |
| Rate limit | 429 (REST Retry-After gives seconds to wait; REST and MCP budget errors include rateLimit.resetAt in Unix milliseconds) | Wait until the indicated reset. Daily order caps include unpaid and expired orders; retrying an existing order with its original idempotency key does not consume another order slot. |
Protocol references
- MCP Streamable HTTP transport
- x402 v2 facilitator settlement
- x402 troubleshooting
- Claude Code MCP configuration
- Cursor MCP configuration
- Firebase REST authentication
The live service contract below takes precedence over general protocol examples. API prices, availability and delivery promises must come from actual responses.
Coupons and complimentary orders
Pass optional couponCode to quote_prints with the ordinary photo/address/consent payload. Codes ignore case, spaces, and hyphens. The returned price includes the original print/shipping/tax components, originalTotal, discount, and coupon breakdown. All amounts are integer USD cents; price.total is the only buyer amount to approve and pay. Only one coupon applies per order. Taxes remain the quoted amount; optional tax credit is a merchant subsidy, not a tax recalculation.
For example, add "couponCode":"WELCOME10" to the documented quote request (example code only; it is not preactivated). A 10% print discount on a 100-cent subtotal with 400-cent shipping and 50-cent tax returns originalTotal:550, discount:10, total:540. Approve 540 cents and call create_print_order with that quote ID. You may repeat couponCode in create_print_order as an assertion; a different code returns 409 and requires a fresh quote and approval. Neither order creation nor payment can silently change an approved discount.
Positive totals: all new card orders, including discounted orders, use Square and return a private checkoutUrl where the buyer pays in an embedded Square modal without leaving PhotoPrintAgent. If payment processing or order processing are unavailable, card creation returns 503 without falling back to Stripe. Poll get_order after the buyer pays. Base and Solana x402 quotes/challenges use the same discounted amount. Follow the normal signature retry recipe, preserving the order ID and crypto quote ID.
Zero totals: create_print_order still requires buyerApproved:true and termsAccepted:true. It reserves the coupon, verifies photos and current pricing, records paymentStatus not_required, and submits fulfillment once. Do not request a card payment, crypto quote, or payment signature for a zero-total order. Reuse the same idempotency key on timeout, then call get_order. processing means the order was accepted for printing; it does not mean shipped.
Coupons may have start/end dates, minimum print subtotal, usage/per-email limits and promotion budgets. 400 means invalid, inactive, not started, expired or ineligible; 409 means capacity exhausted, changed coupon/quote, or coupon mismatch. Remove the code or get a fresh eligible quote and seek buyer approval of the new total. Quotes do not reserve usage; order creation atomically does. Ambiguous payments retain capacity until resolved. Admin coupon endpoints require a verified allowlisted admin and are not exposed as public MCP tools.
Optional campaignId on quote_prints attributes an order to an active campaign. It never changes the price by itself; include the campaign's couponCode explicitly.
Product shipping prices
list_products includes each product’s optional shipping policy. mode is flat (one shipping charge per order) or per_item (shipping amount multiplied by total print quantity). When no policy is returned, shipping is calculated during the quote. All amounts are integer USD cents. For flat shipping, multipleItemAmountCents can override amountCents when the total quantity is 2 or more. It remains a single flat charge for 20, 30, or any other allowed multi-item quantity. If omitted or null, the same flat amount applies to every quantity.
Always use quote_prints.price.shipping and price.total; do not supply or calculate your own shipping override. Coupons apply to the customer’s configured shipping price. The quote remains the authoritative buyer total, including tax. Product shipping edits require a new quote for unpaid checkout. Compatible products may share an order using per-item productId; incompatible combinations are rejected.
Product artwork and multiple images
Use list_products for the complete active catalog and each product’s artwork requirements. The legacy top-level product.specs describes only the original 4×6 product. The orderable products array excludes Admin Only and unready products. Use availableOnly:false to include public unavailable products in products; the legacy catalogProducts array is empty. Follow nextOffset until null to read every page. Do not promise checkout for unavailable products. Verified admin Firebase sessions can use list_admin_products to discover ready private products. Guest and account agent keys have no admin privileges.
Call create_upload with the chosen productId for each image, then POST binary bytes using both returned X-Product-Id and X-Photo-Options headers. A two-sided product exposes Front and Back slots. Upload and preview both, then quote one item with photoIds: [frontPhotoId, backPhotoId] and quantity: 1. For multiple copies, increase the item quantity; do not quote each side as a separate product. Preserve the returned slot order. All images must belong to the caller, be unexpired, and match the product artwork dimensions. A product or artwork change requires new uploads.
Single-image products continue to accept photoId. photoIds and photoId are mutually exclusive. The server validates each design against the product’s image count, limits the order to 200 images and 500 product units, and reserves every image through card/x402 payment and fulfillment. Shipping quantities and coupon totals count complete products. Products with product-specific page composition or templates remain unavailable until that layout is configured; neither MCP nor a payment method bypasses readiness checks.
Photo, checkout, and account lifecycle
Use list_photos to recover uploads and get_photo for an authenticated JPEG endpoint. It is private: send your existing Bearer credential, never append it to a URL. delete_photo rejects photos locked or reserved by an order. Expired photos cannot be previewed or reused.
Use preview_print_item before requesting buyer approval. Pass the complete ordered photoIds for one design. A reviewed composition renders the same assembled file used for fulfillment (including four-photo photobooth strips). Other products return flat artwork pages in order, not a simulated physical product. Metadata is in structuredContent; actual JPEG thumbnails follow in content as image blocks. At most four pages are returned per call; pass nextOffset to continue. No public image links are created.
preview_print_price uses placeholder artwork without creating a payable quote. quote_prints still requires explicit photo/address sharing consent. list_orders returns up to 50 recent owned orders; get_order checks the latest payment state. get_checkout_link recovers a private on-site checkout for an existing order. Its fragment is a credential: only give it to the buyer. Never recreate an order to recover a payment.
update_order_coupon uses the existing unpaid x402 checkout guards. Check canEditCoupon, pass an empty code to remove it, then review the returned price and pricingVersion. This does not open a card checkout or request a wallet payment. Obtain new approval before requesting a fresh crypto quote. If the revised total is zero, call confirm_complimentary_order only with the buyer's explicit approval and returned pricingVersion. Existing terms acceptance is preserved; confirmation submits fulfillment once. Card, paid, and ambiguous payment states are protected.
Verified Firebase account sessions can create, list, and revoke their agent keys. Guests and existing agent keys cannot manage credentials. Keys retain the existing 90-day expiry. Admin catalog editing, refunds, merchant credentials, payment recovery overrides, email marketing, and store configuration remain in the protected Admin interface; these are not customer commerce tools. No MCP tool accepts card details or wallet secrets, silently accepts terms, or bypasses product readiness or payment verification.
Abuse prevention and private order security records
The order terms prohibit abuse through the website, API, or MCP. Obtain the buyer's approval and terms acceptance before ordering. PhotoPrintAgent cooperates with valid lawful requests subject to applicable legal requirements.
Order requests record private security evidence: authenticated account/guest identity, non-secret agent-key references, request time, action, response status, network peer and reported forwarding IPs, and User-Agent. An authenticated MCP initialize can supply clientInfo.name and clientInfo.version; later calls using the same credential and User-Agent can reference that reported client for up to 30 days. Optional X-MCP-Client-Name and X-MCP-Client-Version headers can identify a particular call. These names and network headers are reported claims, not verified personal identity. Never put secrets or personal information in client names or versions. Guest tokens in tool arguments are authenticated for the order but cannot be matched to an earlier anonymous initialization.
Security records are private and separate from analytics, remain enabled when analytics is opted out, and normally enter cleanup after 180 days unless held for a documented investigation or legal requirement. They are not returned by customer tools. See the privacy policy. Do not send passwords, private keys, raw card data, or unrelated personal data in tool arguments or headers.
Complete buying workflow
- Call
list_productswith query, category, finish, widthInches/heightInches, minPriceCents/maxPriceCents, availableOnly and offset/limit. Save nextOffset for pagination. Price filters use known unit prices before shipping/tax; unknown prices never match those filters. Readcapabilities: supported is an API feature, availableToOrder and productCount reflect the current catalog. Check a product's available flag and image slot rules before designing it. - Call
estimate_print_pricewith productId, quantity, ZIP and two-letter state. This requires no photos, name, email, phone or street address. Null components are unknown, not free. knownAmount is only the sum of known components and must never be presented as a complete total. No payable quote is created. - Upload and review the actual photos. Use the final
quote_printsworkflow, collect buyer approval and terms acceptance, then create/pay the order once. - Read
get_order.progress: productionStatus, shipmentStatus, lastUpdatedAt, supportStatus and request eligibility. Unknown shipment means no shipment confirmation is available; an estimate is not a verified delivery event. - Use
request_order_helpfor authorized help, change, cancellation or refund requests. A requested status is never a completed change or refund. Preserve idempotencyKey when retrying; only submit a new key for a new request.
Order events
subscribe_order_events registers a public HTTPS endpoint for one owned order.
Obtain the buyer's permission to share that order's status with the destination.
The secret is returned once. Validate HMAC-SHA256 over timestamp + . + exact
raw request body using X-PPA-Timestamp and X-PPA-Signature. Reject timestamps
outside five minutes and durably deduplicate by orderId and sequence. Return a
2xx acknowledgment only after safely recording the event. Retries are bounded
and delivery pauses after 12 failures. list_order_subscriptions shows delivery
state; replay_order_events resumes/replays from an explicit saved sequence.
unsubscribe_order_events revokes the secret. get_order_events provides
paginated recovery if a webhook was missed. Event content contains customer
status and approved tracking URLs, never private operational details.
Recoverable uploads
Send a stable Idempotency-Key header (16–100 safe characters) with identical
image bytes, product and crop options on retries. A changed payload with the same
key returns 409. GET /api/uploads/<key> with the same credential returns
processing, retryable, or complete plus the saved photo. Use a new key if the
image or crop changes. Attempts expire after 30 days, matching photo retention.
This is whole-file recovery, not byte-range resumption; the maximum is 15 MB.
A working Node/browser helper is /sdk/photo-upload.mjs. A webhook verification
helper is /sdk/order-webhook.mjs.
import {readFile} from 'node:fs/promises';
import {uploadPhoto} from './photo-upload.mjs';
const photo = await uploadPhoto({
bytes: await readFile('photo.jpg'), contentType: 'image/jpeg',
productId: 'REPLACE_WITH_AVAILABLE_PRODUCT_ID',
token: process.env.PPA_TOKEN,
attemptKey: process.env.PPA_UPLOAD_ATTEMPT_KEY,
onState: state => console.log(state),
});
// Persist photo.id with your draft; never log the credential.
OAuth account connections
Dynamic client registration accepts public clients (token_endpoint_auth_method
none) with exact registered HTTPS or loopback redirect URIs. Send resource in
both authorization and token requests, and use PKCE S256 and a random state.
Access tokens expire in one hour. Refresh tokens rotate on every use; reuse
revokes the grant. Revoke the grant through /api/oauth/revoke when disconnecting.
Connections grant customer operations only, never admin or key-management access.
A connection does not replace buyer approval or terms acceptance. Protected MCP
tool calls without credentials return HTTP 401 with a WWW-Authenticate discovery
challenge; guest and public discovery tools remain accessible.
PhotoPrintAgent product codes
Every catalog listing has a stable productCode such as PPA0F3FBA1A7130.
The public sku is the same seller-owned code. Show this code to customers and
use list_products.query to find it. Each sellable size/finish/pack variant has
its own code. Continue using the returned id as productId for API operations;
existing IDs and saved checkout links remain valid. These codes are seller SKUs,
not UPC/EAN/GTIN barcodes or marketplace listing IDs.
Full and narrow connectors (2.4)
Full commerce: https://photoprintagent.com/mcp (alias /api/mcp).
Narrow customer connector: https://photoprintagent.com/mcp-narrow (aliases
/api/mcp-narrow and /api/mcp-claude). Its generated reference is
https://photoprintagent.com/docs/mcp-narrow. The narrow profile has an explicit
10-tool allowlist: product discovery, existing-photo previews, estimates, quotes,
saved orders/events and support requests. Upload and purchase on the website;
no order creation, payment, key administration or AI generation tool is exposed.
Aliases do not change its canonical OAuth resource.
Use mcp:read for account status and previews. Add mcp:write for upload/quote
preparation and support/event management where the profile supports them. Full
commerce additionally supports mcp:orders for order creation/checkout handoffs
and mcp:payments for payment or complimentary-order confirmation. Request only
needed permissions. New requests without scope default to mcp:read; legacy
explicit mcp grants remain valid only on the full resource. Every grant requires
explicit account-holder consent. Permissions never replace purchase or terms
approval. Read-only get_order reads saved state without payment reconciliation.
OAuth grants are bound to the canonical full or narrow resource. Narrow tokens
cannot call full MCP or REST, and full tokens cannot call narrow MCP. Narrow private
tools require OAuth, not guest/API keys. On full MCP, scoped OAuth tokens are also
checked at the REST upload/payment routes; changing transports cannot bypass a
scope. Missing scopes return HTTP 403 with an insufficient_scope challenge.
Tools/list is filtered for scoped OAuth credentials; unauthenticated discovery
lists the profile's contract, not authorization to invoke its private tools.
OAuth Client ID Metadata Documents are supported: use an HTTPS client_id URL with
a path, serving bounded JSON with matching client_id, client_name, redirect_uris
and token_endpoint_auth_method none. Only public HTTPS port 443 is fetched,
without redirects or credentials. Dynamic client registration remains available
for older clients. Exact redirect matching, PKCE S256, single-use codes, resource
binding, refresh rotation/replay revocation and account revocation still apply.
Refresh may narrow scopes but cannot add them. Grants expire after 30 days.
The stable TypeScript MCP SDK 1.32.2 supports protocol 2025-11-25 and older negotiated revisions. Later specification features are not advertised as implemented. Test a new client's protocol negotiation before rollout.
Client setup and acceptance
For Claude custom connectors, use the narrow URL above and complete the OAuth
consent screen. For other Streamable HTTP clients, choose the full URL only when
advanced commerce is needed. Keep tokens in the client's secure credential store,
never in chat, URLs or source files. For status-only clients request mcp:read.
Check: connection consent identifies the application/profile and permissions; Cancel grants nothing; Allow returns to the client; tools/list matches the chosen profile; another account's objects are denied; a read-only grant cannot quote, upload or pay; revocation immediately denies access. Use an existing saved order for recovery checks, never create or pay a replacement after ambiguity. Native app verification and directory approval are separate from SDK compatibility.
Complete tool reference (server 2.4.0)
Each success object appears in structuredContent and as JSON in content[0].text for older clients. The following requests/responses are complete illustrative wire messages. Credentials, IDs, timestamps, addresses, rankings and prices here are examples; never pay them. Common errors are examples of tool execution errors; SDK input validation may use text only.
list_admin_products
List ready products including Admin Only products. Requires a verified allowlisted admin Firebase session; guest and agent keys cannot access private catalog products.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"products": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"productCode": {
"type": "string",
"pattern": "^PPA[A-F0-9]{12}$"
},
"sku": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"unitPriceCents": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
{
"type": "null"
}
],
"description": "Integer USD cents"
},
"category": {
"type": "string"
},
"finish": {
"type": "string"
},
"size": {
"type": "string"
},
"widthInches": {
"type": "number"
},
"heightInches": {
"type": "number"
},
"artwork": {
"type": "object",
"properties": {
"qualityGuidance": {
"type": "object",
"properties": {
"recommendedDpi": {
"type": "number"
},
"minimumDpiIsRejectionThreshold": {
"type": "boolean"
},
"fitModes": {
"type": "array",
"items": {
"type": "string"
}
},
"fitDescription": {
"type": "string"
}
},
"required": [
"recommendedDpi",
"minimumDpiIsRejectionThreshold",
"fitModes",
"fitDescription"
],
"additionalProperties": false
},
"widthPixels": {
"type": "integer"
},
"heightPixels": {
"type": "integer"
},
"minImages": {
"type": "integer"
},
"maxImages": {
"type": "integer"
},
"minimumDpi": {
"type": "number"
},
"allowRotate": {
"type": "boolean"
},
"labels": {
"type": "array",
"items": {
"type": "string"
}
},
"bleed": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"issues": {
"type": "array",
"items": {
"type": "string"
}
},
"calendar": {
"type": "object",
"properties": {
"layout": {
"type": "string",
"const": "alternating-photo-grid"
},
"months": {
"type": "number",
"enum": [
12,
18
]
}
},
"required": [
"layout",
"months"
],
"additionalProperties": false
},
"composition": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
},
"background": {
"type": "string"
},
"slots": {
"type": "array",
"items": {
"type": "object",
"properties": {
"x": {
"type": "integer"
},
"y": {
"type": "integer"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
}
},
"required": [
"x",
"y",
"width",
"height"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"width",
"height",
"background",
"slots"
],
"additionalProperties": false
}
},
"required": [
"widthPixels",
"heightPixels",
"minImages",
"maxImages",
"minimumDpi",
"allowRotate",
"labels",
"bleed",
"issues"
],
"additionalProperties": false
},
"shipping": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"provider",
"flat",
"per_item"
]
},
"amountCents": {
"type": "integer",
"minimum": 0,
"maximum": 100000,
"default": 0
},
"multipleItemAmountCents": {
"anyOf": [
{
"$ref": "#/properties/products/items/properties/shipping/properties/amountCents"
},
{
"type": "null"
}
],
"default": null
}
},
"required": [
"mode"
],
"additionalProperties": false
},
"adminOnly": {
"type": "boolean"
},
"available": {
"type": "boolean"
},
"unavailableReason": {
"type": "string"
},
"preview": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"id",
"title",
"description",
"widthInches",
"heightInches"
],
"additionalProperties": true
}
}
},
"required": [
"products"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "list_admin_products",
"arguments": {}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"products\":[{\"id\":\"photo-4x6\",\"productCode\":\"PPA5B2F748CE094\",\"sku\":\"PPA5B2F748CE094\",\"title\":\"Classic 4 × 6 photo prints\",\"description\":\"Your photos printed for home delivery.\",\"widthInches\":6,\"heightInches\":4}]}"
}
],
"structuredContent": {
"products": [
{
"id": "photo-4x6",
"productCode": "PPA5B2F748CE094",
"sku": "PPA5B2F748CE094",
"title": "Classic 4 × 6 photo prints",
"description": "Your photos printed for home delivery.",
"widthInches": 6,
"heightInches": 4
}
]
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":403,\"message\":\"Admin access required.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 403,
"message": "Admin access required."
}
},
"isError": true
}
}
list_photos
List your unexpired, unlocked uploaded photos. Use their IDs in slot order. Photos reserved by an order cannot be deleted.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"photos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"productId": {
"type": "string"
},
"artworkKey": {
"type": "string"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
},
"quality": {
"anyOf": [
{
"type": "string",
"enum": [
"high",
"reduced"
]
},
{
"type": "null"
}
]
},
"orientation": {
"type": "string",
"enum": [
"portrait",
"landscape"
]
}
},
"required": [
"id",
"productId",
"artworkKey",
"width",
"height",
"quality",
"orientation"
],
"additionalProperties": false
}
}
},
"required": [
"photos"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "list_photos",
"arguments": {}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"photos\":[{\"id\":\"22222222-2222-4222-8222-222222222222\",\"productId\":\"photo-4x6\",\"artworkKey\":\"example-artwork-key\",\"width\":1800,\"height\":1200,\"quality\":\"high\",\"orientation\":\"landscape\"}]}"
}
],
"structuredContent": {
"photos": [
{
"id": "22222222-2222-4222-8222-222222222222",
"productId": "photo-4x6",
"artworkKey": "example-artwork-key",
"width": 1800,
"height": 1200,
"quality": "high",
"orientation": "landscape"
}
]
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":401,\"message\":\"Authentication required.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 401,
"message": "Authentication required."
}
},
"isError": true
}
}
get_photo
Get the private JPEG download endpoint for your uploaded photo. Send the same Bearer credential; this is not a public image URL.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {
"photoId": {
"type": "string",
"format": "uuid"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"photoId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"method": {
"type": "string",
"const": "GET"
},
"mimeType": {
"type": "string",
"const": "image/jpeg"
},
"authorization": {
"type": "string"
}
},
"required": [
"url",
"method",
"mimeType",
"authorization"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "get_photo",
"arguments": {
"photoId": "22222222-2222-4222-8222-222222222222"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"url\":\"https://photoprintagent.com/api/photos/22222222-2222-4222-8222-222222222222\",\"method\":\"GET\",\"mimeType\":\"image/jpeg\",\"authorization\":\"Bearer: use your existing account or guest credential\"}"
}
],
"structuredContent": {
"url": "https://photoprintagent.com/api/photos/22222222-2222-4222-8222-222222222222",
"method": "GET",
"mimeType": "image/jpeg",
"authorization": "Bearer: use your existing account or guest credential"
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":404,\"message\":\"Not found.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 404,
"message": "Not found."
}
},
"isError": true
}
}
delete_photo
Permanently delete one of your uploaded photos. Photos locked or reserved by an order cannot be deleted.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {
"photoId": {
"type": "string",
"format": "uuid"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"photoId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"ok": {
"type": "boolean",
"const": true
}
},
"required": [
"ok"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "delete_photo",
"arguments": {
"photoId": "22222222-2222-4222-8222-222222222222"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"ok\":true}"
}
],
"structuredContent": {
"ok": true
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":409,\"message\":\"This photo is attached to an order.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 409,
"message": "This photo is attached to an order."
}
},
"isError": true
}
}
preview_print_item
Preview one complete design using owned uploaded photoIds in product slot order. Reviewed compositions (including photobooth strips) render the same assembly used for fulfillment. For artwork.calendar, include calendar:{startYear,startMonth}; previews include the generated date grids in print page order. Other products return ordered flat artwork pages, not a physical mockup. JPEG thumbnails appear as MCP image content after the JSON metadata. Page with offset/limit; no order or external photo link is created.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {
"productId": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{1,63}$"
},
"photoIds": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"minItems": 1,
"maxItems": 200
},
"calendar": {
"type": "object",
"properties": {
"startYear": {
"type": "integer",
"minimum": 2000,
"maximum": 2100
},
"startMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
}
},
"required": [
"startYear",
"startMonth"
],
"additionalProperties": false
},
"offset": {
"type": "integer",
"minimum": 0,
"default": 0
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 4,
"default": 4
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"photoIds"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"productId": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"composition",
"artwork_pages",
"calendar"
]
},
"layoutId": {
"type": [
"string",
"null"
]
},
"totalPages": {
"type": "integer"
},
"nextOffset": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"pages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"index": {
"type": "integer"
},
"label": {
"type": "string"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
}
},
"required": [
"index",
"label",
"width",
"height"
],
"additionalProperties": false
}
}
},
"required": [
"productId",
"kind",
"layoutId",
"totalPages",
"nextOffset",
"pages"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "preview_print_item",
"arguments": {
"productId": "photo-4x6",
"photoIds": [
"22222222-2222-4222-8222-222222222222"
]
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"productId\":\"photo-4x6\",\"kind\":\"artwork_pages\",\"layoutId\":null,\"totalPages\":1,\"nextOffset\":null,\"pages\":[{\"index\":0,\"label\":\"Image 1\",\"width\":1000,\"height\":667}]}"
}
],
"structuredContent": {
"productId": "photo-4x6",
"kind": "artwork_pages",
"layoutId": null,
"totalPages": 1,
"nextOffset": null,
"pages": [
{
"index": 0,
"label": "Image 1",
"width": 1000,
"height": 667
}
]
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":409,\"message\":\"An image was prepared for different artwork dimensions. Upload it again for this product.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 409,
"message": "An image was prepared for different artwork dimensions. Upload it again for this product."
}
},
"isError": true
}
}
The success example above shows metadata only. Runtime content additionally includes one image/jpeg MCP image block per returned page, with base64 JPEG data; image bytes are omitted from this reference.
preview_print_price
Estimate product and destination pricing before using the customer’s photos for an order. Uses placeholder artwork and does not create an order or a payable quote. Call quote_prints with buyer consent before checkout.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"productId": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{1,63}$"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"calendar": {
"type": "object",
"properties": {
"startYear": {
"type": "integer",
"minimum": 2000,
"maximum": 2100
},
"startMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
}
},
"required": [
"startYear",
"startMonth"
],
"additionalProperties": false
},
"productId": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{1,63}$"
},
"photoId": {
"type": "string",
"format": "uuid"
},
"photoIds": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"minItems": 1,
"maxItems": 200
},
"quantity": {
"type": "integer",
"minimum": 1,
"maximum": 99
}
},
"required": [
"quantity"
],
"additionalProperties": false
},
"minItems": 1,
"maxItems": 50
},
"shipping": {
"type": "object",
"properties": {
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 150
},
"lastName": {
"$ref": "#/properties/shipping/properties/firstName"
},
"email": {
"type": "string",
"format": "email",
"maxLength": 254
},
"phone": {
"type": "string"
},
"line1": {
"$ref": "#/properties/shipping/properties/firstName"
},
"line2": {
"type": "string",
"maxLength": 150,
"default": ""
},
"city": {
"$ref": "#/properties/shipping/properties/firstName"
},
"state": {
"type": "string",
"pattern": "^[A-Z]{2}$"
},
"zip": {
"type": "string",
"pattern": "^\\d{5}(-\\d{4})?$"
},
"country": {
"type": "string",
"const": "US"
}
},
"required": [
"firstName",
"lastName",
"email",
"phone",
"line1",
"city",
"state",
"zip",
"country"
],
"additionalProperties": false
},
"couponCode": {
"type": "string",
"maxLength": 64
},
"campaignId": {
"type": "string",
"pattern": "^[a-f0-9]{16}$"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"items",
"shipping"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"preview": {
"type": "boolean",
"const": true
},
"price": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"const": "USD"
},
"subtotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"shipping": {
"$ref": "#/properties/price/properties/subtotal"
},
"tax": {
"$ref": "#/properties/price/properties/subtotal"
},
"total": {
"$ref": "#/properties/price/properties/subtotal"
},
"originalTotal": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"discount": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"coupon": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"printDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"shippingDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"taxCredit": {
"$ref": "#/properties/price/properties/subtotal"
}
},
"required": [
"code",
"name",
"printDiscount",
"shippingDiscount",
"taxCredit"
],
"additionalProperties": false
}
},
"required": [
"currency",
"subtotal",
"shipping",
"tax",
"total"
],
"additionalProperties": false
},
"validUntil": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"expiresAt": {
"$ref": "#/properties/validUntil"
},
"lineItems": {
"type": "array",
"items": {
"type": "object",
"properties": {
"photoId": {
"type": "string",
"format": "uuid"
},
"photoIds": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"productId": {
"type": "string"
},
"quantity": {
"type": "integer"
},
"calendar": {
"type": "object",
"properties": {
"startYear": {
"type": "integer",
"minimum": 2000,
"maximum": 2100
},
"startMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
}
},
"required": [
"startYear",
"startMonth"
],
"additionalProperties": false
}
},
"required": [
"productId",
"quantity"
],
"additionalProperties": false
}
}
},
"required": [
"preview",
"price",
"validUntil",
"expiresAt",
"lineItems"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "preview_print_price",
"arguments": {
"items": [
{
"photoId": "22222222-2222-4222-8222-222222222222",
"quantity": 2
}
],
"shipping": {
"firstName": "Jane",
"lastName": "Buyer",
"email": "jane@example.com",
"phone": "2125550100",
"line1": "123 Example Street",
"line2": "Suite 2R",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
}
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"preview\":true,\"price\":{\"currency\":\"USD\",\"subtotal\":100,\"shipping\":400,\"tax\":50,\"total\":550},\"validUntil\":1893456900000,\"expiresAt\":1893456900000,\"lineItems\":[{\"photoId\":\"22222222-2222-4222-8222-222222222222\",\"quantity\":2,\"productId\":\"photo-4x6\"}]}"
}
],
"structuredContent": {
"preview": true,
"price": {
"currency": "USD",
"subtotal": 100,
"shipping": 400,
"tax": 50,
"total": 550
},
"validUntil": 1893456900000,
"expiresAt": 1893456900000,
"lineItems": [
{
"photoId": "22222222-2222-4222-8222-222222222222",
"quantity": 2,
"productId": "photo-4x6"
}
]
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":400,\"message\":\"Check your photos, quantities, and delivery details.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 400,
"message": "Check your photos, quantities, and delivery details."
}
},
"isError": true
}
}
list_orders
List your most recent orders, newest first, up to 50. Does not reconcile payments; use get_order for a specific order. Unpaid Admin Only orders require a verified admin session.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 50,
"default": 50
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"orders": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"status": {
"type": "string",
"enum": [
"creating_checkout",
"awaiting_payment",
"verifying_payment",
"settling_payment",
"paid",
"submitting",
"processing",
"needs_review",
"expired"
]
},
"method": {
"type": "string",
"enum": [
"card",
"x402"
]
},
"price": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"const": "USD"
},
"subtotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"shipping": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal"
},
"tax": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal"
},
"total": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal"
},
"originalTotal": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"discount": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"coupon": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"printDiscount": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal"
},
"shippingDiscount": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal"
},
"taxCredit": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal"
}
},
"required": [
"code",
"name",
"printDiscount",
"shippingDiscount",
"taxCredit"
],
"additionalProperties": false
}
},
"required": [
"currency",
"subtotal",
"shipping",
"tax",
"total"
],
"additionalProperties": false
},
"pricingVersion": {
"type": "integer",
"minimum": 0
},
"paymentDeadline": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"canEditCoupon": {
"type": "boolean"
},
"canRenewCheckout": {
"type": "boolean"
},
"cardPaymentUrl": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"cardProcessor": {
"anyOf": [
{
"type": "string",
"enum": [
"square",
"stripe"
]
},
{
"type": "null"
}
]
},
"quantity": {
"type": "integer"
},
"progress": {
"type": "object",
"properties": {
"productionStatus": {
"type": "string",
"enum": [
"not_submitted",
"queued",
"submitting",
"accepted",
"printing",
"shipped",
"delivered",
"cancelled",
"on_hold",
"needs_review",
"unknown"
]
},
"shipmentStatus": {
"type": "string",
"enum": [
"unknown",
"shipped",
"delivered"
]
},
"lastUpdatedAt": {
"type": [
"number",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"supportStatus": {
"type": "string",
"enum": [
"none",
"open",
"waiting_customer",
"under_review",
"resolved"
]
},
"canRequestCancellation": {
"type": "boolean"
},
"canRequestChange": {
"type": "boolean"
},
"canRequestRefund": {
"type": "boolean"
},
"cancellationGuaranteed": {
"type": "boolean",
"const": false
}
},
"required": [
"productionStatus",
"shipmentStatus",
"lastUpdatedAt",
"trackingUrls",
"supportStatus",
"canRequestCancellation",
"canRequestChange",
"canRequestRefund",
"cancellationGuaranteed"
],
"additionalProperties": false
},
"productName": {
"type": "string"
},
"imageCount": {
"type": "integer"
},
"createdAt": {
"$ref": "#/properties/orders/items/properties/paymentDeadline"
},
"paidAt": {
"anyOf": [
{
"$ref": "#/properties/orders/items/properties/paymentDeadline"
},
{
"type": "null"
}
],
"description": "Unix time in milliseconds"
},
"paymentStatus": {
"type": "string",
"enum": [
"unpaid",
"pending",
"paid",
"refunded",
"not_required",
"needs_review",
"expired"
]
},
"fulfillmentStatus": {
"type": "string",
"enum": [
"not_submitted",
"submitting",
"accepted",
"needs_review"
]
},
"cryptoPayment": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"rankId": {
"type": "string"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string"
},
"asset": {
"type": "string"
},
"decimals": {
"type": "integer"
},
"transferMethod": {
"type": "string",
"enum": [
"eip3009",
"permit2",
"spl"
]
},
"network": {
"type": "string"
},
"tokenProgram": {
"type": "string"
},
"rank": {
"type": [
"number",
"null"
]
},
"wrapped": {
"type": "boolean"
},
"stable": {
"type": "boolean"
},
"availability": {
"type": "string",
"enum": [
"quote_required",
"receiving_ready"
]
},
"priceChecked": {
"type": "boolean"
},
"tokenId": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^\\d+$"
},
"displayAmount": {
"type": "string"
},
"usdTotal": {
"$ref": "#/properties/orders/items/properties/price/properties/subtotal"
},
"usdPrice": {
"type": "string"
},
"priceAsOf": {
"$ref": "#/properties/orders/items/properties/paymentDeadline"
},
"source": {
"type": "string"
},
"payTo": {
"type": "string"
},
"quotedAt": {
"$ref": "#/properties/orders/items/properties/paymentDeadline"
},
"validUntil": {
"$ref": "#/properties/orders/items/properties/paymentDeadline"
}
},
"required": [
"id",
"rankId",
"name",
"symbol",
"asset",
"decimals",
"transferMethod",
"network",
"tokenId",
"amount",
"displayAmount",
"usdTotal",
"usdPrice",
"priceAsOf",
"source",
"payTo",
"quotedAt",
"validUntil"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"transaction": {
"type": [
"string",
"null"
]
},
"network": {
"type": [
"string",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
},
"message": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"status",
"method",
"price",
"pricingVersion",
"paymentDeadline",
"canEditCoupon",
"quantity",
"createdAt",
"paidAt",
"paymentStatus",
"fulfillmentStatus",
"cryptoPayment",
"transaction",
"network",
"trackingUrls",
"message"
],
"additionalProperties": false
}
}
},
"required": [
"orders"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "list_orders",
"arguments": {
"limit": 50
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"orders\":[{\"id\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"status\":\"awaiting_payment\",\"method\":\"x402\",\"price\":{\"currency\":\"USD\",\"subtotal\":100,\"shipping\":400,\"tax\":50,\"total\":550},\"pricingVersion\":0,\"paymentDeadline\":1893542400000,\"canEditCoupon\":true,\"quantity\":2,\"createdAt\":1893456000000,\"paidAt\":null,\"paymentStatus\":\"unpaid\",\"fulfillmentStatus\":\"not_submitted\",\"cryptoPayment\":null,\"transaction\":null,\"network\":null,\"trackingUrls\":[],\"message\":null}]}"
}
],
"structuredContent": {
"orders": [
{
"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"status": "awaiting_payment",
"method": "x402",
"price": {
"currency": "USD",
"subtotal": 100,
"shipping": 400,
"tax": 50,
"total": 550
},
"pricingVersion": 0,
"paymentDeadline": 1893542400000,
"canEditCoupon": true,
"quantity": 2,
"createdAt": 1893456000000,
"paidAt": null,
"paymentStatus": "unpaid",
"fulfillmentStatus": "not_submitted",
"cryptoPayment": null,
"transaction": null,
"network": null,
"trackingUrls": [],
"message": null
}
]
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":401,\"message\":\"Authentication required.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 401,
"message": "Authentication required."
}
},
"isError": true
}
}
get_checkout_link
Mint a private on-site checkout link for your existing order. Preserve its access fragment, share only with the buyer, and never create another order to recover a checkout. Card payment uses the embedded payment modal; MCP never accepts card details.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"checkoutUrl": {
"type": "string",
"format": "uri"
}
},
"required": [
"checkoutUrl"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "get_checkout_link",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"checkoutUrl\":\"https://photoprintagent.com/checkout/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#access=ppc_0000000000000000000000000000000000000000000000000000000000000000\"}"
}
],
"structuredContent": {
"checkoutUrl": "https://photoprintagent.com/checkout/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#access=ppc_0000000000000000000000000000000000000000000000000000000000000000"
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":404,\"message\":\"Not found.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 404,
"message": "Not found."
}
},
"isError": true
}
}
update_order_coupon
Apply or remove a coupon on your eligible unpaid x402 order; empty couponCode removes it. Check canEditCoupon first. Returns the revised price and pricingVersion, invalidates old crypto quotes, and never requests payment. Obtain approval of the new total before paying. Card or ambiguous payments cannot be changed.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"couponCode": {
"type": "string",
"maxLength": 64
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId",
"couponCode"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"status": {
"type": "string",
"enum": [
"creating_checkout",
"awaiting_payment",
"verifying_payment",
"settling_payment",
"paid",
"submitting",
"processing",
"needs_review",
"expired"
]
},
"method": {
"type": "string",
"enum": [
"card",
"x402"
]
},
"price": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"const": "USD"
},
"subtotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"shipping": {
"$ref": "#/properties/price/properties/subtotal"
},
"tax": {
"$ref": "#/properties/price/properties/subtotal"
},
"total": {
"$ref": "#/properties/price/properties/subtotal"
},
"originalTotal": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"discount": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"coupon": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"printDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"shippingDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"taxCredit": {
"$ref": "#/properties/price/properties/subtotal"
}
},
"required": [
"code",
"name",
"printDiscount",
"shippingDiscount",
"taxCredit"
],
"additionalProperties": false
}
},
"required": [
"currency",
"subtotal",
"shipping",
"tax",
"total"
],
"additionalProperties": false
},
"pricingVersion": {
"type": "integer",
"minimum": 0
},
"paymentDeadline": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"canEditCoupon": {
"type": "boolean"
},
"canRenewCheckout": {
"type": "boolean"
},
"cardPaymentUrl": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"cardProcessor": {
"anyOf": [
{
"type": "string",
"enum": [
"square",
"stripe"
]
},
{
"type": "null"
}
]
},
"quantity": {
"type": "integer"
},
"progress": {
"type": "object",
"properties": {
"productionStatus": {
"type": "string",
"enum": [
"not_submitted",
"queued",
"submitting",
"accepted",
"printing",
"shipped",
"delivered",
"cancelled",
"on_hold",
"needs_review",
"unknown"
]
},
"shipmentStatus": {
"type": "string",
"enum": [
"unknown",
"shipped",
"delivered"
]
},
"lastUpdatedAt": {
"type": [
"number",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"supportStatus": {
"type": "string",
"enum": [
"none",
"open",
"waiting_customer",
"under_review",
"resolved"
]
},
"canRequestCancellation": {
"type": "boolean"
},
"canRequestChange": {
"type": "boolean"
},
"canRequestRefund": {
"type": "boolean"
},
"cancellationGuaranteed": {
"type": "boolean",
"const": false
}
},
"required": [
"productionStatus",
"shipmentStatus",
"lastUpdatedAt",
"trackingUrls",
"supportStatus",
"canRequestCancellation",
"canRequestChange",
"canRequestRefund",
"cancellationGuaranteed"
],
"additionalProperties": false
},
"productName": {
"type": "string"
},
"imageCount": {
"type": "integer"
},
"createdAt": {
"$ref": "#/properties/paymentDeadline"
},
"paidAt": {
"anyOf": [
{
"$ref": "#/properties/paymentDeadline"
},
{
"type": "null"
}
],
"description": "Unix time in milliseconds"
},
"paymentStatus": {
"type": "string",
"enum": [
"unpaid",
"pending",
"paid",
"refunded",
"not_required",
"needs_review",
"expired"
]
},
"fulfillmentStatus": {
"type": "string",
"enum": [
"not_submitted",
"submitting",
"accepted",
"needs_review"
]
},
"cryptoPayment": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"rankId": {
"type": "string"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string"
},
"asset": {
"type": "string"
},
"decimals": {
"type": "integer"
},
"transferMethod": {
"type": "string",
"enum": [
"eip3009",
"permit2",
"spl"
]
},
"network": {
"type": "string"
},
"tokenProgram": {
"type": "string"
},
"rank": {
"type": [
"number",
"null"
]
},
"wrapped": {
"type": "boolean"
},
"stable": {
"type": "boolean"
},
"availability": {
"type": "string",
"enum": [
"quote_required",
"receiving_ready"
]
},
"priceChecked": {
"type": "boolean"
},
"tokenId": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^\\d+$"
},
"displayAmount": {
"type": "string"
},
"usdTotal": {
"$ref": "#/properties/price/properties/subtotal"
},
"usdPrice": {
"type": "string"
},
"priceAsOf": {
"$ref": "#/properties/paymentDeadline"
},
"source": {
"type": "string"
},
"payTo": {
"type": "string"
},
"quotedAt": {
"$ref": "#/properties/paymentDeadline"
},
"validUntil": {
"$ref": "#/properties/paymentDeadline"
}
},
"required": [
"id",
"rankId",
"name",
"symbol",
"asset",
"decimals",
"transferMethod",
"network",
"tokenId",
"amount",
"displayAmount",
"usdTotal",
"usdPrice",
"priceAsOf",
"source",
"payTo",
"quotedAt",
"validUntil"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"transaction": {
"type": [
"string",
"null"
]
},
"network": {
"type": [
"string",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
},
"message": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"status",
"method",
"price",
"pricingVersion",
"paymentDeadline",
"canEditCoupon",
"quantity",
"createdAt",
"paidAt",
"paymentStatus",
"fulfillmentStatus",
"cryptoPayment",
"transaction",
"network",
"trackingUrls",
"message"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "update_order_coupon",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"couponCode": ""
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"id\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"status\":\"awaiting_payment\",\"method\":\"x402\",\"price\":{\"currency\":\"USD\",\"subtotal\":100,\"shipping\":400,\"tax\":50,\"total\":550},\"pricingVersion\":0,\"paymentDeadline\":1893542400000,\"canEditCoupon\":true,\"quantity\":2,\"createdAt\":1893456000000,\"paidAt\":null,\"paymentStatus\":\"unpaid\",\"fulfillmentStatus\":\"not_submitted\",\"cryptoPayment\":null,\"transaction\":null,\"network\":null,\"trackingUrls\":[],\"message\":null}"
}
],
"structuredContent": {
"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"status": "awaiting_payment",
"method": "x402",
"price": {
"currency": "USD",
"subtotal": 100,
"shipping": 400,
"tax": 50,
"total": 550
},
"pricingVersion": 0,
"paymentDeadline": 1893542400000,
"canEditCoupon": true,
"quantity": 2,
"createdAt": 1893456000000,
"paidAt": null,
"paymentStatus": "unpaid",
"fulfillmentStatus": "not_submitted",
"cryptoPayment": null,
"transaction": null,
"network": null,
"trackingUrls": [],
"message": null
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":409,\"message\":\"This order can no longer change its payment total.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 409,
"message": "This order can no longer change its payment total."
}
},
"isError": true
}
}
confirm_complimentary_order
Explicitly approve fulfillment of your existing zero-total order after a coupon change. Requires buyerApproved:true and the current pricingVersion. Original order terms consent remains required. Idempotent for an already confirmed complimentary order; never use this for a positive total.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"buyerApproved": {
"type": "boolean",
"const": true
},
"pricingVersion": {
"type": "integer",
"minimum": 0
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId",
"buyerApproved",
"pricingVersion"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"status": {
"type": "string",
"enum": [
"creating_checkout",
"awaiting_payment",
"verifying_payment",
"settling_payment",
"paid",
"submitting",
"processing",
"needs_review",
"expired"
]
},
"method": {
"type": "string",
"enum": [
"card",
"x402"
]
},
"price": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"const": "USD"
},
"subtotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"shipping": {
"$ref": "#/properties/price/properties/subtotal"
},
"tax": {
"$ref": "#/properties/price/properties/subtotal"
},
"total": {
"$ref": "#/properties/price/properties/subtotal"
},
"originalTotal": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"discount": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"coupon": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"printDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"shippingDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"taxCredit": {
"$ref": "#/properties/price/properties/subtotal"
}
},
"required": [
"code",
"name",
"printDiscount",
"shippingDiscount",
"taxCredit"
],
"additionalProperties": false
}
},
"required": [
"currency",
"subtotal",
"shipping",
"tax",
"total"
],
"additionalProperties": false
},
"pricingVersion": {
"type": "integer",
"minimum": 0
},
"paymentDeadline": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"canEditCoupon": {
"type": "boolean"
},
"canRenewCheckout": {
"type": "boolean"
},
"cardPaymentUrl": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"cardProcessor": {
"anyOf": [
{
"type": "string",
"enum": [
"square",
"stripe"
]
},
{
"type": "null"
}
]
},
"quantity": {
"type": "integer"
},
"progress": {
"type": "object",
"properties": {
"productionStatus": {
"type": "string",
"enum": [
"not_submitted",
"queued",
"submitting",
"accepted",
"printing",
"shipped",
"delivered",
"cancelled",
"on_hold",
"needs_review",
"unknown"
]
},
"shipmentStatus": {
"type": "string",
"enum": [
"unknown",
"shipped",
"delivered"
]
},
"lastUpdatedAt": {
"type": [
"number",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"supportStatus": {
"type": "string",
"enum": [
"none",
"open",
"waiting_customer",
"under_review",
"resolved"
]
},
"canRequestCancellation": {
"type": "boolean"
},
"canRequestChange": {
"type": "boolean"
},
"canRequestRefund": {
"type": "boolean"
},
"cancellationGuaranteed": {
"type": "boolean",
"const": false
}
},
"required": [
"productionStatus",
"shipmentStatus",
"lastUpdatedAt",
"trackingUrls",
"supportStatus",
"canRequestCancellation",
"canRequestChange",
"canRequestRefund",
"cancellationGuaranteed"
],
"additionalProperties": false
},
"productName": {
"type": "string"
},
"imageCount": {
"type": "integer"
},
"createdAt": {
"$ref": "#/properties/paymentDeadline"
},
"paidAt": {
"anyOf": [
{
"$ref": "#/properties/paymentDeadline"
},
{
"type": "null"
}
],
"description": "Unix time in milliseconds"
},
"paymentStatus": {
"type": "string",
"enum": [
"unpaid",
"pending",
"paid",
"refunded",
"not_required",
"needs_review",
"expired"
]
},
"fulfillmentStatus": {
"type": "string",
"enum": [
"not_submitted",
"submitting",
"accepted",
"needs_review"
]
},
"cryptoPayment": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"rankId": {
"type": "string"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string"
},
"asset": {
"type": "string"
},
"decimals": {
"type": "integer"
},
"transferMethod": {
"type": "string",
"enum": [
"eip3009",
"permit2",
"spl"
]
},
"network": {
"type": "string"
},
"tokenProgram": {
"type": "string"
},
"rank": {
"type": [
"number",
"null"
]
},
"wrapped": {
"type": "boolean"
},
"stable": {
"type": "boolean"
},
"availability": {
"type": "string",
"enum": [
"quote_required",
"receiving_ready"
]
},
"priceChecked": {
"type": "boolean"
},
"tokenId": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^\\d+$"
},
"displayAmount": {
"type": "string"
},
"usdTotal": {
"$ref": "#/properties/price/properties/subtotal"
},
"usdPrice": {
"type": "string"
},
"priceAsOf": {
"$ref": "#/properties/paymentDeadline"
},
"source": {
"type": "string"
},
"payTo": {
"type": "string"
},
"quotedAt": {
"$ref": "#/properties/paymentDeadline"
},
"validUntil": {
"$ref": "#/properties/paymentDeadline"
}
},
"required": [
"id",
"rankId",
"name",
"symbol",
"asset",
"decimals",
"transferMethod",
"network",
"tokenId",
"amount",
"displayAmount",
"usdTotal",
"usdPrice",
"priceAsOf",
"source",
"payTo",
"quotedAt",
"validUntil"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"transaction": {
"type": [
"string",
"null"
]
},
"network": {
"type": [
"string",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
},
"message": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"status",
"method",
"price",
"pricingVersion",
"paymentDeadline",
"canEditCoupon",
"quantity",
"createdAt",
"paidAt",
"paymentStatus",
"fulfillmentStatus",
"cryptoPayment",
"transaction",
"network",
"trackingUrls",
"message"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "confirm_complimentary_order",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"buyerApproved": true,
"pricingVersion": 1
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"id\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"status\":\"processing\",\"method\":\"x402\",\"price\":{\"currency\":\"USD\",\"subtotal\":100,\"shipping\":400,\"tax\":50,\"total\":0,\"discount\":550,\"originalTotal\":550},\"pricingVersion\":1,\"paymentDeadline\":1893542400000,\"canEditCoupon\":false,\"quantity\":2,\"createdAt\":1893456000000,\"paidAt\":1893456060000,\"paymentStatus\":\"not_required\",\"fulfillmentStatus\":\"accepted\",\"cryptoPayment\":null,\"transaction\":null,\"network\":null,\"trackingUrls\":[],\"message\":null}"
}
],
"structuredContent": {
"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"status": "processing",
"method": "x402",
"price": {
"currency": "USD",
"subtotal": 100,
"shipping": 400,
"tax": 50,
"total": 0,
"discount": 550,
"originalTotal": 550
},
"pricingVersion": 1,
"paymentDeadline": 1893542400000,
"canEditCoupon": false,
"quantity": 2,
"createdAt": 1893456000000,
"paidAt": 1893456060000,
"paymentStatus": "not_required",
"fulfillmentStatus": "accepted",
"cryptoPayment": null,
"transaction": null,
"network": null,
"trackingUrls": [],
"message": null
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":409,\"message\":\"Your order total changed. Review it before confirming.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 409,
"message": "Your order total changed. Review it before confirming."
}
},
"isError": true
}
}
list_agent_keys
List your account key IDs and expiry/revocation status, never their secrets. Requires a verified Firebase account session; guest and agent keys cannot manage keys.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"keys": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"createdAt": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"expiresAt": {
"$ref": "#/properties/keys/items/properties/createdAt"
},
"revoked": {
"type": "boolean"
}
},
"required": [
"id",
"createdAt",
"expiresAt",
"revoked"
],
"additionalProperties": false
}
}
},
"required": [
"keys"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "list_agent_keys",
"arguments": {}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"keys\":[{\"id\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"createdAt\":1893456000000,\"expiresAt\":1901232000000,\"revoked\":false}]}"
}
],
"structuredContent": {
"keys": [
{
"id": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"createdAt": 1893456000000,
"expiresAt": 1901232000000,
"revoked": false
}
]
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":403,\"message\":\"Use a verified Firebase ID token to manage keys. See /docs/mcp.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 403,
"message": "Use a verified Firebase ID token to manage keys. See /docs/mcp."
}
},
"isError": true
}
}
revoke_agent_key
Revoke one of your account keys by ID. Requires a verified Firebase account session; guest and agent keys cannot manage keys.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {
"keyId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
}
},
"required": [
"keyId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"ok": {
"type": "boolean",
"const": true
}
},
"required": [
"ok"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "revoke_agent_key",
"arguments": {
"keyId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"ok\":true}"
}
],
"structuredContent": {
"ok": true
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":403,\"message\":\"Use a verified Firebase ID token to manage keys. See /docs/mcp.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 403,
"message": "Use a verified Firebase ID token to manage keys. See /docs/mcp."
}
},
"isError": true
}
}
list_products
Public paginated product catalog, print specifications, and availability. Follow nextOffset until null. availableOnly defaults to true; false includes unavailable public products with explicit available flags. Filters cover query, category, finish, dimensions and known unit price range. capabilities distinguishes API support from current orderability. productCode and sku are PhotoPrintAgent seller codes for customer listings and search; id remains the API identifier for uploads and quotes. Each product supplies artwork dimensions, minimum/maximum image counts, ordered slot labels, bleed and rotation rules. These apply to all active supported products, including multi-image designs. Artwork minimumDpi values are print quality guidance, not an upload rejection threshold: accept smaller valid images, resize them, and treat reduced quality as a nonblocking warning. Admin Only products are never listed. Pass a returned products[].id as productId when uploading and quoting; omission selects the original photo-4x6 product. Price depends on the items and destination; call quote_prints for an authoritative total.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"query": {
"type": "string",
"maxLength": 100
},
"category": {
"type": "string",
"maxLength": 80
},
"finish": {
"type": "string",
"maxLength": 80
},
"widthInches": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000
},
"heightInches": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000
},
"minPriceCents": {
"type": "integer",
"minimum": 0
},
"maxPriceCents": {
"type": "integer",
"minimum": 0
},
"availableOnly": {
"type": "boolean",
"default": true
},
"offset": {
"type": "integer",
"minimum": 0,
"default": 0
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"product": {
"type": "object",
"properties": {
"id": {
"type": "string",
"const": "photo-4x6"
},
"productCode": {
"type": "string"
},
"sku": {
"type": "string"
},
"title": {
"type": "string"
},
"countries": {
"type": "array",
"items": {
"type": "string",
"const": "US"
}
},
"maxPhotos": {
"type": "integer"
},
"maxPrints": {
"type": "integer"
},
"specs": {
"type": "object",
"properties": {
"widthInches": {
"type": "number"
},
"heightInches": {
"type": "number"
},
"landscapePixels": {
"type": "array",
"items": {
"type": "number"
}
},
"portraitPixels": {
"type": "array",
"items": {
"type": "number"
}
},
"recommendedDpi": {
"type": "number"
},
"minimumDpi": {
"type": "number"
},
"colorSpace": {
"type": "string",
"const": "sRGB"
},
"outputFormat": {
"type": "string",
"const": "image/jpeg"
},
"maxFileBytes": {
"type": "number"
},
"maxInputPixels": {
"type": "number"
},
"acceptedMimeTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"acceptedExtensions": {
"type": "array",
"items": {
"type": "string"
}
},
"imageHandling": {
"type": "object",
"properties": {
"resolutionPolicy": {
"type": "string"
},
"animationPolicy": {
"type": "string"
},
"multipagePolicy": {
"type": "string"
},
"transparencyPolicy": {
"type": "string"
},
"colorPolicy": {
"type": "string"
},
"svgPolicy": {
"type": "string"
},
"unsupportedPolicy": {
"type": "string"
},
"helpUrl": {
"type": "string"
}
},
"required": [
"resolutionPolicy",
"animationPolicy",
"multipagePolicy",
"transparencyPolicy",
"colorPolicy",
"svgPolicy",
"unsupportedPolicy",
"helpUrl"
],
"additionalProperties": false
},
"aspectRatio": {
"type": "string"
},
"cropRules": {
"type": "string"
},
"priceMode": {
"type": "string",
"const": "quote_required"
}
},
"required": [
"widthInches",
"heightInches",
"landscapePixels",
"portraitPixels",
"recommendedDpi",
"minimumDpi",
"colorSpace",
"outputFormat",
"maxFileBytes",
"maxInputPixels",
"acceptedMimeTypes",
"acceptedExtensions",
"imageHandling",
"aspectRatio",
"cropRules",
"priceMode"
],
"additionalProperties": false
}
},
"required": [
"id",
"title",
"countries",
"maxPhotos",
"maxPrints",
"specs"
],
"additionalProperties": false
},
"products": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"productCode": {
"type": "string",
"pattern": "^PPA[A-F0-9]{12}$"
},
"sku": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"unitPriceCents": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
{
"type": "null"
}
],
"description": "Integer USD cents"
},
"category": {
"type": "string"
},
"finish": {
"type": "string"
},
"size": {
"type": "string"
},
"widthInches": {
"type": "number"
},
"heightInches": {
"type": "number"
},
"artwork": {
"type": "object",
"properties": {
"qualityGuidance": {
"type": "object",
"properties": {
"recommendedDpi": {
"type": "number"
},
"minimumDpiIsRejectionThreshold": {
"type": "boolean"
},
"fitModes": {
"type": "array",
"items": {
"type": "string"
}
},
"fitDescription": {
"type": "string"
}
},
"required": [
"recommendedDpi",
"minimumDpiIsRejectionThreshold",
"fitModes",
"fitDescription"
],
"additionalProperties": false
},
"widthPixels": {
"type": "integer"
},
"heightPixels": {
"type": "integer"
},
"minImages": {
"type": "integer"
},
"maxImages": {
"type": "integer"
},
"minimumDpi": {
"type": "number"
},
"allowRotate": {
"type": "boolean"
},
"labels": {
"type": "array",
"items": {
"type": "string"
}
},
"bleed": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"issues": {
"type": "array",
"items": {
"type": "string"
}
},
"calendar": {
"type": "object",
"properties": {
"layout": {
"type": "string",
"const": "alternating-photo-grid"
},
"months": {
"type": "number",
"enum": [
12,
18
]
}
},
"required": [
"layout",
"months"
],
"additionalProperties": false
},
"composition": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
},
"background": {
"type": "string"
},
"slots": {
"type": "array",
"items": {
"type": "object",
"properties": {
"x": {
"type": "integer"
},
"y": {
"type": "integer"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
}
},
"required": [
"x",
"y",
"width",
"height"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"width",
"height",
"background",
"slots"
],
"additionalProperties": false
}
},
"required": [
"widthPixels",
"heightPixels",
"minImages",
"maxImages",
"minimumDpi",
"allowRotate",
"labels",
"bleed",
"issues"
],
"additionalProperties": false
},
"shipping": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"provider",
"flat",
"per_item"
]
},
"amountCents": {
"type": "integer",
"minimum": 0,
"maximum": 100000,
"default": 0
},
"multipleItemAmountCents": {
"anyOf": [
{
"$ref": "#/properties/products/items/properties/shipping/properties/amountCents"
},
{
"type": "null"
}
],
"default": null
}
},
"required": [
"mode"
],
"additionalProperties": false
},
"adminOnly": {
"type": "boolean"
},
"available": {
"type": "boolean"
},
"unavailableReason": {
"type": "string"
},
"preview": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"id",
"title",
"description",
"widthInches",
"heightInches"
],
"additionalProperties": true
}
},
"catalogProducts": {
"type": "array",
"items": {
"$ref": "#/properties/products/items"
}
},
"orderingAvailable": {
"type": "boolean"
},
"googleEnabled": {
"type": "boolean"
},
"xEnabled": {
"type": "boolean"
},
"x402Available": {
"type": "boolean"
},
"paymentNetwork": {
"type": "string"
},
"solanaAvailable": {
"type": "boolean"
},
"x402PayTo": {
"type": [
"string",
"null"
]
},
"support": {
"type": "string"
},
"deliveryEstimate": {
"type": "string"
},
"total": {
"type": "number"
},
"nextOffset": {
"type": [
"number",
"null"
]
},
"capabilities": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"supported": {
"type": "boolean"
},
"availableToOrder": {
"type": "boolean"
},
"productCount": {
"type": "number"
}
},
"required": [
"supported",
"availableToOrder",
"productCount"
],
"additionalProperties": false
}
},
"priceFilterBasis": {
"type": "string"
}
},
"required": [
"product",
"orderingAvailable",
"googleEnabled",
"xEnabled",
"x402Available",
"paymentNetwork",
"solanaAvailable",
"x402PayTo",
"support"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "list_products",
"arguments": {}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"products\":[{\"id\":\"photo-4x6\",\"productCode\":\"PPA5B2F748CE094\",\"sku\":\"PPA5B2F748CE094\",\"title\":\"Classic 4 × 6 photo prints\",\"description\":\"Your photos printed for home delivery.\",\"widthInches\":6,\"heightInches\":4}],\"product\":{\"id\":\"photo-4x6\",\"productCode\":\"PPA5B2F748CE094\",\"sku\":\"PPA5B2F748CE094\",\"title\":\"4 × 6 inch photo prints\",\"countries\":[\"US\"],\"maxPhotos\":50,\"maxPrints\":500,\"specs\":{\"widthInches\":6,\"heightInches\":4,\"landscapePixels\":[1800,1200],\"portraitPixels\":[1200,1800],\"recommendedDpi\":300,\"minimumDpi\":0,\"colorSpace\":\"sRGB\",\"outputFormat\":\"image/jpeg\",\"maxFileBytes\":15728640,\"maxInputPixels\":150000000,\"acceptedMimeTypes\":[\"image/jpeg\",\"image/jpg\",\"image/pjpeg\",\"image/png\",\"image/apng\",\"image/webp\",\"image/gif\",\"image/heic\",\"image/heif\",\"image/heic-sequence\",\"image/heif-sequence\",\"image/tiff\",\"image/x-tiff\",\"image/avif\",\"image/avif-sequence\",\"image/bmp\",\"image/x-bmp\",\"image/x-ms-bmp\",\"image/svg+xml\"],\"acceptedExtensions\":[\".jpg\",\".jpeg\",\".jpe\",\".jfif\",\".png\",\".apng\",\".webp\",\".gif\",\".heic\",\".heif\",\".hif\",\".tif\",\".tiff\",\".avif\",\".bmp\",\".svg\",\".svgz\"],\"imageHandling\":{\"resolutionPolicy\":\"JPEG, PNG and TIFF: up to 150 megapixels; other formats: up to 24 megapixels. Maximum edge: 24,000 pixels. Files: up to 15 MB.\",\"animationPolicy\":\"Print the first frame only; APNG uses its default still image.\",\"multipagePolicy\":\"Print the first TIFF page; HEIC/HEIF uses the primary image, falling back to the first.\",\"transparencyPolicy\":\"Composite transparency on white.\",\"colorPolicy\":\"Convert to an 8-bit sRGB JPEG and strip metadata. HDR and wide-gamut appearance may change.\",\"svgPolicy\":\"Self-contained SVG only; no scripts, external resources, embedded images, or stylesheets.\",\"unsupportedPolicy\":\"PDF, camera RAW, PSD, JPEG XL, JPEG 2000, and other unsupported encodings must be exported to a supported format first.\",\"helpUrl\":\"https://photoprintagent.com/help\"},\"aspectRatio\":\"3:2 landscape or 2:3 portrait\",\"cropRules\":\"Only a still image is printed. Transparency is composited on white. cover crops at x/y percent (default center); contain adds white borders. Low-resolution images are accepted and resized with ordinary interpolation; quality may be reduced. No AI enhancement is applied. EXIF orientation is applied. Metadata is stripped.\",\"priceMode\":\"quote_required\"}},\"orderingAvailable\":true,\"googleEnabled\":true,\"xEnabled\":false,\"x402Available\":true,\"paymentNetwork\":\"Base and Solana\",\"solanaAvailable\":false,\"x402PayTo\":\"0x1111111111111111111111111111111111111111\",\"support\":\"support@photoprintagent.com\"}"
}
],
"structuredContent": {
"products": [
{
"id": "photo-4x6",
"productCode": "PPA5B2F748CE094",
"sku": "PPA5B2F748CE094",
"title": "Classic 4 × 6 photo prints",
"description": "Your photos printed for home delivery.",
"widthInches": 6,
"heightInches": 4
}
],
"product": {
"id": "photo-4x6",
"productCode": "PPA5B2F748CE094",
"sku": "PPA5B2F748CE094",
"title": "4 × 6 inch photo prints",
"countries": [
"US"
],
"maxPhotos": 50,
"maxPrints": 500,
"specs": {
"widthInches": 6,
"heightInches": 4,
"landscapePixels": [
1800,
1200
],
"portraitPixels": [
1200,
1800
],
"recommendedDpi": 300,
"minimumDpi": 0,
"colorSpace": "sRGB",
"outputFormat": "image/jpeg",
"maxFileBytes": 15728640,
"maxInputPixels": 150000000,
"acceptedMimeTypes": [
"image/jpeg",
"image/jpg",
"image/pjpeg",
"image/png",
"image/apng",
"image/webp",
"image/gif",
"image/heic",
"image/heif",
"image/heic-sequence",
"image/heif-sequence",
"image/tiff",
"image/x-tiff",
"image/avif",
"image/avif-sequence",
"image/bmp",
"image/x-bmp",
"image/x-ms-bmp",
"image/svg+xml"
],
"acceptedExtensions": [
".jpg",
".jpeg",
".jpe",
".jfif",
".png",
".apng",
".webp",
".gif",
".heic",
".heif",
".hif",
".tif",
".tiff",
".avif",
".bmp",
".svg",
".svgz"
],
"imageHandling": {
"resolutionPolicy": "JPEG, PNG and TIFF: up to 150 megapixels; other formats: up to 24 megapixels. Maximum edge: 24,000 pixels. Files: up to 15 MB.",
"animationPolicy": "Print the first frame only; APNG uses its default still image.",
"multipagePolicy": "Print the first TIFF page; HEIC/HEIF uses the primary image, falling back to the first.",
"transparencyPolicy": "Composite transparency on white.",
"colorPolicy": "Convert to an 8-bit sRGB JPEG and strip metadata. HDR and wide-gamut appearance may change.",
"svgPolicy": "Self-contained SVG only; no scripts, external resources, embedded images, or stylesheets.",
"unsupportedPolicy": "PDF, camera RAW, PSD, JPEG XL, JPEG 2000, and other unsupported encodings must be exported to a supported format first.",
"helpUrl": "https://photoprintagent.com/help"
},
"aspectRatio": "3:2 landscape or 2:3 portrait",
"cropRules": "Only a still image is printed. Transparency is composited on white. cover crops at x/y percent (default center); contain adds white borders. Low-resolution images are accepted and resized with ordinary interpolation; quality may be reduced. No AI enhancement is applied. EXIF orientation is applied. Metadata is stripped.",
"priceMode": "quote_required"
}
},
"orderingAvailable": true,
"googleEnabled": true,
"xEnabled": false,
"x402Available": true,
"paymentNetwork": "Base and Solana",
"solanaAvailable": false,
"x402PayTo": "0x1111111111111111111111111111111111111111",
"support": "support@photoprintagent.com"
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":503,\"message\":\"Service temporarily unavailable.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 503,
"message": "Service temporarily unavailable."
}
},
"isError": true
}
}
start_guest_checkout
Public: mint a private guest credential once. No account, payment or print is created. Save it in a secret store.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"token": {
"type": "string"
},
"guestApiKey": {
"type": "string"
},
"checkoutUntil": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"expiresAt": {
"$ref": "#/properties/checkoutUntil"
},
"tokenType": {
"type": "string",
"const": "Bearer"
},
"instructions": {
"type": "string"
}
},
"required": [
"token",
"guestApiKey",
"checkoutUntil",
"expiresAt",
"tokenType",
"instructions"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "start_guest_checkout",
"arguments": {}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"token\":\"ppg_0000000000000000000000000000000000000000000000000000000000000000\",\"guestApiKey\":\"ppg_0000000000000000000000000000000000000000000000000000000000000000\",\"checkoutUntil\":1893542400000,\"expiresAt\":1896048000000,\"tokenType\":\"Bearer\",\"instructions\":\"Keep this private guest token. Use it as Authorization: Bearer on API/MCP requests, or as guestToken in MCP tools. Create checkouts within 24 hours; order access lasts 30 days. No account is created.\"}"
}
],
"structuredContent": {
"token": "ppg_0000000000000000000000000000000000000000000000000000000000000000",
"guestApiKey": "ppg_0000000000000000000000000000000000000000000000000000000000000000",
"checkoutUntil": 1893542400000,
"expiresAt": 1896048000000,
"tokenType": "Bearer",
"instructions": "Keep this private guest token. Use it as Authorization: Bearer on API/MCP requests, or as guestToken in MCP tools. Create checkouts within 24 hours; order access lasts 30 days. No account is created."
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":400,\"message\":\"You already have checkout access. Use the existing credential.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 400,
"message": "You already have checkout access. Use the existing credential."
}
},
"isError": true
}
}
create_upload
Get the authenticated binary upload endpoint and product/crop headers. Pass productId from list_products for every image. Upload each required image separately; retain the returned IDs in slot order. Crops and resolution checks use that product’s artwork specifications, not a universal 4x6 size. POST the image bytes separately; never put base64 or remote image URLs in MCP. For recoverable uploads, send a stable Idempotency-Key on POST and check GET /api/uploads/{key} after a lost response. Retry the same bytes and options with the same key; never retry payment as an upload recovery step. SDK: https://photoprintagent.com/sdk/photo-upload.mjs. No storage is allocated until upload. JPEG, PNG/APNG, WebP, GIF, HEIC/HEIF, TIFF, AVIF, BMP and self-contained SVG are supported. Read acceptedMimeTypes, acceptedExtensions and imageHandling for frame/page selection, transparency, and limits. Use application/octet-stream when MIME type is unavailable. Unsupported encodings must be converted before upload.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {
"productId": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{1,63}$"
},
"crop": {
"type": "object",
"properties": {
"fit": {
"type": "string",
"enum": [
"cover",
"contain"
],
"default": "cover"
},
"orientation": {
"type": "string",
"enum": [
"landscape",
"portrait"
],
"default": "landscape"
},
"x": {
"type": "number",
"minimum": 0,
"maximum": 100,
"default": 50
},
"y": {
"type": "number",
"minimum": 0,
"maximum": 100,
"default": 50
}
},
"additionalProperties": false
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"uploadUrl": {
"type": "string",
"format": "uri"
},
"method": {
"type": "string",
"const": "POST"
},
"authorization": {
"type": "string",
"const": "Bearer: use your existing account or guest credential"
},
"headers": {
"type": "object",
"properties": {
"X-Photo-Options": {
"type": "string"
},
"X-Product-Id": {
"type": "string"
}
},
"required": [
"X-Photo-Options"
],
"additionalProperties": false
},
"acceptedMimeTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"acceptedExtensions": {
"type": "array",
"items": {
"type": "string"
}
},
"imageHandling": {
"type": "object",
"properties": {
"resolutionPolicy": {
"type": "string"
},
"animationPolicy": {
"type": "string"
},
"multipagePolicy": {
"type": "string"
},
"transparencyPolicy": {
"type": "string"
},
"colorPolicy": {
"type": "string"
},
"svgPolicy": {
"type": "string"
},
"unsupportedPolicy": {
"type": "string"
},
"helpUrl": {
"type": "string"
}
},
"required": [
"resolutionPolicy",
"animationPolicy",
"multipagePolicy",
"transparencyPolicy",
"colorPolicy",
"svgPolicy",
"unsupportedPolicy",
"helpUrl"
],
"additionalProperties": false
},
"maxFileBytes": {
"type": "integer"
},
"maxInputPixels": {
"type": "integer"
},
"helpUrl": {
"type": "string",
"format": "uri"
},
"responseSchemaUrl": {
"type": "string",
"format": "uri"
},
"artwork": {
"type": "object",
"properties": {
"qualityGuidance": {
"type": "object",
"properties": {
"recommendedDpi": {
"type": "number"
},
"minimumDpiIsRejectionThreshold": {
"type": "boolean"
},
"fitModes": {
"type": "array",
"items": {
"type": "string"
}
},
"fitDescription": {
"type": "string"
}
},
"required": [
"recommendedDpi",
"minimumDpiIsRejectionThreshold",
"fitModes",
"fitDescription"
],
"additionalProperties": false
},
"widthPixels": {
"type": "integer"
},
"heightPixels": {
"type": "integer"
},
"minImages": {
"type": "integer"
},
"maxImages": {
"type": "integer"
},
"minimumDpi": {
"type": "number"
},
"allowRotate": {
"type": "boolean"
},
"labels": {
"type": "array",
"items": {
"type": "string"
}
},
"bleed": {
"type": "object",
"additionalProperties": {
"type": "number"
}
},
"issues": {
"type": "array",
"items": {
"type": "string"
}
},
"calendar": {
"type": "object",
"properties": {
"layout": {
"type": "string",
"const": "alternating-photo-grid"
},
"months": {
"type": "number",
"enum": [
12,
18
]
}
},
"required": [
"layout",
"months"
],
"additionalProperties": false
},
"composition": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
},
"background": {
"type": "string"
},
"slots": {
"type": "array",
"items": {
"type": "object",
"properties": {
"x": {
"type": "integer"
},
"y": {
"type": "integer"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
}
},
"required": [
"x",
"y",
"width",
"height"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"width",
"height",
"background",
"slots"
],
"additionalProperties": false
}
},
"required": [
"widthPixels",
"heightPixels",
"minImages",
"maxImages",
"minimumDpi",
"allowRotate",
"labels",
"bleed",
"issues"
],
"additionalProperties": false
}
},
"required": [
"uploadUrl",
"method",
"authorization",
"headers",
"acceptedMimeTypes",
"acceptedExtensions",
"imageHandling",
"maxFileBytes",
"maxInputPixels",
"helpUrl",
"responseSchemaUrl"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "create_upload",
"arguments": {
"crop": {
"fit": "cover",
"orientation": "landscape",
"x": 50,
"y": 50
}
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"uploadUrl\":\"https://photoprintagent.com/api/photos\",\"method\":\"POST\",\"authorization\":\"Bearer: use your existing account or guest credential\",\"headers\":{\"X-Photo-Options\":\"{\\\"fit\\\":\\\"cover\\\",\\\"orientation\\\":\\\"landscape\\\",\\\"x\\\":50,\\\"y\\\":50}\"},\"acceptedMimeTypes\":[\"image/jpeg\",\"image/jpg\",\"image/pjpeg\",\"image/png\",\"image/apng\",\"image/webp\",\"image/gif\",\"image/heic\",\"image/heif\",\"image/heic-sequence\",\"image/heif-sequence\",\"image/tiff\",\"image/x-tiff\",\"image/avif\",\"image/avif-sequence\",\"image/bmp\",\"image/x-bmp\",\"image/x-ms-bmp\",\"image/svg+xml\"],\"acceptedExtensions\":[\".jpg\",\".jpeg\",\".jpe\",\".jfif\",\".png\",\".apng\",\".webp\",\".gif\",\".heic\",\".heif\",\".hif\",\".tif\",\".tiff\",\".avif\",\".bmp\",\".svg\",\".svgz\"],\"imageHandling\":{\"resolutionPolicy\":\"JPEG, PNG and TIFF: up to 150 megapixels; other formats: up to 24 megapixels. Maximum edge: 24,000 pixels. Files: up to 15 MB.\",\"animationPolicy\":\"Print the first frame only; APNG uses its default still image.\",\"multipagePolicy\":\"Print the first TIFF page; HEIC/HEIF uses the primary image, falling back to the first.\",\"transparencyPolicy\":\"Composite transparency on white.\",\"colorPolicy\":\"Convert to an 8-bit sRGB JPEG and strip metadata. HDR and wide-gamut appearance may change.\",\"svgPolicy\":\"Self-contained SVG only; no scripts, external resources, embedded images, or stylesheets.\",\"unsupportedPolicy\":\"PDF, camera RAW, PSD, JPEG XL, JPEG 2000, and other unsupported encodings must be exported to a supported format first.\",\"helpUrl\":\"https://photoprintagent.com/help\"},\"helpUrl\":\"https://photoprintagent.com/help\",\"maxFileBytes\":15728640,\"maxInputPixels\":150000000,\"responseSchemaUrl\":\"https://photoprintagent.com/docs/mcp.json#/uploadResponseSchema\"}"
}
],
"structuredContent": {
"uploadUrl": "https://photoprintagent.com/api/photos",
"method": "POST",
"authorization": "Bearer: use your existing account or guest credential",
"headers": {
"X-Photo-Options": "{\"fit\":\"cover\",\"orientation\":\"landscape\",\"x\":50,\"y\":50}"
},
"acceptedMimeTypes": [
"image/jpeg",
"image/jpg",
"image/pjpeg",
"image/png",
"image/apng",
"image/webp",
"image/gif",
"image/heic",
"image/heif",
"image/heic-sequence",
"image/heif-sequence",
"image/tiff",
"image/x-tiff",
"image/avif",
"image/avif-sequence",
"image/bmp",
"image/x-bmp",
"image/x-ms-bmp",
"image/svg+xml"
],
"acceptedExtensions": [
".jpg",
".jpeg",
".jpe",
".jfif",
".png",
".apng",
".webp",
".gif",
".heic",
".heif",
".hif",
".tif",
".tiff",
".avif",
".bmp",
".svg",
".svgz"
],
"imageHandling": {
"resolutionPolicy": "JPEG, PNG and TIFF: up to 150 megapixels; other formats: up to 24 megapixels. Maximum edge: 24,000 pixels. Files: up to 15 MB.",
"animationPolicy": "Print the first frame only; APNG uses its default still image.",
"multipagePolicy": "Print the first TIFF page; HEIC/HEIF uses the primary image, falling back to the first.",
"transparencyPolicy": "Composite transparency on white.",
"colorPolicy": "Convert to an 8-bit sRGB JPEG and strip metadata. HDR and wide-gamut appearance may change.",
"svgPolicy": "Self-contained SVG only; no scripts, external resources, embedded images, or stylesheets.",
"unsupportedPolicy": "PDF, camera RAW, PSD, JPEG XL, JPEG 2000, and other unsupported encodings must be exported to a supported format first.",
"helpUrl": "https://photoprintagent.com/help"
},
"helpUrl": "https://photoprintagent.com/help",
"maxFileBytes": 15728640,
"maxInputPixels": 150000000,
"responseSchemaUrl": "https://photoprintagent.com/docs/mcp.json#/uploadResponseSchema"
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":401,\"message\":\"Call start_guest_checkout and provide guestToken, or use a Bearer credential. No account is required.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 401,
"message": "Call start_guest_checkout and provide guestToken, or use a Bearer credential. No account is required."
}
},
"isError": true
}
}
quote_prints
Quote private uploaded photo IDs and a US destination for an optional productId from list_products (defaults to photo-4x6). Items may specify productId to mix products using the same print service; omitted item productId uses the order productId. For a single image use items:[{photoId,productId,quantity}]. For a multi-image design use items:[{photoIds:[frontId,backId,...],quantity}]; array order is print order and quantity counts complete products, not individual images. Follow artwork.minImages/maxImages and labels. For artwork.calendar, upload a cover plus one photo per month and include calendar:{startYear,startMonth} on the item; the server generates and interleaves the date grids. Do not upload date grids. For artwork.composition, upload each source photo at the per-image dimensions; the server assembles the ordered photos into the single print file shown by the layout. Never precompose those photos or send each side as a separate item. Up to 200 uploaded images and 500 product units per order. Shipping follows the product’s configured pricing; flat rates can differ for 1 versus 2+ prints. Use the returned shipping and total; never multiply flat shipping by quantity. Requires consent for PhotoPrintAgent to process these photos and address for printing and delivery. Unique photos, at most 500 total prints. Optional couponCode is validated here; price.total is the discounted buyer amount and price.discount is the savings in USD cents.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"productId": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{1,63}$"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"calendar": {
"type": "object",
"properties": {
"startYear": {
"type": "integer",
"minimum": 2000,
"maximum": 2100
},
"startMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
}
},
"required": [
"startYear",
"startMonth"
],
"additionalProperties": false
},
"productId": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{1,63}$"
},
"photoId": {
"type": "string",
"format": "uuid"
},
"photoIds": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"minItems": 1,
"maxItems": 200
},
"quantity": {
"type": "integer",
"minimum": 1,
"maximum": 99
}
},
"required": [
"quantity"
],
"additionalProperties": false
},
"minItems": 1,
"maxItems": 50
},
"shipping": {
"type": "object",
"properties": {
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 150
},
"lastName": {
"$ref": "#/properties/shipping/properties/firstName"
},
"email": {
"type": "string",
"format": "email",
"maxLength": 254
},
"phone": {
"type": "string"
},
"line1": {
"$ref": "#/properties/shipping/properties/firstName"
},
"line2": {
"type": "string",
"maxLength": 150,
"default": ""
},
"city": {
"$ref": "#/properties/shipping/properties/firstName"
},
"state": {
"type": "string",
"pattern": "^[A-Z]{2}$"
},
"zip": {
"type": "string",
"pattern": "^\\d{5}(-\\d{4})?$"
},
"country": {
"type": "string",
"const": "US"
}
},
"required": [
"firstName",
"lastName",
"email",
"phone",
"line1",
"city",
"state",
"zip",
"country"
],
"additionalProperties": false
},
"consent": {
"type": "boolean",
"const": true
},
"couponCode": {
"type": "string",
"maxLength": 64
},
"campaignId": {
"type": "string",
"pattern": "^[a-f0-9]{16}$"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"items",
"shipping",
"consent"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"price": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"const": "USD"
},
"subtotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"shipping": {
"$ref": "#/properties/price/properties/subtotal"
},
"tax": {
"$ref": "#/properties/price/properties/subtotal"
},
"total": {
"$ref": "#/properties/price/properties/subtotal"
},
"originalTotal": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"discount": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"coupon": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"printDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"shippingDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"taxCredit": {
"$ref": "#/properties/price/properties/subtotal"
}
},
"required": [
"code",
"name",
"printDiscount",
"shippingDiscount",
"taxCredit"
],
"additionalProperties": false
}
},
"required": [
"currency",
"subtotal",
"shipping",
"tax",
"total"
],
"additionalProperties": false
},
"validUntil": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"expiresAt": {
"$ref": "#/properties/validUntil"
},
"lineItems": {
"type": "array",
"items": {
"type": "object",
"properties": {
"photoId": {
"type": "string",
"format": "uuid"
},
"photoIds": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"productId": {
"type": "string"
},
"quantity": {
"type": "integer"
},
"calendar": {
"type": "object",
"properties": {
"startYear": {
"type": "integer",
"minimum": 2000,
"maximum": 2100
},
"startMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
}
},
"required": [
"startYear",
"startMonth"
],
"additionalProperties": false
}
},
"required": [
"productId",
"quantity"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"price",
"validUntil",
"expiresAt",
"lineItems"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "quote_prints",
"arguments": {
"items": [
{
"photoId": "22222222-2222-4222-8222-222222222222",
"quantity": 2
}
],
"shipping": {
"firstName": "Jane",
"lastName": "Buyer",
"email": "jane@example.com",
"phone": "2125550100",
"line1": "123 Example Street",
"line2": "Suite 2R",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
},
"consent": true
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"id\":\"33333333-3333-4333-8333-333333333333\",\"price\":{\"currency\":\"USD\",\"subtotal\":100,\"shipping\":400,\"tax\":50,\"total\":550},\"validUntil\":1893456900000,\"expiresAt\":1893456900000,\"lineItems\":[{\"photoId\":\"22222222-2222-4222-8222-222222222222\",\"quantity\":2,\"productId\":\"photo-4x6\"}]}"
}
],
"structuredContent": {
"id": "33333333-3333-4333-8333-333333333333",
"price": {
"currency": "USD",
"subtotal": 100,
"shipping": 400,
"tax": 50,
"total": 550
},
"validUntil": 1893456900000,
"expiresAt": 1893456900000,
"lineItems": [
{
"photoId": "22222222-2222-4222-8222-222222222222",
"quantity": 2,
"productId": "photo-4x6"
}
]
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":400,\"message\":\"Check your photos, quantities, and delivery details.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 400,
"message": "Check your photos, quantities, and delivery details."
}
},
"isError": true
}
}
create_print_order
Create one order from the approved quote, which already contains buyer contact and address. Requires termsAccepted:true confirming acceptance of https://photoprintagent.com/terms with the buyer’s authorization, separately from buyerApproved:true. Never infer acceptance from an upload, quote, or previous order. Reuse the same idempotency key for retries. Returns a buyer card checkout URL or x402 payment URL; call pay_print_order for the challenge. A zero-total coupon order is submitted with buyerApproved:true and needs no card or wallet. Optional couponCode must match the approved quote.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"quoteId": {
"type": "string",
"format": "uuid"
},
"couponCode": {
"type": "string",
"maxLength": 64
},
"idempotencyKey": {
"type": "string",
"pattern": "^[-\\w]{16,100}$"
},
"buyerApproved": {
"type": "boolean",
"const": true
},
"termsAccepted": {
"type": "boolean",
"const": true,
"description": "Required explicit acceptance of https://photoprintagent.com/terms for this order, with buyer authorization. Missing or false acceptance is rejected."
},
"method": {
"type": "string",
"enum": [
"card",
"x402"
],
"default": "x402"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"quoteId",
"idempotencyKey",
"buyerApproved",
"termsAccepted"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"order": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"status": {
"type": "string",
"enum": [
"creating_checkout",
"awaiting_payment",
"verifying_payment",
"settling_payment",
"paid",
"submitting",
"processing",
"needs_review",
"expired"
]
},
"method": {
"type": "string",
"enum": [
"card",
"x402"
]
},
"price": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"const": "USD"
},
"subtotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"shipping": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"tax": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"total": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"originalTotal": {
"$ref": "#/properties/order/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"discount": {
"$ref": "#/properties/order/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"coupon": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"printDiscount": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"shippingDiscount": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"taxCredit": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
}
},
"required": [
"code",
"name",
"printDiscount",
"shippingDiscount",
"taxCredit"
],
"additionalProperties": false
}
},
"required": [
"currency",
"subtotal",
"shipping",
"tax",
"total"
],
"additionalProperties": false
},
"pricingVersion": {
"type": "integer",
"minimum": 0
},
"paymentDeadline": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"canEditCoupon": {
"type": "boolean"
},
"canRenewCheckout": {
"type": "boolean"
},
"cardPaymentUrl": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"cardProcessor": {
"anyOf": [
{
"type": "string",
"enum": [
"square",
"stripe"
]
},
{
"type": "null"
}
]
},
"quantity": {
"type": "integer"
},
"progress": {
"type": "object",
"properties": {
"productionStatus": {
"type": "string",
"enum": [
"not_submitted",
"queued",
"submitting",
"accepted",
"printing",
"shipped",
"delivered",
"cancelled",
"on_hold",
"needs_review",
"unknown"
]
},
"shipmentStatus": {
"type": "string",
"enum": [
"unknown",
"shipped",
"delivered"
]
},
"lastUpdatedAt": {
"type": [
"number",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"supportStatus": {
"type": "string",
"enum": [
"none",
"open",
"waiting_customer",
"under_review",
"resolved"
]
},
"canRequestCancellation": {
"type": "boolean"
},
"canRequestChange": {
"type": "boolean"
},
"canRequestRefund": {
"type": "boolean"
},
"cancellationGuaranteed": {
"type": "boolean",
"const": false
}
},
"required": [
"productionStatus",
"shipmentStatus",
"lastUpdatedAt",
"trackingUrls",
"supportStatus",
"canRequestCancellation",
"canRequestChange",
"canRequestRefund",
"cancellationGuaranteed"
],
"additionalProperties": false
},
"productName": {
"type": "string"
},
"imageCount": {
"type": "integer"
},
"createdAt": {
"$ref": "#/properties/order/properties/paymentDeadline"
},
"paidAt": {
"anyOf": [
{
"$ref": "#/properties/order/properties/paymentDeadline"
},
{
"type": "null"
}
],
"description": "Unix time in milliseconds"
},
"paymentStatus": {
"type": "string",
"enum": [
"unpaid",
"pending",
"paid",
"refunded",
"not_required",
"needs_review",
"expired"
]
},
"fulfillmentStatus": {
"type": "string",
"enum": [
"not_submitted",
"submitting",
"accepted",
"needs_review"
]
},
"cryptoPayment": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"rankId": {
"type": "string"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string"
},
"asset": {
"type": "string"
},
"decimals": {
"type": "integer"
},
"transferMethod": {
"type": "string",
"enum": [
"eip3009",
"permit2",
"spl"
]
},
"network": {
"type": "string"
},
"tokenProgram": {
"type": "string"
},
"rank": {
"type": [
"number",
"null"
]
},
"wrapped": {
"type": "boolean"
},
"stable": {
"type": "boolean"
},
"availability": {
"type": "string",
"enum": [
"quote_required",
"receiving_ready"
]
},
"priceChecked": {
"type": "boolean"
},
"tokenId": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^\\d+$"
},
"displayAmount": {
"type": "string"
},
"usdTotal": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"usdPrice": {
"type": "string"
},
"priceAsOf": {
"$ref": "#/properties/order/properties/paymentDeadline"
},
"source": {
"type": "string"
},
"payTo": {
"type": "string"
},
"quotedAt": {
"$ref": "#/properties/order/properties/paymentDeadline"
},
"validUntil": {
"$ref": "#/properties/order/properties/paymentDeadline"
}
},
"required": [
"id",
"rankId",
"name",
"symbol",
"asset",
"decimals",
"transferMethod",
"network",
"tokenId",
"amount",
"displayAmount",
"usdTotal",
"usdPrice",
"priceAsOf",
"source",
"payTo",
"quotedAt",
"validUntil"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"transaction": {
"type": [
"string",
"null"
]
},
"network": {
"type": [
"string",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
},
"message": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"status",
"method",
"price",
"pricingVersion",
"paymentDeadline",
"canEditCoupon",
"quantity",
"createdAt",
"paidAt",
"paymentStatus",
"fulfillmentStatus",
"cryptoPayment",
"transaction",
"network",
"trackingUrls",
"message"
],
"additionalProperties": false
},
"paymentUrl": {
"type": "string"
},
"checkoutUrl": {
"type": "string",
"format": "uri"
}
},
"required": [
"order",
"checkoutUrl"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "create_print_order",
"arguments": {
"quoteId": "33333333-3333-4333-8333-333333333333",
"idempotencyKey": "44444444-4444-4444-8444-444444444444",
"buyerApproved": true,
"termsAccepted": true,
"method": "x402"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"order\":{\"id\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"status\":\"awaiting_payment\",\"method\":\"x402\",\"price\":{\"currency\":\"USD\",\"subtotal\":100,\"shipping\":400,\"tax\":50,\"total\":550},\"pricingVersion\":0,\"paymentDeadline\":1893542400000,\"canEditCoupon\":true,\"quantity\":2,\"createdAt\":1893456000000,\"paidAt\":null,\"paymentStatus\":\"unpaid\",\"fulfillmentStatus\":\"not_submitted\",\"cryptoPayment\":null,\"transaction\":null,\"network\":null,\"trackingUrls\":[],\"message\":null},\"paymentUrl\":\"/api/orders/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/pay\",\"checkoutUrl\":\"https://photoprintagent.com/checkout/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#access=ppc_0000000000000000000000000000000000000000000000000000000000000000\"}"
}
],
"structuredContent": {
"order": {
"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"status": "awaiting_payment",
"method": "x402",
"price": {
"currency": "USD",
"subtotal": 100,
"shipping": 400,
"tax": 50,
"total": 550
},
"pricingVersion": 0,
"paymentDeadline": 1893542400000,
"canEditCoupon": true,
"quantity": 2,
"createdAt": 1893456000000,
"paidAt": null,
"paymentStatus": "unpaid",
"fulfillmentStatus": "not_submitted",
"cryptoPayment": null,
"transaction": null,
"network": null,
"trackingUrls": [],
"message": null
},
"paymentUrl": "/api/orders/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/pay",
"checkoutUrl": "https://photoprintagent.com/checkout/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#access=ppc_0000000000000000000000000000000000000000000000000000000000000000"
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":409,\"message\":\"Refresh your quote before checking out.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 409,
"message": "Refresh your quote before checking out."
}
},
"isError": true
}
}
pay_print_order
Request an x402 v2 challenge without a signature, or settle an approved signature and submit the paid print. Uses the same guarded payment flow as REST. An unsigned call returns payment_required in structuredContent (MCP HTTP 200). Never repay an ambiguous order.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"cryptoQuoteId": {
"type": "string",
"format": "uuid"
},
"paymentSignature": {
"type": "string",
"minLength": 1,
"maxLength": 64000,
"description": "Base64-encoded x402 v2 payload, same value as PAYMENT-SIGNATURE; never provide both."
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"payment_required",
"order_status"
]
},
"httpStatus": {
"type": "number",
"enum": [
200,
402
]
},
"payment_required": {
"type": "object",
"properties": {
"x402Version": {
"type": "number",
"const": 2
},
"resource": {
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"description": {
"type": "string"
},
"mimeType": {
"type": "string"
}
},
"required": [
"url"
],
"additionalProperties": false
},
"accepts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"scheme": {
"type": "string",
"const": "exact"
},
"network": {
"type": "string"
},
"asset": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^\\d+$"
},
"payTo": {
"type": "string"
},
"maxTimeoutSeconds": {
"type": "integer"
},
"extra": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"scheme",
"network",
"asset",
"amount",
"payTo",
"maxTimeoutSeconds"
],
"additionalProperties": false
}
},
"error": {
"type": "string"
},
"extensions": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"x402Version",
"resource",
"accepts"
],
"additionalProperties": false
},
"paymentRequiredHeader": {
"type": "string"
},
"order": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"status": {
"type": "string",
"enum": [
"creating_checkout",
"awaiting_payment",
"verifying_payment",
"settling_payment",
"paid",
"submitting",
"processing",
"needs_review",
"expired"
]
},
"method": {
"type": "string",
"enum": [
"card",
"x402"
]
},
"price": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"const": "USD"
},
"subtotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"shipping": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"tax": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"total": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"originalTotal": {
"$ref": "#/properties/order/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"discount": {
"$ref": "#/properties/order/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"coupon": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"printDiscount": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"shippingDiscount": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"taxCredit": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
}
},
"required": [
"code",
"name",
"printDiscount",
"shippingDiscount",
"taxCredit"
],
"additionalProperties": false
}
},
"required": [
"currency",
"subtotal",
"shipping",
"tax",
"total"
],
"additionalProperties": false
},
"pricingVersion": {
"type": "integer",
"minimum": 0
},
"paymentDeadline": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"canEditCoupon": {
"type": "boolean"
},
"canRenewCheckout": {
"type": "boolean"
},
"cardPaymentUrl": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"cardProcessor": {
"anyOf": [
{
"type": "string",
"enum": [
"square",
"stripe"
]
},
{
"type": "null"
}
]
},
"quantity": {
"type": "integer"
},
"progress": {
"type": "object",
"properties": {
"productionStatus": {
"type": "string",
"enum": [
"not_submitted",
"queued",
"submitting",
"accepted",
"printing",
"shipped",
"delivered",
"cancelled",
"on_hold",
"needs_review",
"unknown"
]
},
"shipmentStatus": {
"type": "string",
"enum": [
"unknown",
"shipped",
"delivered"
]
},
"lastUpdatedAt": {
"type": [
"number",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"supportStatus": {
"type": "string",
"enum": [
"none",
"open",
"waiting_customer",
"under_review",
"resolved"
]
},
"canRequestCancellation": {
"type": "boolean"
},
"canRequestChange": {
"type": "boolean"
},
"canRequestRefund": {
"type": "boolean"
},
"cancellationGuaranteed": {
"type": "boolean",
"const": false
}
},
"required": [
"productionStatus",
"shipmentStatus",
"lastUpdatedAt",
"trackingUrls",
"supportStatus",
"canRequestCancellation",
"canRequestChange",
"canRequestRefund",
"cancellationGuaranteed"
],
"additionalProperties": false
},
"productName": {
"type": "string"
},
"imageCount": {
"type": "integer"
},
"createdAt": {
"$ref": "#/properties/order/properties/paymentDeadline"
},
"paidAt": {
"anyOf": [
{
"$ref": "#/properties/order/properties/paymentDeadline"
},
{
"type": "null"
}
],
"description": "Unix time in milliseconds"
},
"paymentStatus": {
"type": "string",
"enum": [
"unpaid",
"pending",
"paid",
"refunded",
"not_required",
"needs_review",
"expired"
]
},
"fulfillmentStatus": {
"type": "string",
"enum": [
"not_submitted",
"submitting",
"accepted",
"needs_review"
]
},
"cryptoPayment": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"rankId": {
"type": "string"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string"
},
"asset": {
"type": "string"
},
"decimals": {
"type": "integer"
},
"transferMethod": {
"type": "string",
"enum": [
"eip3009",
"permit2",
"spl"
]
},
"network": {
"type": "string"
},
"tokenProgram": {
"type": "string"
},
"rank": {
"type": [
"number",
"null"
]
},
"wrapped": {
"type": "boolean"
},
"stable": {
"type": "boolean"
},
"availability": {
"type": "string",
"enum": [
"quote_required",
"receiving_ready"
]
},
"priceChecked": {
"type": "boolean"
},
"tokenId": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^\\d+$"
},
"displayAmount": {
"type": "string"
},
"usdTotal": {
"$ref": "#/properties/order/properties/price/properties/subtotal"
},
"usdPrice": {
"type": "string"
},
"priceAsOf": {
"$ref": "#/properties/order/properties/paymentDeadline"
},
"source": {
"type": "string"
},
"payTo": {
"type": "string"
},
"quotedAt": {
"$ref": "#/properties/order/properties/paymentDeadline"
},
"validUntil": {
"$ref": "#/properties/order/properties/paymentDeadline"
}
},
"required": [
"id",
"rankId",
"name",
"symbol",
"asset",
"decimals",
"transferMethod",
"network",
"tokenId",
"amount",
"displayAmount",
"usdTotal",
"usdPrice",
"priceAsOf",
"source",
"payTo",
"quotedAt",
"validUntil"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"transaction": {
"type": [
"string",
"null"
]
},
"network": {
"type": [
"string",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
},
"message": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"status",
"method",
"price",
"pricingVersion",
"paymentDeadline",
"canEditCoupon",
"quantity",
"createdAt",
"paidAt",
"paymentStatus",
"fulfillmentStatus",
"cryptoPayment",
"transaction",
"network",
"trackingUrls",
"message"
],
"additionalProperties": false
},
"paymentResponse": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"transaction": {
"type": "string"
},
"network": {
"type": "string"
},
"payer": {
"type": "string"
},
"errorReason": {
"type": "string"
}
},
"required": [
"success",
"transaction",
"network"
],
"additionalProperties": true
},
"paymentResponseHeader": {
"type": "string"
}
},
"required": [
"status",
"httpStatus"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "pay_print_order",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"status\":\"payment_required\",\"httpStatus\":402,\"payment_required\":{\"x402Version\":2,\"resource\":{\"url\":\"https://photoprintagent.com/api/orders/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/pay\",\"description\":\"4×6 photo print order aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"mimeType\":\"application/json\"},\"accepts\":[{\"scheme\":\"exact\",\"network\":\"eip155:8453\",\"asset\":\"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\"amount\":\"5500000\",\"payTo\":\"0x1111111111111111111111111111111111111111\",\"maxTimeoutSeconds\":300,\"extra\":{\"name\":\"USD Coin\",\"version\":\"2\"}}]},\"paymentRequiredHeader\":\"eyJ4NDAyVmVyc2lvbiI6MiwicmVzb3VyY2UiOnsidXJsIjoiaHR0cHM6Ly9waG90b3ByaW50YWdlbnQuY29tL2FwaS9vcmRlcnMvYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYS9wYXkiLCJkZXNjcmlwdGlvbiI6IjTDlzYgcGhvdG8gcHJpbnQgb3JkZXIgYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1pbWVUeXBlIjoiYXBwbGljYXRpb24vanNvbiJ9LCJhY2NlcHRzIjpbeyJzY2hlbWUiOiJleGFjdCIsIm5ldHdvcmsiOiJlaXAxNTU6ODQ1MyIsImFzc2V0IjoiMHg4MzM1ODlmQ0Q2ZURiNkUwOGY0YzdDMzJENGY3MWI1NGJkQTAyOTEzIiwiYW1vdW50IjoiNTUwMDAwMCIsInBheVRvIjoiMHgxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExIiwibWF4VGltZW91dFNlY29uZHMiOjMwMCwiZXh0cmEiOnsibmFtZSI6IlVTRCBDb2luIiwidmVyc2lvbiI6IjIifX1dfQ==\"}"
}
],
"structuredContent": {
"status": "payment_required",
"httpStatus": 402,
"payment_required": {
"x402Version": 2,
"resource": {
"url": "https://photoprintagent.com/api/orders/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/pay",
"description": "4×6 photo print order aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"mimeType": "application/json"
},
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "5500000",
"payTo": "0x1111111111111111111111111111111111111111",
"maxTimeoutSeconds": 300,
"extra": {
"name": "USD Coin",
"version": "2"
}
}
]
},
"paymentRequiredHeader": "eyJ4NDAyVmVyc2lvbiI6MiwicmVzb3VyY2UiOnsidXJsIjoiaHR0cHM6Ly9waG90b3ByaW50YWdlbnQuY29tL2FwaS9vcmRlcnMvYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYS9wYXkiLCJkZXNjcmlwdGlvbiI6IjTDlzYgcGhvdG8gcHJpbnQgb3JkZXIgYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1pbWVUeXBlIjoiYXBwbGljYXRpb24vanNvbiJ9LCJhY2NlcHRzIjpbeyJzY2hlbWUiOiJleGFjdCIsIm5ldHdvcmsiOiJlaXAxNTU6ODQ1MyIsImFzc2V0IjoiMHg4MzM1ODlmQ0Q2ZURiNkUwOGY0YzdDMzJENGY3MWI1NGJkQTAyOTEzIiwiYW1vdW50IjoiNTUwMDAwMCIsInBheVRvIjoiMHgxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExIiwibWF4VGltZW91dFNlY29uZHMiOjMwMCwiZXh0cmEiOnsibmFtZSI6IlVTRCBDb2luIiwidmVyc2lvbiI6IjIifX1dfQ=="
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":402,\"message\":\"Payment authorization was rejected.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 402,
"message": "Payment authorization was rejected."
}
},
"isError": true
}
}
Signed retry request (replace the placeholder with the base64 SDK output; preserve orderId):
{
"jsonrpc": "2.0",
"id": 11,
"method": "tools/call",
"params": {
"name": "pay_print_order",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"paymentSignature": "<BASE64_X402_V2_SIGNED_PAYLOAD>"
}
}
}
New settlement success response (also PAYMENT-RESPONSE header):
{
"jsonrpc": "2.0",
"id": 11,
"result": {
"content": [
{
"type": "text",
"text": "{\"status\":\"order_status\",\"httpStatus\":200,\"order\":{\"id\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"status\":\"processing\",\"method\":\"x402\",\"price\":{\"currency\":\"USD\",\"subtotal\":100,\"shipping\":400,\"tax\":50,\"total\":550},\"pricingVersion\":0,\"paymentDeadline\":1893542400000,\"canEditCoupon\":true,\"quantity\":2,\"createdAt\":1893456000000,\"paidAt\":1893456060000,\"paymentStatus\":\"paid\",\"fulfillmentStatus\":\"accepted\",\"cryptoPayment\":null,\"transaction\":\"0x5555555555555555555555555555555555555555555555555555555555555555\",\"network\":\"eip155:8453\",\"trackingUrls\":[],\"message\":\"Your order has been accepted and is processing.\"},\"paymentResponse\":{\"success\":true,\"transaction\":\"0x5555555555555555555555555555555555555555555555555555555555555555\",\"network\":\"eip155:8453\"},\"paymentResponseHeader\":\"eyJzdWNjZXNzIjp0cnVlLCJ0cmFuc2FjdGlvbiI6IjB4NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NSIsIm5ldHdvcmsiOiJlaXAxNTU6ODQ1MyJ9\"}"
}
],
"structuredContent": {
"status": "order_status",
"httpStatus": 200,
"order": {
"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"status": "processing",
"method": "x402",
"price": {
"currency": "USD",
"subtotal": 100,
"shipping": 400,
"tax": 50,
"total": 550
},
"pricingVersion": 0,
"paymentDeadline": 1893542400000,
"canEditCoupon": true,
"quantity": 2,
"createdAt": 1893456000000,
"paidAt": 1893456060000,
"paymentStatus": "paid",
"fulfillmentStatus": "accepted",
"cryptoPayment": null,
"transaction": "0x5555555555555555555555555555555555555555555555555555555555555555",
"network": "eip155:8453",
"trackingUrls": [],
"message": "Your order has been accepted and is processing."
},
"paymentResponse": {
"success": true,
"transaction": "0x5555555555555555555555555555555555555555555555555555555555555555",
"network": "eip155:8453"
},
"paymentResponseHeader": "eyJzdWNjZXNzIjp0cnVlLCJ0cmFuc2FjdGlvbiI6IjB4NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NSIsIm5ldHdvcmsiOiJlaXAxNTU6ODQ1MyJ9"
}
}
}
get_order
Read your private order. Payment and fulfillment states are separate; processing means PhotoPrintAgent accepted the order for processing, not shipped. Use only PhotoPrintAgent branding and the returned customer status in updates. Does not initiate charges. Polling verifies a completed card checkout only with payment permission or a full guest/account credential. Read-only OAuth returns saved status without reconciliation.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"status": {
"type": "string",
"enum": [
"creating_checkout",
"awaiting_payment",
"verifying_payment",
"settling_payment",
"paid",
"submitting",
"processing",
"needs_review",
"expired"
]
},
"method": {
"type": "string",
"enum": [
"card",
"x402"
]
},
"price": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"const": "USD"
},
"subtotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"shipping": {
"$ref": "#/properties/price/properties/subtotal"
},
"tax": {
"$ref": "#/properties/price/properties/subtotal"
},
"total": {
"$ref": "#/properties/price/properties/subtotal"
},
"originalTotal": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"discount": {
"$ref": "#/properties/price/properties/subtotal",
"description": "Integer USD cents"
},
"coupon": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"name": {
"type": "string"
},
"printDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"shippingDiscount": {
"$ref": "#/properties/price/properties/subtotal"
},
"taxCredit": {
"$ref": "#/properties/price/properties/subtotal"
}
},
"required": [
"code",
"name",
"printDiscount",
"shippingDiscount",
"taxCredit"
],
"additionalProperties": false
}
},
"required": [
"currency",
"subtotal",
"shipping",
"tax",
"total"
],
"additionalProperties": false
},
"pricingVersion": {
"type": "integer",
"minimum": 0
},
"paymentDeadline": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"canEditCoupon": {
"type": "boolean"
},
"canRenewCheckout": {
"type": "boolean"
},
"cardPaymentUrl": {
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"type": "null"
}
]
},
"cardProcessor": {
"anyOf": [
{
"type": "string",
"enum": [
"square",
"stripe"
]
},
{
"type": "null"
}
]
},
"quantity": {
"type": "integer"
},
"progress": {
"type": "object",
"properties": {
"productionStatus": {
"type": "string",
"enum": [
"not_submitted",
"queued",
"submitting",
"accepted",
"printing",
"shipped",
"delivered",
"cancelled",
"on_hold",
"needs_review",
"unknown"
]
},
"shipmentStatus": {
"type": "string",
"enum": [
"unknown",
"shipped",
"delivered"
]
},
"lastUpdatedAt": {
"type": [
"number",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"supportStatus": {
"type": "string",
"enum": [
"none",
"open",
"waiting_customer",
"under_review",
"resolved"
]
},
"canRequestCancellation": {
"type": "boolean"
},
"canRequestChange": {
"type": "boolean"
},
"canRequestRefund": {
"type": "boolean"
},
"cancellationGuaranteed": {
"type": "boolean",
"const": false
}
},
"required": [
"productionStatus",
"shipmentStatus",
"lastUpdatedAt",
"trackingUrls",
"supportStatus",
"canRequestCancellation",
"canRequestChange",
"canRequestRefund",
"cancellationGuaranteed"
],
"additionalProperties": false
},
"productName": {
"type": "string"
},
"imageCount": {
"type": "integer"
},
"createdAt": {
"$ref": "#/properties/paymentDeadline"
},
"paidAt": {
"anyOf": [
{
"$ref": "#/properties/paymentDeadline"
},
{
"type": "null"
}
],
"description": "Unix time in milliseconds"
},
"paymentStatus": {
"type": "string",
"enum": [
"unpaid",
"pending",
"paid",
"refunded",
"not_required",
"needs_review",
"expired"
]
},
"fulfillmentStatus": {
"type": "string",
"enum": [
"not_submitted",
"submitting",
"accepted",
"needs_review"
]
},
"cryptoPayment": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"rankId": {
"type": "string"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string"
},
"asset": {
"type": "string"
},
"decimals": {
"type": "integer"
},
"transferMethod": {
"type": "string",
"enum": [
"eip3009",
"permit2",
"spl"
]
},
"network": {
"type": "string"
},
"tokenProgram": {
"type": "string"
},
"rank": {
"type": [
"number",
"null"
]
},
"wrapped": {
"type": "boolean"
},
"stable": {
"type": "boolean"
},
"availability": {
"type": "string",
"enum": [
"quote_required",
"receiving_ready"
]
},
"priceChecked": {
"type": "boolean"
},
"tokenId": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^\\d+$"
},
"displayAmount": {
"type": "string"
},
"usdTotal": {
"$ref": "#/properties/price/properties/subtotal"
},
"usdPrice": {
"type": "string"
},
"priceAsOf": {
"$ref": "#/properties/paymentDeadline"
},
"source": {
"type": "string"
},
"payTo": {
"type": "string"
},
"quotedAt": {
"$ref": "#/properties/paymentDeadline"
},
"validUntil": {
"$ref": "#/properties/paymentDeadline"
}
},
"required": [
"id",
"rankId",
"name",
"symbol",
"asset",
"decimals",
"transferMethod",
"network",
"tokenId",
"amount",
"displayAmount",
"usdTotal",
"usdPrice",
"priceAsOf",
"source",
"payTo",
"quotedAt",
"validUntil"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"transaction": {
"type": [
"string",
"null"
]
},
"network": {
"type": [
"string",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
},
"message": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"status",
"method",
"price",
"pricingVersion",
"paymentDeadline",
"canEditCoupon",
"quantity",
"createdAt",
"paidAt",
"paymentStatus",
"fulfillmentStatus",
"cryptoPayment",
"transaction",
"network",
"trackingUrls",
"message"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "get_order",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"id\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"status\":\"processing\",\"method\":\"x402\",\"price\":{\"currency\":\"USD\",\"subtotal\":100,\"shipping\":400,\"tax\":50,\"total\":550},\"pricingVersion\":0,\"paymentDeadline\":1893542400000,\"canEditCoupon\":true,\"quantity\":2,\"createdAt\":1893456000000,\"paidAt\":1893456060000,\"paymentStatus\":\"paid\",\"fulfillmentStatus\":\"accepted\",\"cryptoPayment\":null,\"transaction\":\"0x5555555555555555555555555555555555555555555555555555555555555555\",\"network\":\"eip155:8453\",\"trackingUrls\":[],\"message\":\"Your order has been accepted and is processing.\"}"
}
],
"structuredContent": {
"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"status": "processing",
"method": "x402",
"price": {
"currency": "USD",
"subtotal": 100,
"shipping": 400,
"tax": 50,
"total": 550
},
"pricingVersion": 0,
"paymentDeadline": 1893542400000,
"canEditCoupon": true,
"quantity": 2,
"createdAt": 1893456000000,
"paidAt": 1893456060000,
"paymentStatus": "paid",
"fulfillmentStatus": "accepted",
"cryptoPayment": null,
"transaction": "0x5555555555555555555555555555555555555555555555555555555555555555",
"network": "eip155:8453",
"trackingUrls": [],
"message": "Your order has been accepted and is processing."
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":404,\"message\":\"Not found.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 404,
"message": "Not found."
}
},
"isError": true
}
}
list_payment_assets
Public: search Base ERC-20 and ready Solana SPL / compatible Token-2022 payment candidates by name, ticker or exact contract/mint. No market-cap limit. Results are paginated; pass nextOffset as offset. Call quote_crypto_payment to verify the token and obtain a fresh price. Solana needs the merchant receiving account initialized.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"search": {
"type": "string",
"maxLength": 100,
"default": ""
},
"network": {
"type": "string",
"enum": [
"eip155:8453",
"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
]
},
"offset": {
"type": "integer",
"minimum": 0,
"maximum": 20000,
"default": 0
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"network": {
"type": "string"
},
"priceStatus": {
"type": "string",
"enum": [
"available",
"unavailable"
]
},
"rankingSource": {
"type": "string"
},
"catalogUpdatedAt": {
"type": "string"
},
"catalogSource": {
"type": "string",
"enum": [
"bundled",
"refreshed"
]
},
"catalogStale": {
"type": "boolean"
},
"assets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"rankId": {
"type": "string"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string"
},
"asset": {
"type": "string"
},
"decimals": {
"type": "integer"
},
"transferMethod": {
"type": "string",
"enum": [
"eip3009",
"permit2",
"spl"
]
},
"network": {
"type": "string"
},
"tokenProgram": {
"type": "string"
},
"rank": {
"type": [
"number",
"null"
]
},
"wrapped": {
"type": "boolean"
},
"stable": {
"type": "boolean"
},
"availability": {
"type": "string",
"enum": [
"quote_required",
"receiving_ready"
]
},
"priceChecked": {
"type": "boolean"
}
},
"required": [
"id",
"rankId",
"name",
"symbol",
"asset",
"decimals",
"transferMethod",
"network"
],
"additionalProperties": false
}
},
"networks": {
"type": "array",
"items": {
"type": "string"
}
},
"total": {
"type": "integer"
},
"offset": {
"type": "integer"
},
"nextOffset": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"solanaPayTo": {
"type": [
"string",
"null"
]
}
},
"required": [
"network",
"priceStatus",
"rankingSource",
"assets",
"networks",
"total",
"offset",
"nextOffset",
"solanaPayTo"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "list_payment_assets",
"arguments": {}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"network\":\"eip155:8453\",\"priceStatus\":\"available\",\"rankingSource\":\"CoinGecko token catalog; no market-cap restriction\",\"assets\":[{\"id\":\"usd-coin\",\"rankId\":\"usd-coin\",\"name\":\"USDC\",\"symbol\":\"USDC\",\"asset\":\"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\"decimals\":6,\"transferMethod\":\"eip3009\",\"network\":\"eip155:8453\",\"rank\":6}],\"networks\":[\"eip155:8453\"],\"total\":1,\"offset\":0,\"nextOffset\":null,\"solanaPayTo\":\"87RFu8CtatoJe2dAys91WxT6bCGw9rzmnGzZ8HwsAzye\"}"
}
],
"structuredContent": {
"network": "eip155:8453",
"priceStatus": "available",
"rankingSource": "CoinGecko token catalog; no market-cap restriction",
"assets": [
{
"id": "usd-coin",
"rankId": "usd-coin",
"name": "USDC",
"symbol": "USDC",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"decimals": 6,
"transferMethod": "eip3009",
"network": "eip155:8453",
"rank": 6
}
],
"networks": [
"eip155:8453"
],
"total": 1,
"offset": 0,
"nextOffset": null,
"solanaPayTo": "87RFu8CtatoJe2dAys91WxT6bCGw9rzmnGzZ8HwsAzye"
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":503,\"message\":\"Live crypto pricing is temporarily unavailable.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 503,
"message": "Live crypto pricing is temporarily unavailable."
}
},
"isError": true
}
}
quote_crypto_payment
Lock an unpaid order in a listed token for up to 60 seconds. Obtain approval of this exact amount and include cryptoQuoteId in the payment retry.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"tokenId": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId",
"tokenId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"rankId": {
"type": "string"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string"
},
"asset": {
"type": "string"
},
"decimals": {
"type": "integer"
},
"transferMethod": {
"type": "string",
"enum": [
"eip3009",
"permit2",
"spl"
]
},
"network": {
"type": "string"
},
"tokenProgram": {
"type": "string"
},
"rank": {
"type": [
"number",
"null"
]
},
"wrapped": {
"type": "boolean"
},
"stable": {
"type": "boolean"
},
"availability": {
"type": "string",
"enum": [
"quote_required",
"receiving_ready"
]
},
"priceChecked": {
"type": "boolean"
},
"tokenId": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^\\d+$"
},
"displayAmount": {
"type": "string"
},
"usdTotal": {
"type": "integer",
"minimum": 0,
"description": "Integer USD cents"
},
"usdPrice": {
"type": "string"
},
"priceAsOf": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"source": {
"type": "string"
},
"payTo": {
"type": "string"
},
"quotedAt": {
"$ref": "#/properties/priceAsOf"
},
"validUntil": {
"$ref": "#/properties/priceAsOf"
}
},
"required": [
"id",
"rankId",
"name",
"symbol",
"asset",
"decimals",
"transferMethod",
"network",
"tokenId",
"amount",
"displayAmount",
"usdTotal",
"usdPrice",
"priceAsOf",
"source",
"payTo",
"quotedAt",
"validUntil"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "quote_crypto_payment",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"tokenId": "usd-coin"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"id\":\"55555555-5555-4555-8555-555555555555\",\"rankId\":\"usd-coin\",\"name\":\"USDC\",\"symbol\":\"USDC\",\"asset\":\"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\"decimals\":6,\"transferMethod\":\"eip3009\",\"network\":\"eip155:8453\",\"rank\":6,\"tokenId\":\"usd-coin\",\"amount\":\"5500000\",\"displayAmount\":\"5.5\",\"usdTotal\":550,\"usdPrice\":\"1\",\"priceAsOf\":1893456000000,\"source\":\"USDC checkout denomination\",\"payTo\":\"0x1111111111111111111111111111111111111111\",\"quotedAt\":1893456000000,\"validUntil\":1893456060000}"
}
],
"structuredContent": {
"id": "55555555-5555-4555-8555-555555555555",
"rankId": "usd-coin",
"name": "USDC",
"symbol": "USDC",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"decimals": 6,
"transferMethod": "eip3009",
"network": "eip155:8453",
"rank": 6,
"tokenId": "usd-coin",
"amount": "5500000",
"displayAmount": "5.5",
"usdTotal": 550,
"usdPrice": "1",
"priceAsOf": 1893456000000,
"source": "USDC checkout denomination",
"payTo": "0x1111111111111111111111111111111111111111",
"quotedAt": 1893456000000,
"validUntil": 1893456060000
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":409,\"message\":\"This order is not waiting for a crypto payment.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 409,
"message": "This order is not waiting for a crypto payment."
}
},
"isError": true
}
}
get_checkout_options
Public account and guest authentication instructions, current order terms URL/version, and required acceptance field.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
Input JSON Schema:
{
"type": "object",
"properties": {},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"terms": {
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"version": {
"type": "string"
},
"acceptanceField": {
"type": "string",
"const": "termsAccepted"
}
},
"required": [
"url",
"version",
"acceptanceField"
],
"additionalProperties": false
},
"account": {
"type": "object",
"properties": {
"signInUrl": {
"type": "string",
"format": "uri"
},
"firebaseConfigUrl": {
"type": "string",
"format": "uri"
},
"oauthMetadataUrl": {
"type": "string",
"format": "uri"
},
"instructions": {
"type": "string"
}
},
"required": [
"signInUrl",
"firebaseConfigUrl",
"instructions"
],
"additionalProperties": false
},
"guest": {
"type": "object",
"properties": {
"endpoint": {
"type": "string"
},
"method": {
"type": "string",
"const": "POST"
},
"mcpTool": {
"type": "string",
"const": "start_guest_checkout"
},
"accountRequired": {
"type": "boolean",
"const": false
},
"paymentMethods": {
"type": "array",
"items": {
"type": "string",
"enum": [
"card",
"x402"
]
}
}
},
"required": [
"endpoint",
"method",
"mcpTool",
"accountRequired",
"paymentMethods"
],
"additionalProperties": false
},
"guideUrl": {
"type": "string",
"format": "uri"
}
},
"required": [
"terms",
"account",
"guest",
"guideUrl"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "get_checkout_options",
"arguments": {}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"terms\":{\"url\":\"https://photoprintagent.com/terms\",\"version\":\"2026-10-25\",\"acceptanceField\":\"termsAccepted\"},\"account\":{\"signInUrl\":\"https://photoprintagent.com/agents\",\"firebaseConfigUrl\":\"https://photoprintagent.com/firebase-config.json\",\"instructions\":\"Use a verified Firebase ID token with POST /api/agent-keys or create_agent_key. See the account login recipe above.\"},\"guest\":{\"endpoint\":\"/api/guest-sessions\",\"method\":\"POST\",\"mcpTool\":\"start_guest_checkout\",\"accountRequired\":false,\"paymentMethods\":[\"card\",\"x402\"]},\"guideUrl\":\"https://photoprintagent.com/docs/mcp\"}"
}
],
"structuredContent": {
"terms": {
"url": "https://photoprintagent.com/terms",
"version": "2026-10-25",
"acceptanceField": "termsAccepted"
},
"account": {
"signInUrl": "https://photoprintagent.com/agents",
"firebaseConfigUrl": "https://photoprintagent.com/firebase-config.json",
"instructions": "Use a verified Firebase ID token with POST /api/agent-keys or create_agent_key. See the account login recipe above."
},
"guest": {
"endpoint": "/api/guest-sessions",
"method": "POST",
"mcpTool": "start_guest_checkout",
"accountRequired": false,
"paymentMethods": [
"card",
"x402"
]
},
"guideUrl": "https://photoprintagent.com/docs/mcp"
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":503,\"message\":\"Service temporarily unavailable.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 503,
"message": "Service temporarily unavailable."
}
},
"isError": true
}
}
create_agent_key
Mint a 90-day account key using a verified Firebase ID token in Authorization. Guests and existing agent keys cannot mint keys.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"key": {
"type": "string"
},
"id": {
"type": "string"
},
"expiresAt": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
}
},
"required": [
"key",
"id",
"expiresAt"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "create_agent_key",
"arguments": {}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"key\":\"ppa_0000000000000000000000000000000000000000000000000000000000000000\",\"id\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"expiresAt\":1901232000000}"
}
],
"structuredContent": {
"key": "ppa_0000000000000000000000000000000000000000000000000000000000000000",
"id": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"expiresAt": 1901232000000
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":403,\"message\":\"Use a verified Firebase ID token to manage keys. See /docs/mcp.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 403,
"message": "Use a verified Firebase ID token to manage keys. See /docs/mcp."
}
},
"isError": true
}
}
estimate_print_price
Estimate configured product and shipping charges using only product, quantity, ZIP and state. No photos or contact details required. Unknown tax or charges remain null; this is not a payable quote.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"productId": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"quantity": {
"type": "integer",
"minimum": 1,
"maximum": 500
},
"zip": {
"type": "string",
"pattern": "^\\d{5}$"
},
"state": {
"type": "string",
"pattern": "^[A-Z]{2}$"
}
},
"required": [
"productId",
"quantity",
"zip",
"state"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"estimate": {
"type": "boolean",
"const": true
},
"currency": {
"type": "string",
"const": "USD"
},
"productId": {
"type": "string"
},
"quantity": {
"type": "number"
},
"subtotal": {
"type": [
"number",
"null"
]
},
"shipping": {
"type": [
"number",
"null"
]
},
"tax": {
"type": [
"number",
"null"
]
},
"total": {
"type": [
"number",
"null"
]
},
"knownAmount": {
"type": "number"
},
"unknownComponents": {
"type": "array",
"items": {
"type": "string"
}
},
"requiresFinalQuote": {
"type": "boolean",
"const": true
},
"message": {
"type": "string"
}
},
"required": [
"estimate",
"currency",
"productId",
"quantity",
"subtotal",
"shipping",
"tax",
"total",
"knownAmount",
"unknownComponents",
"requiresFinalQuote",
"message"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "estimate_print_price",
"arguments": {
"productId": "photo-4x6",
"quantity": 2,
"zip": "10001",
"state": "NY"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"estimate\":true,\"currency\":\"USD\",\"productId\":\"photo-4x6\",\"quantity\":2,\"subtotal\":null,\"shipping\":null,\"tax\":null,\"total\":null,\"knownAmount\":0,\"unknownComponents\":[\"subtotal\",\"shipping\",\"tax\"],\"requiresFinalQuote\":true,\"message\":\"Enter your delivery address for the final quote.\"}"
}
],
"structuredContent": {
"estimate": true,
"currency": "USD",
"productId": "photo-4x6",
"quantity": 2,
"subtotal": null,
"shipping": null,
"tax": null,
"total": null,
"knownAmount": 0,
"unknownComponents": [
"subtotal",
"shipping",
"tax"
],
"requiresFinalQuote": true,
"message": "Enter your delivery address for the final quote."
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":409,\"message\":\"This product is not currently available to order.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 409,
"message": "This product is not currently available to order."
}
},
"isError": true
}
}
get_order_events
Read your customer-safe order events in sequence. Save the last sequence as after for incremental recovery; duplicate events must be deduplicated by orderId and sequence.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"after": {
"type": "integer",
"minimum": 0,
"default": 0
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"events": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"sequence": {
"type": "integer"
},
"type": {
"type": "string",
"const": "order.updated"
},
"occurredAt": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"data": {
"type": "object",
"properties": {
"productionStatus": {
"type": "string",
"enum": [
"not_submitted",
"queued",
"submitting",
"accepted",
"printing",
"shipped",
"delivered",
"cancelled",
"on_hold",
"needs_review",
"unknown"
]
},
"shipmentStatus": {
"type": "string",
"enum": [
"unknown",
"shipped",
"delivered"
]
},
"lastUpdatedAt": {
"type": [
"number",
"null"
]
},
"trackingUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"supportStatus": {
"type": "string",
"enum": [
"none",
"open",
"waiting_customer",
"under_review",
"resolved"
]
},
"canRequestCancellation": {
"type": "boolean"
},
"canRequestChange": {
"type": "boolean"
},
"canRequestRefund": {
"type": "boolean"
},
"cancellationGuaranteed": {
"type": "boolean",
"const": false
},
"paymentStatus": {
"type": "string",
"enum": [
"refunded",
"not_required",
"paid",
"unpaid"
]
}
},
"required": [
"productionStatus",
"shipmentStatus",
"lastUpdatedAt",
"trackingUrls",
"supportStatus",
"canRequestCancellation",
"canRequestChange",
"canRequestRefund",
"cancellationGuaranteed",
"paymentStatus"
],
"additionalProperties": false
}
},
"required": [
"id",
"orderId",
"sequence",
"type",
"occurredAt",
"data"
],
"additionalProperties": false
}
},
"nextCursor": {
"type": [
"number",
"null"
]
}
},
"required": [
"events",
"nextCursor"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "get_order_events",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"events\":[],\"nextCursor\":null}"
}
],
"structuredContent": {
"events": [],
"nextCursor": null
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":404,\"message\":\"Order not found.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 404,
"message": "Order not found."
}
},
"isError": true
}
}
request_order_help
Create an order-bound support, address-change, cancellation or refund REQUEST. Requires buyer authorization. No cancellation, refund or change is executed or guaranteed. Reuse idempotencyKey when retrying the same request; read progress capability flags first.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"type": {
"type": "string",
"enum": [
"general",
"address",
"cancellation",
"refund",
"damaged_prints",
"late_delivery"
]
},
"message": {
"type": "string",
"minLength": 10,
"maxLength": 2000
},
"idempotencyKey": {
"type": "string",
"pattern": "^[\\w-]{16,100}$"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId",
"type",
"message",
"idempotencyKey"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"reference": {
"type": "string"
},
"status": {
"type": "string",
"const": "requested"
},
"type": {
"type": "string"
},
"createdAt": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
"message": {
"type": "string"
}
},
"required": [
"reference",
"status",
"type",
"createdAt",
"message"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "request_order_help",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"type": "general",
"message": "Please review this order status.",
"idempotencyKey": "support-request-example-1"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"reference\":\"example-reference\",\"status\":\"requested\",\"type\":\"general\",\"createdAt\":1893456000000,\"message\":\"Your request is saved for review. No order change, cancellation or refund has been confirmed.\"}"
}
],
"structuredContent": {
"reference": "example-reference",
"status": "requested",
"type": "general",
"createdAt": 1893456000000,
"message": "Your request is saved for review. No order change, cancellation or refund has been confirmed."
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":409,\"message\":\"This action cannot be requested in the current order state.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 409,
"message": "This action cannot be requested in the current order state."
}
},
"isError": true
}
}
subscribe_order_events
Subscribe an owned order to an HTTPS webhook you control. Requires permission to send this order status to that endpoint. Returns a signing secret once. At-least-once delivery; verify timestamp/signature and deduplicate orderId + sequence. Repeated failures pause delivery; use event history for recovery.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"url": {
"type": "string",
"format": "uri",
"maxLength": 2000
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId",
"url"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"secret": {
"type": "string"
},
"url": {
"type": "string"
},
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"signature": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"id",
"secret",
"url",
"orderId",
"signature",
"message"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "subscribe_order_events",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"url": "https://example.com/order-events"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"id\":\"example-subscription\",\"secret\":\"EXAMPLE-NOT-A-REAL-SECRET\",\"url\":\"https://example.com/order-events\",\"orderId\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"signature\":\"HMAC-SHA256 of timestamp + dot + body\",\"message\":\"Store the signing secret securely.\"}"
}
],
"structuredContent": {
"id": "example-subscription",
"secret": "EXAMPLE-NOT-A-REAL-SECRET",
"url": "https://example.com/order-events",
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"signature": "HMAC-SHA256 of timestamp + dot + body",
"message": "Store the signing secret securely."
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":400,\"message\":\"Webhook destination must resolve only to public addresses.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 400,
"message": "Webhook destination must resolve only to public addresses."
}
},
"isError": true
}
}
list_order_subscriptions
List your webhook destinations and delivery status for an owned order. Signing secrets are never returned.
Tool annotations:
{
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"orderId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"subscriptions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"url": {
"type": "string"
},
"active": {
"type": "boolean"
},
"cursor": {
"type": "number"
},
"deliveryStatus": {
"type": "string"
},
"lastDeliveredAt": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
},
{
"type": "null"
}
],
"description": "Unix time in milliseconds"
}
},
"required": [
"id",
"url",
"active",
"cursor",
"deliveryStatus",
"lastDeliveredAt"
],
"additionalProperties": false
}
}
},
"required": [
"subscriptions"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "list_order_subscriptions",
"arguments": {
"orderId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"subscriptions\":[]}"
}
],
"structuredContent": {
"subscriptions": []
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":404,\"message\":\"Order not found.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 404,
"message": "Order not found."
}
},
"isError": true
}
}
replay_order_events
Resume a failed subscription or replay events after a saved sequence. Requires authorization to resend order status to the registered destination; no payments or orders are repeated.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"subscriptionId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"after": {
"type": "integer",
"minimum": 0,
"default": 0
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"subscriptionId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"ok": {
"type": "boolean",
"const": true
}
},
"required": [
"ok"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "replay_order_events",
"arguments": {
"subscriptionId": "example-subscription",
"after": 0
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"ok\":true}"
}
],
"structuredContent": {
"ok": true
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":404,\"message\":\"Subscription not found.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 404,
"message": "Subscription not found."
}
},
"isError": true
}
}
unsubscribe_order_events
Disable one of your webhook subscriptions and erase its signing secret.
Tool annotations:
{
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": true
}
Input JSON Schema:
{
"type": "object",
"properties": {
"subscriptionId": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{1,100}$"
},
"guestToken": {
"type": "string",
"pattern": "^ppg_[a-f0-9]{64}$",
"description": "Private guest credential; omit when Authorization Bearer is present."
}
},
"required": [
"subscriptionId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Output JSON Schema (structuredContent):
{
"type": "object",
"properties": {
"ok": {
"type": "boolean",
"const": true
}
},
"required": [
"ok"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Request:
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "unsubscribe_order_events",
"arguments": {
"subscriptionId": "example-subscription"
}
}
}
Success response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"ok\":true}"
}
],
"structuredContent": {
"ok": true
}
}
}
Common error response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [
{
"type": "text",
"text": "{\"error\":{\"httpStatus\":404,\"message\":\"Subscription not found.\"}}"
}
],
"structuredContent": {
"error": {
"httpStatus": 404,
"message": "Subscription not found."
}
},
"isError": true
}
}
Binary upload response JSON Schema
Returned by POST /api/photos (HTTP 201), outside the JSON-RPC envelope.
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"productId": {
"type": "string"
},
"artworkKey": {
"type": "string"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
},
"quality": {
"type": "string",
"enum": [
"high",
"reduced"
]
},
"sourceFormat": {
"type": "string"
},
"sourceImages": {
"type": "integer",
"exclusiveMinimum": 0
},
"expiresAt": {
"type": "integer",
"minimum": 0,
"description": "Unix time in milliseconds"
}
},
"required": [
"id",
"width",
"height",
"quality",
"expiresAt"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}