{
  "contractVersion": 1,
  "source": "painted-agency",
  "generatedAt": "2026-10-07T00:00:00Z",
  "derivedFrom": {
    "offersContractVersion": 1,
    "catalogueSha256": "11a6a81fc753e505beaba0ad4860f3a031264ca7df7e5bfdf93663a93dcc0549",
    "verifiedSkusSha256": null
  },
  "site": {
    "name": "Painted Agency",
    "url": "https://www.painted.agency"
  },
  "checkout": {
    "endpoint": "/api/checkout",
    "method": "POST",
    "contentType": "application/json",
    "priceAuthority": "server",
    "body": "an object { lines: CheckoutLine[] }",
    "line": {
      "pieceSlug": "the productID of a Product in this feed",
      "formatId": "checkoutLine.formatId of one of its Offers (paper or canvas, unframed)",
      "size": "checkoutLine.size of that Offer, short edge x long edge in inches",
      "qty": "an integer from 1 to 25"
    },
    "success": {
      "status": 200,
      "body": "{ url: <Stripe Checkout URL> }"
    },
    "errors": [
      {
        "code": "INVALID_REQUEST",
        "status": 400,
        "meaning": "the body is not JSON or not the documented shape"
      },
      {
        "code": "CART_EMPTY",
        "status": 400,
        "meaning": "lines is empty"
      },
      {
        "code": "INVALID_QUANTITY",
        "status": 400,
        "meaning": "qty is not an integer from 1 to 25"
      },
      {
        "code": "UNKNOWN_PIECE",
        "status": 400,
        "meaning": "pieceSlug names no piece the house sells"
      },
      {
        "code": "UNKNOWN_PRODUCT",
        "status": 400,
        "meaning": "formatId and size are not a catalogue pair"
      },
      {
        "code": "PRODUCT_UNAVAILABLE",
        "status": 400,
        "meaning": "the pair exists but the house cannot fulfil it"
      },
      {
        "code": "UNKNOWN_SET",
        "status": 400,
        "meaning": "bundleSlug names no set"
      },
      {
        "code": "SET_UNAVAILABLE",
        "status": 400,
        "meaning": "a member of the set is not sellable"
      },
      {
        "code": "CLIENT_PRICE_REFUSED",
        "status": 400,
        "meaning": "a line or the body carried an amount or price field; the server is the only price authority"
      },
      {
        "code": "STRIPE_NOT_CONFIGURED",
        "status": 503,
        "meaning": "the house has no payment key; nothing was charged"
      }
    ]
  },
  "products": []
}
