{"openapi":"3.1.0","info":{"title":"Gonzalez Brothers trade API","version":"1","summary":"Green and roasted specialty coffee from six named farms in Ecuador, roasted in London.","description":"Public catalog reads need no credentials. Account, order, sample and shortlist operations take a Cognito access token\nas `Authorization: Bearer <JWT>` (obtain one with `POST /api/v1/auth/login`).\n\nEvery scope name below is declared once and enforced per operation. A token minted by the password flow carries no\nresource scopes and is treated as holding every `authenticated` scope; a token that does carry `https://api.gonzalezbrothers.coffee/<scope>`\nentries in its `scope` claim is limited to exactly those. The same list is published as `scopes_supported` at\n`/.well-known/oauth-protected-resource`.\n\nErrors are RFC 7807 problem details. Unknown paths return a real 404 with a problem body that links back here.\nThe shop itself (products, collections, checkout) lives at https://gonzalezbrothers.coffee — see https://gonzalezbrothers.coffee/agents.md.","contact":{"name":"Gonzalez Brothers","url":"https://gonzalezbrothers.coffee/apps/shop/contact"},"termsOfService":"https://gonzalezbrothers.coffee/policies/terms-of-service"},"servers":[{"url":"https://api.gonzalezbrothers.coffee","description":"Production API"}],"tags":[{"name":"Meta","description":"Health and discovery"},{"name":"Catalog","description":"Green-coffee lots"},{"name":"Auth","description":"Trade-account credentials (Cognito)"},{"name":"Samples","description":"Sample requests"},{"name":"Orders","description":"Green-coffee orders"},{"name":"Shortlist","description":"Saved lots"},{"name":"Account","description":"Profile and preferences"},{"name":"Forms","description":"Open forms: newsletter, enquiries, contact, stock alerts"},{"name":"Storefront","description":"Endpoints reached through the shop domain (https://gonzalezbrothers.coffee/apps/shop); Shopify signs the request"}],"externalDocs":{"description":"Agent guide for the shop","url":"https://gonzalezbrothers.coffee/agents.md"},"paths":{"/health":{"get":{"tags":["Meta"],"summary":"Liveness check","operationId":"getHealth","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"status":{"type":"string","const":"healthy"}}}}}}}}}}},"/openapi.json":{"get":{"tags":["Meta"],"summary":"This document","operationId":"getOpenApi","security":[],"responses":{"200":{"description":"OpenAPI 3.1 document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/openapi.json":{"get":{"tags":["Meta"],"summary":"This document, under the API prefix","operationId":"getOpenApiUnderApi","security":[],"responses":{"200":{"description":"OpenAPI 3.1 document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/.well-known/oauth-protected-resource":{"get":{"tags":["Meta"],"summary":"RFC 9728 protected-resource metadata","description":"Names the authorization server and the scopes this API understands (`scopes_supported`).","operationId":"getProtectedResourceMetadata","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtectedResourceMetadata"}}}}}}},"/api/v1/catalog":{"get":{"tags":["Catalog"],"summary":"List the green-coffee catalog","description":"Anonymous callers get the minimal response. A bearer token holding `catalog.enriched` (the `b2b` Cognito group) gets the enriched response: prices, inventory, flavour and full supplier records.","operationId":"listCatalog","security":[{"cognito":["https://api.gonzalezbrothers.coffee/catalog.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/catalog.read"]},{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/MinimalCatalogResponse"},{"$ref":"#/components/schemas/EnrichedCatalogResponse"}]}}}},"404":{"description":"Unsupported API version (only v1)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"supported_versions":{"type":"array","items":{"type":"string"}}}}}}}}}},"/api/v1/catalog/full":{"get":{"tags":["Catalog"],"summary":"The enriched catalog, public","description":"Prices, inventory, flavour, certifications, origin and images with supplier contact and farm coordinates redacted. No auth.","operationId":"getFullCatalog","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichedCatalogResponse"}}}}}}},"/api/v1/lots/{id}":{"get":{"tags":["Catalog"],"summary":"One lot by id","operationId":"getLot","security":[{"cognito":["https://api.gonzalezbrothers.coffee/catalog.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/catalog.read"]},{"bearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Coffee lot id","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/CatalogItem"}}}}}},"400":{"description":"Not a UUID","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such lot","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/auth/signup":{"post":{"tags":["Auth"],"summary":"Create a trade account","operationId":"signup","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Message"}}}}}},"400":{"description":"Validation error or weak password","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Email already registered","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/auth/confirm":{"post":{"tags":["Auth"],"summary":"Confirm the email code","operationId":"confirmSignup","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","code"],"properties":{"email":{"type":"string","format":"email"},"code":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Message"}}}}}},"400":{"description":"Invalid or expired code","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown user","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Exchange email + password for tokens","description":"Returns a Cognito access token (JWT, RS256, 60 min). Send it as `Authorization: Bearer <accessToken>`.","operationId":"login","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","required":["accessToken","refreshToken","expiresIn"],"properties":{"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"expiresIn":{"type":"integer"}}}}}}}},"401":{"description":"Wrong email or password","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Email not confirmed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/auth/refresh":{"post":{"tags":["Auth"],"summary":"Refresh an access token","operationId":"refreshToken","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refreshToken"],"properties":{"refreshToken":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"accessToken":{"type":"string"},"expiresIn":{"type":"integer"}}}}}}}},"401":{"description":"Refresh token rejected","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/auth/forgot":{"post":{"tags":["Auth"],"summary":"Send a password-reset code","operationId":"forgotPassword","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailOnly"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Message"}}}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/auth/verify-reset-code":{"post":{"tags":["Auth"],"summary":"Verify a reset code for a reset token","operationId":"verifyResetCode","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","code"],"properties":{"email":{"type":"string","format":"email"},"code":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"resetToken":{"type":"string"}}}}}}}},"400":{"description":"Invalid or expired code","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/auth/reset":{"post":{"tags":["Auth"],"summary":"Set a new password","operationId":"resetPassword","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["resetToken","newPassword"],"properties":{"resetToken":{"type":"string"},"newPassword":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Message"}}}}}},"400":{"description":"Invalid reset token or weak password","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/auth/resend":{"post":{"tags":["Auth"],"summary":"Resend the confirmation code","operationId":"resendConfirmation","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailOnly"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Message"}}}}}},"409":{"description":"Already confirmed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/samples":{"post":{"tags":["Samples"],"summary":"Request up to three samples","description":"Open to anyone: a guest supplies a delivery address inline; an authenticated customer ships to their profile address (or an override).","operationId":"requestSamples","security":[{"cognito":["https://api.gonzalezbrothers.coffee/samples.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/samples.write"]},{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleRequestBody"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/SampleRequest"}}}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Sample limit exceeded, or an item was rejected (`rejectedItems`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"tags":["Samples"],"summary":"List my sample requests","operationId":"listSamples","security":[{"cognito":["https://api.gonzalezbrothers.coffee/samples.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/samples.read"]},{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/SampleSummary"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/api/v1/samples/{id}":{"get":{"tags":["Samples"],"summary":"One of my sample requests","operationId":"getSample","security":[{"cognito":["https://api.gonzalezbrothers.coffee/samples.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/samples.read"]},{"bearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Sample request id","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/SampleRequest"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"description":"Not yours, or no such request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/orders":{"post":{"tags":["Orders"],"summary":"Place an order","description":"Sells what is available: lines are checked against live green inventory in one transaction.","operationId":"placeOrder","security":[{"cognito":["https://api.gonzalezbrothers.coffee/orders.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/orders.write"]},{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaceOrderRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Order"}}}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}},"get":{"tags":["Orders"],"summary":"List my orders","operationId":"listOrders","security":[{"cognito":["https://api.gonzalezbrothers.coffee/orders.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/orders.read"]},{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Order"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/api/v1/orders/{id}":{"get":{"tags":["Orders"],"summary":"One of my orders","operationId":"getOrder","security":[{"cognito":["https://api.gonzalezbrothers.coffee/orders.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/orders.read"]},{"bearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Order id","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"description":"Not yours, or no such order","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/orders/{id}/cancel":{"post":{"tags":["Orders"],"summary":"Cancel a submitted order","operationId":"cancelOrder","security":[{"cognito":["https://api.gonzalezbrothers.coffee/orders.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/orders.write"]},{"bearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Order id","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"maxLength":2000}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Order"}}}}}},"400":{"description":"Only a Submitted order can be cancelled","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"description":"Not yours, or no such order","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/shortlist":{"get":{"tags":["Shortlist"],"summary":"My shortlist","operationId":"getShortlist","security":[{"cognito":["https://api.gonzalezbrothers.coffee/shortlist.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/shortlist.read"]},{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/ShortlistItem"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/api/v1/shortlist/{lotId}":{"put":{"tags":["Shortlist"],"summary":"Add a lot","operationId":"shortlistAdd","security":[{"cognito":["https://api.gonzalezbrothers.coffee/shortlist.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/shortlist.write"]},{"bearer":[]}],"parameters":[{"name":"lotId","in":"path","required":true,"description":"Coffee lot id","schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Added"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"404":{"description":"No such lot","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["Shortlist"],"summary":"Remove a lot","operationId":"shortlistRemove","security":[{"cognito":["https://api.gonzalezbrothers.coffee/shortlist.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/shortlist.write"]},{"bearer":[]}],"parameters":[{"name":"lotId","in":"path","required":true,"description":"Coffee lot id","schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Removed"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/api/v1/account/preferences":{"get":{"tags":["Account"],"summary":"My preferences","operationId":"getPreferences","security":[{"cognito":["https://api.gonzalezbrothers.coffee/account.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/account.read"]},{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Preferences"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}},"put":{"tags":["Account"],"summary":"Update my preferences","operationId":"putPreferences","security":[{"cognito":["https://api.gonzalezbrothers.coffee/account.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/account.write"]},{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Preferences"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Preferences"}}}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/api/v1/account/profile":{"get":{"tags":["Account"],"summary":"My profile","operationId":"getProfile","security":[{"cognito":["https://api.gonzalezbrothers.coffee/account.read"]},{"agentClient":["https://api.gonzalezbrothers.coffee/account.read"]},{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Profile"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}},"put":{"tags":["Account"],"summary":"Update my profile","description":"Send only the fields to change; `firstName`, `lastName` and `company` cannot be cleared.","operationId":"putProfile","security":[{"cognito":["https://api.gonzalezbrothers.coffee/account.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/account.write"]},{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Profile"}}}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/api/v1/account/profile-picture":{"post":{"tags":["Account"],"summary":"Upload a profile picture","description":"Multipart `image` field, at most 4 MB (JPEG, PNG, WebP or HEIC; normalised server-side). Request bodies over 4.25 MiB are refused with a `payload-too-large` 413 problem document.","operationId":"putProfilePicture","security":[{"cognito":["https://api.gonzalezbrothers.coffee/account.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/account.write"]},{"bearer":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"Stored","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"url":{"type":"string","format":"uri"}}}}}}}},"400":{"description":"Not an image, or too large","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}},"delete":{"tags":["Account"],"summary":"Remove my profile picture","operationId":"deleteProfilePicture","security":[{"cognito":["https://api.gonzalezbrothers.coffee/account.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/account.write"]},{"bearer":[]}],"responses":{"204":{"description":"Removed"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/api/v1/account/unsubscribe-link":{"post":{"tags":["Account"],"summary":"Mint my one-click unsubscribe link","operationId":"createUnsubscribeLink","security":[{"cognito":["https://api.gonzalezbrothers.coffee/account.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/account.write"]},{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"url":{"type":"string","format":"uri"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/InsufficientScope"},"503":{"description":"Unsubscribe links not configured","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/account":{"delete":{"tags":["Account"],"summary":"Delete my account (GDPR)","description":"Password-verified; anonymises the customer record and sends a confirmation email.","operationId":"deleteAccount","security":[{"cognito":["https://api.gonzalezbrothers.coffee/account.write"]},{"agentClient":["https://api.gonzalezbrothers.coffee/account.write"]},{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string"}}}}}},"responses":{"204":{"description":"Deleted"},"401":{"description":"Wrong password, or no token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"$ref":"#/components/responses/InsufficientScope"}}}},"/api/v1/newsletter/subscribe":{"post":{"tags":["Forms"],"summary":"Subscribe an email to the newsletter","operationId":"subscribeNewsletter","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailOnly"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"subscribed":{"type":"boolean","const":true}}}}}}}},"400":{"description":"Invalid email","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/stock-notifications":{"post":{"tags":["Forms"],"summary":"Be told when a lot is back in stock","operationId":"createStockNotification","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","coffeeLotId"],"properties":{"email":{"type":"string","format":"email"},"coffeeLotId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"id":{"type":"string"},"created":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid email or unknown lot","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/enquiries":{"post":{"tags":["Forms"],"summary":"Ask about a lot","operationId":"createEnquiry","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","email","coffeeLotId"],"additionalProperties":false,"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"company":{"type":"string"},"phone":{"type":"string"},"coffeeLotId":{"type":"string","format":"uuid"},"message":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"id":{"type":"string"},"enquiryNumber":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Unknown field","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/contact":{"post":{"tags":["Forms"],"summary":"Send a message to the team","operationId":"sendContactMessage","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"sent":{"type":"boolean","const":true}}}}}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/channels/{channel}":{"get":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"Lots on a sales channel","description":"What the shop is selling right now on the `retail` (roasted bags), `trade` (roasted kilos) or `green` (green sacks, quoted) channel.","operationId":"storefrontChannel","parameters":[{"name":"channel","in":"path","required":true,"schema":{"type":"string","enum":["retail","trade","green"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelListing"}}}},"404":{"description":"Unknown channel","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}}}}},"/retail/{handle}":{"get":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"Editorial content behind a retail product","operationId":"storefrontRetailContent","parameters":[{"name":"handle","in":"path","required":true,"description":"Shopify product handle","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetailContent"}}}},"404":{"description":"Not a retail product","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}}}}},"/wholesale/lot/{handle}":{"get":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"Trade detail for a green lot","description":"Anonymous callers get `{ \"tier\": \"guest\" }`; the cupping detail, documents and sourcing block need an approved trade customer signed in to the shop.","operationId":"storefrontLotDetail","parameters":[{"name":"handle","in":"path","required":true,"description":"Shopify product handle","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["tier"],"properties":{"tier":{"type":"string","enum":["guest","apply","pending","approved"]}},"additionalProperties":true}}}},"404":{"description":"No such lot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}}}}},"/brochure":{"get":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"The priced green-coffee brochure (PDF)","operationId":"storefrontBrochure","parameters":[{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"supplier","in":"query","schema":{"type":"string"}},{"name":"download","in":"query","schema":{"type":"string","enum":["1"]},"description":"Attachment instead of inline"}],"responses":{"200":{"description":"PDF","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/quotes":{"post":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"Request a quote for roasted kilos or green sacks","description":"Trade and green never go through the cart: coffee is priced live, shipping is quoted by a person. Five requests per email per day.","operationId":"storefrontQuote","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"quoteNumber":{"type":"string"},"coffeeTotalPence":{"type":"integer"}}}}}},"400":{"description":"Validation error (`code: invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}},"429":{"description":"Throttled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}}}}},"/samples":{"post":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"Request samples by lot number","operationId":"storefrontSamples","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorefrontSampleRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"sampleNumber":{"type":"string"},"status":{"type":"string"},"itemCount":{"type":"integer"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}},"404":{"description":"Unknown lot number","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}},"409":{"description":"Sample limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/contact":{"post":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"Send a message from the shop","operationId":"storefrontContact","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"ref":{"type":"string"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/back-in-stock":{"post":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"Back-in-stock alert for a shop product","operationId":"storefrontBackInStock","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","product_handle","product_title"],"properties":{"email":{"type":"string","format":"email"},"product_handle":{"type":"string"},"product_title":{"type":"string"},"variant_id":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/tasting":{"post":{"security":[],"servers":[{"url":"https://gonzalezbrothers.coffee/apps/shop","description":"Storefront App Proxy — Shopify signs each request; call it through the shop domain."}],"tags":["Storefront"],"summary":"Book a cupping / tasting","operationId":"storefrontTasting","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","email","company","phone","location"],"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"company":{"type":"string"},"phone":{"type":"string"},"location":{"type":"string","maxLength":300},"note":{"type":"string","maxLength":2000}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"ref":{"type":"string"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyError"}}}}}}}},"components":{"securitySchemes":{"cognito":{"type":"openIdConnect","openIdConnectUrl":"https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_djUBehHp7/.well-known/openid-configuration","description":"Cognito access token (RS256, issuer `https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_djUBehHp7`). Scope names in the requirement lists are the ones this API enforces; see `x-scopes`."},"agentClient":{"type":"oauth2","description":"Machine-to-machine access for agents: a Cognito client-credentials client issued per integration. Request only the scopes the task needs; the API enforces them (403 `insufficient_scope` otherwise).","flows":{"clientCredentials":{"tokenUrl":"https://b2b-account-prod-api.auth.eu-west-2.amazoncognito.com/oauth2/token","scopes":{"https://api.gonzalezbrothers.coffee/catalog.read":"Read the catalog and lot detail without supplier contact or location data.","https://api.gonzalezbrothers.coffee/catalog.enriched":"Read the enriched catalog: full supplier records including contact and farm location.","https://api.gonzalezbrothers.coffee/orders.read":"List and read your own orders.","https://api.gonzalezbrothers.coffee/orders.write":"Place and cancel your own orders.","https://api.gonzalezbrothers.coffee/samples.read":"List and read your own sample requests.","https://api.gonzalezbrothers.coffee/samples.write":"Request samples against your account.","https://api.gonzalezbrothers.coffee/shortlist.read":"Read your shortlist.","https://api.gonzalezbrothers.coffee/shortlist.write":"Add lots to and remove lots from your shortlist.","https://api.gonzalezbrothers.coffee/account.read":"Read your profile and preferences.","https://api.gonzalezbrothers.coffee/account.write":"Update your profile, preferences and picture, or delete your account."}}}},"bearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"The same Cognito access token, for tooling that models it as a plain bearer."}},"responses":{"RateLimited":{"description":"Per-IP limit hit (fixed 60 s window). Honour `retry-after`. Every response from a limited route carries `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` and `RateLimit-Policy`.","content":{"text/plain":{"schema":{"type":"string","const":"Too Many Requests"}}},"headers":{"retry-after":{"schema":{"type":"integer"},"description":"Seconds until the window resets"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per window"},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current window"},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until the window resets"},"RateLimit-Policy":{"schema":{"type":"string"},"description":"`<limit>;w=60` — the window in seconds"}}},"Unauthorized":{"description":"Missing or invalid bearer token","headers":{"www-authenticate":{"schema":{"type":"string","const":"Bearer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"InsufficientScope":{"description":"The token lacks the scope this operation needs (RFC 6750 `insufficient_scope`)","headers":{"www-authenticate":{"schema":{"type":"string"},"description":"Bearer error=\"insufficient_scope\", scope=\"<the scope to request>\""}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"schemas":{"Problem":{"type":"object","description":"RFC 7807 problem details. `type` is `https://api.gonzalezbrothers.coffee/errors/<slug>`.","required":["type","title","status","detail"],"properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"},"rejectedItems":{"type":"array","items":{"type":"object","properties":{"coffeeLotId":{"type":"string"},"reason":{"type":"string"},"humanReason":{"type":"string"}}}}}},"ProxyError":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"code":{"type":"string"},"error":{"type":"string"}}},"Message":{"type":"object","required":["message"],"properties":{"message":{"type":"string"}}},"EmailOnly":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}},"ProtectedResourceMetadata":{"type":"object","required":["resource","authorization_servers","scopes_supported"],"properties":{"resource":{"type":"string","format":"uri"},"authorization_servers":{"type":"array","items":{"type":"string","format":"uri"}},"bearer_methods_supported":{"type":"array","items":{"type":"string"}},"scopes_supported":{"type":"array","items":{"type":"string"}},"resource_name":{"type":"string"},"resource_documentation":{"type":"string","format":"uri"}}},"SignupRequest":{"type":"object","required":["email","password","firstName","lastName","company","privacyPolicyAccepted"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"},"firstName":{"type":"string","maxLength":100},"lastName":{"type":"string","maxLength":100},"company":{"type":"string","maxLength":100},"phone":{"type":"string"},"privacyPolicyAccepted":{"type":"boolean","const":true},"newsletterSubscription":{"type":"boolean"}}},"Image":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"alt":{"type":"string"}},"additionalProperties":true},"Variety":{"type":"object","required":["id","name","species"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"species":{"type":"string"},"description":{"type":"string"}}},"CatalogItem":{"type":"object","description":"A green-coffee lot. The enriched form adds prices, inventory, flavour, certifications and the supplier record.","required":["id","title","lotNumber","inStock","sampleAvailable"],"properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"score":{"type":"number"},"inStock":{"type":"boolean"},"sampleAvailable":{"type":"boolean"},"lotNumber":{"type":"string"}},"additionalProperties":true},"MinimalCatalogResponse":{"type":"object","required":["success","responseType","data"],"properties":{"success":{"type":"boolean","const":true},"responseType":{"type":"string","const":"minimal"},"data":{"type":"array","items":{"$ref":"#/components/schemas/CatalogItem"}},"varieties":{"type":"array","items":{"$ref":"#/components/schemas/Variety"}}}},"EnrichedCatalogResponse":{"type":"object","required":["success","responseType","data"],"properties":{"success":{"type":"boolean","const":true},"responseType":{"type":"string","const":"enriched"},"data":{"type":"array","items":{"$ref":"#/components/schemas/CatalogItem"}}}},"SampleItem":{"type":"object","required":["coffeeLotId","sampleType"],"properties":{"coffeeLotId":{"type":"string","format":"uuid"},"sampleType":{"type":"string","enum":["green","roasted"]}}},"SampleRequestBody":{"type":"object","required":["items"],"properties":{"items":{"type":"array","minItems":1,"maxItems":3,"items":{"$ref":"#/components/schemas/SampleItem"}},"shippingAddress":{"type":"object","required":["addressLine1","city","postcode","country"],"properties":{"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"}},"description":"Authenticated callers only: ship somewhere other than the profile address."},"name":{"type":"string"},"email":{"type":"string","format":"email"},"company":{"type":"string"},"phone":{"type":"string"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"}},"description":"Guests must also send `name`, `email`, `company` and a delivery address."},"SampleSummary":{"type":"object","properties":{"id":{"type":"string"},"sampleNumber":{"type":"string"},"status":{"type":"string"},"itemCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}},"SampleRequest":{"type":"object","properties":{"id":{"type":"string"},"sampleNumber":{"type":"string"},"status":{"type":"string"},"itemCount":{"type":"integer"},"items":{"type":"array","items":{"type":"object","additionalProperties":true}},"shippingAddress":{"type":"object","additionalProperties":true},"trackingUrl":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"PlaceOrderRequest":{"type":"object","required":["lines"],"properties":{"lines":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","required":["coffeeLotId","bagSizeKg","quantity"],"properties":{"coffeeLotId":{"type":"string","format":"uuid"},"bagSizeKg":{"type":"integer","minimum":1},"quantity":{"type":"integer","minimum":1}}}},"notes":{"type":"string","maxLength":2000}}},"Order":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"orderNumber":{"type":"string"},"status":{"type":"string"},"lines":{"type":"array","items":{"type":"object","additionalProperties":true}},"createdAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"ShortlistItem":{"type":"object","required":["coffeeLotId","lotNumber","title","inStock","addedAt"],"properties":{"coffeeLotId":{"type":"string","format":"uuid"},"lotNumber":{"type":"string"},"title":{"type":"string"},"score":{"type":"number"},"price":{"type":"number"},"currency":{"type":"string"},"supplierName":{"type":"string"},"thumbnailUrl":{"type":"string","format":"uri"},"inStock":{"type":"boolean"},"addedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"Preferences":{"type":"object","required":["newsletterSubscription"],"properties":{"newsletterSubscription":{"type":"boolean"}}},"Profile":{"type":"object","properties":{"email":{"type":"string","format":"email","readOnly":true},"firstName":{"type":"string"},"lastName":{"type":"string"},"company":{"type":"string"},"phone":{"type":"string"},"country":{"type":"string"},"addressFirstLine":{"type":"string"},"addressSecondLine":{"type":"string"},"postcode":{"type":"string"},"city":{"type":"string"},"vatNumber":{"type":"string"},"shippingAddressFirstLine":{"type":"string"},"shippingAddressSecondLine":{"type":"string"},"shippingPostcode":{"type":"string"},"shippingCity":{"type":"string"},"shippingCountry":{"type":"string"},"shippingSameAsBilling":{"type":"boolean"},"newsletterSubscription":{"type":"boolean"},"profilePictureUrl":{"type":"string","format":"uri","readOnly":true}}},"ContactRequest":{"type":"object","required":["name","email","message"],"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"company":{"type":"string"},"phone":{"type":"string"},"message":{"type":"string"}}},"ChannelListing":{"type":"object","required":["channel","count","items"],"properties":{"channel":{"type":"string","enum":["retail","trade","green"]},"count":{"type":"integer"},"items":{"type":"array","items":{"type":"object","required":["handle","lotNumber"],"properties":{"handle":{"type":"string","description":"Shopify product handle: the shop page is `/products/{handle}`"},"lotNumber":{"type":"string"},"productName":{"type":"string"},"title":{"type":"string"},"pricePerKg":{"type":"number","description":"green: GBP per kilo"},"sampleAvailable":{"type":"boolean"},"sku1kg":{"type":"string"},"price1kg":{"type":"number"},"group":{"type":"string"},"packSizes":{"type":"array","items":{"type":"integer"}}}}}}},"RetailContent":{"type":"object","required":["handle","coffeeLotId","productName","inStock","channels","images"],"properties":{"handle":{"type":"string"},"coffeeLotId":{"type":"string","format":"uuid"},"productName":{"type":"string"},"inStock":{"type":"boolean"},"channels":{"type":"object","properties":{"retailShop":{"type":"boolean"},"tradeList":{"type":"boolean"}}},"farmer":{"type":"object","nullable":true,"additionalProperties":true},"origin":{"type":"object","nullable":true,"additionalProperties":true},"variety":{"type":"object","nullable":true,"additionalProperties":true},"process":{"type":"object","nullable":true,"additionalProperties":true},"roastLevel":{"type":"object","nullable":true,"additionalProperties":true},"images":{"type":"array","items":{"type":"string","format":"uri"}}}},"QuoteRequest":{"type":"object","required":["lines","channel","name","email","addressLine1","city","postcode","country"],"properties":{"lines":{"type":"array","minItems":1,"items":{"type":"object","required":["lotNumber","size","quantity"],"properties":{"lotNumber":{"type":"string"},"size":{"type":"string"},"quantity":{"type":"integer","minimum":1}}}},"channel":{"type":"string","enum":["trade","green"]},"name":{"type":"string"},"email":{"type":"string","format":"email"},"company":{"type":"string"},"phone":{"type":"string"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"}}},"StorefrontSampleRequest":{"type":"object","required":["lotNumbers","sampleType"],"properties":{"lotNumbers":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string"}},"sampleType":{"type":"string","enum":["green","roasted"]},"name":{"type":"string"},"email":{"type":"string","format":"email"},"company":{"type":"string"},"phone":{"type":"string"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"}},"description":"Guests send `name`, `email`, `company` and a delivery address; a signed-in trade customer ships to their profile."}}},"x-scopes":{"https://api.gonzalezbrothers.coffee/catalog.read":"Read the catalog and lot detail without supplier contact or location data.","https://api.gonzalezbrothers.coffee/catalog.enriched":"Read the enriched catalog: full supplier records including contact and farm location.","https://api.gonzalezbrothers.coffee/orders.read":"List and read your own orders.","https://api.gonzalezbrothers.coffee/orders.write":"Place and cancel your own orders.","https://api.gonzalezbrothers.coffee/samples.read":"List and read your own sample requests.","https://api.gonzalezbrothers.coffee/samples.write":"Request samples against your account.","https://api.gonzalezbrothers.coffee/shortlist.read":"Read your shortlist.","https://api.gonzalezbrothers.coffee/shortlist.write":"Add lots to and remove lots from your shortlist.","https://api.gonzalezbrothers.coffee/account.read":"Read your profile and preferences.","https://api.gonzalezbrothers.coffee/account.write":"Update your profile, preferences and picture, or delete your account."},"x-protected-resource-metadata":"https://api.gonzalezbrothers.coffee/.well-known/oauth-protected-resource"}