{ "openapi": "3.1.0", "info": { "title": "Persona Jewelry Storefront API", "version": "1.0.0", "summary": "Public read-only catalogue, search and cart endpoints for personajwlry.com.", "description": "Persona Jewelry sells minimalist, sport-inspired, engravable jewellery. These are the store's public endpoints for reading catalogue data. They are unauthenticated and read-only. Writing an order is deliberately not covered here: purchases go through the Universal Commerce Protocol endpoint documented at /llms.txt, and payment always requires explicit buyer approval.", "contact": { "name": "Persona Jewelry support", "email": "info@personajwlry.com", "url": "https:\/\/personajwlry.com\/pages\/contact" }, "license": { "name": "Proprietary content; endpoints provided by the Shopify storefront platform" } }, "servers": [ { "url": "https:\/\/personajwlry.com", "description": "Live storefront" } ], "externalDocs": { "description": "Agent guidance and when to use this store", "url": "https:\/\/personajwlry.com\/pages\/developers" }, "security": [ {} ], "tags": [ { "name": "catalog", "description": "Products and collections" }, { "name": "search", "description": "Storefront search" }, { "name": "cart", "description": "Session cart state" }, { "name": "graphql", "description": "Typed Storefront GraphQL API" } ], "paths": { "/products.json": { "get": { "operationId": "listProducts", "tags": ["catalog"], "summary": "List products", "description": "Returns the store's published products, newest first, including variants, options, images and prices. Prices are strings in the store's currency (CAD).", "parameters": [ { "name": "limit", "in": "query", "required": false, "description": "Products per page, 1-250. Defaults to 30.", "schema": { "type": "integer", "minimum": 1, "maximum": 250, "default": 30 } }, { "name": "page", "in": "query", "required": false, "description": "1-based page number.", "schema": { "type": "integer", "minimum": 1, "default": 1 } } ], "responses": { "200": { "description": "A page of products.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProductList" } } } }, "404": { "description": "Not found.", "content": { "text/html": { "schema": { "type": "string" } } } } } } }, "/products/{handle}.json": { "get": { "operationId": "getProductByHandle", "tags": ["catalog"], "summary": "Get one product", "description": "Returns a single product by its URL handle, for example footy-field-necklace-gold.", "parameters": [ { "name": "handle", "in": "path", "required": true, "description": "The product's URL handle.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "The product.", "content": { "application/json": { "schema": { "type": "object", "properties": { "product": { "$ref": "#/components/schemas/Product" } }, "required": ["product"] } } } }, "404": { "description": "No product with that handle." } } } }, "/collections.json": { "get": { "operationId": "listCollections", "tags": ["catalog"], "summary": "List collections", "description": "Returns published collections. Sport collections use the handles soccer-football, basketball, hockey, tennis, swimming-jewelry and track-field.", "parameters": [ { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 250, "default": 30 } } ], "responses": { "200": { "description": "A page of collections.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CollectionList" } } } } } } }, "/collections/{handle}/products.json": { "get": { "operationId": "listCollectionProducts", "tags": ["catalog"], "summary": "List products in a collection", "description": "Returns the products belonging to one collection. This is the reliable way to filter by sport: sport is modelled as collection membership, not as a product tag.", "parameters": [ { "name": "handle", "in": "path", "required": true, "description": "Collection handle, e.g. soccer-football.", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 250, "default": 30 } }, { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "default": 1 } } ], "responses": { "200": { "description": "A page of products in the collection.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProductList" } } } }, "404": { "description": "No collection with that handle." } } } }, "/search/suggest.json": { "get": { "operationId": "searchSuggest", "tags": ["search"], "summary": "Search the storefront", "description": "Free-text search across products, collections, pages and articles.", "parameters": [ { "name": "q", "in": "query", "required": true, "description": "The search term.", "schema": { "type": "string", "minLength": 1 } }, { "name": "resources[type]", "in": "query", "required": false, "description": "Comma-separated resource types to search.", "schema": { "type": "string", "example": "product,collection,page" } }, { "name": "resources[limit]", "in": "query", "required": false, "description": "Results per resource type, 1-10.", "schema": { "type": "integer", "minimum": 1, "maximum": 10, "default": 10 } } ], "responses": { "200": { "description": "Grouped search results.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuggestResponse" } } } }, "422": { "description": "Missing or invalid query parameters.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/cart.js": { "get": { "operationId": "getCart", "tags": ["cart"], "summary": "Get the current session cart", "description": "Returns the cart bound to the caller's session cookie. A caller with no cookie receives an empty cart. Served as text/javascript by the platform, with a JSON body.", "responses": { "200": { "description": "The current cart.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Cart" } } } } } } }, "/api/2025-01/graphql.json": { "post": { "operationId": "storefrontGraphql", "tags": ["graphql"], "summary": "Storefront GraphQL API", "description": "The typed Shopify Storefront API. Supports introspection, and every response carries extensions.cost with the query's computed cost, which is the rate-limiting signal to back off on. Prefer this over the .json endpoints when you need to select specific fields or paginate precisely.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GraphQLRequest" }, "example": { "query": "{ products(first: 5) { edges { node { handle title priceRange { minVariantPrice { amount currencyCode } } } } } }" } } } }, "responses": { "200": { "description": "GraphQL result. Field-level problems appear in `errors` with HTTP 200, per the GraphQL spec.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GraphQLResponse" } } } }, "430": { "description": "Shopify security rejection (throttling or blocked request)." } } } } }, "components": { "schemas": { "ProductList": { "type": "object", "required": ["products"], "properties": { "products": { "type": "array", "items": { "$ref": "#/components/schemas/Product" } } } }, "Product": { "type": "object", "required": ["id", "title", "handle", "variants"], "properties": { "id": { "type": "integer", "description": "Shopify product id." }, "title": { "type": "string" }, "handle": { "type": "string", "description": "URL slug; the stable identifier to use." }, "body_html": { "type": "string", "description": "Product description as HTML." }, "product_type": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Includes material, finish (gold/silver) and product type." }, "variants": { "type": "array", "items": { "$ref": "#/components/schemas/Variant" } }, "images": { "type": "array", "items": { "$ref": "#/components/schemas/Image" } }, "options": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "values": { "type": "array", "items": { "type": "string" } } } } } } }, "Variant": { "type": "object", "required": ["id", "title", "price", "available"], "properties": { "id": { "type": "integer" }, "title": { "type": "string", "description": "Option values joined by ' / ', e.g. '20\" - Bestseller / 1-3 Characters'." }, "price": { "type": "string", "description": "Decimal string in the store currency." }, "compare_at_price": { "type": ["string", "null"] }, "available": { "type": "boolean" }, "option1": { "type": ["string", "null"] }, "option2": { "type": ["string", "null"] } } }, "Image": { "type": "object", "properties": { "id": { "type": "integer" }, "src": { "type": "string", "format": "uri" }, "width": { "type": "integer" }, "height": { "type": "integer" }, "position": { "type": "integer", "description": "1 is the primary image; 2 is shown on hover." } } }, "CollectionList": { "type": "object", "required": ["collections"], "properties": { "collections": { "type": "array", "items": { "$ref": "#/components/schemas/Collection" } } } }, "Collection": { "type": "object", "properties": { "id": { "type": "integer" }, "handle": { "type": "string" }, "title": { "type": "string" }, "description": { "type": "string" }, "products_count": { "type": "integer" } } }, "SuggestResponse": { "type": "object", "properties": { "resources": { "type": "object", "properties": { "results": { "type": "object", "properties": { "products": { "type": "array", "items": { "$ref": "#/components/schemas/Product" } }, "collections": { "type": "array", "items": { "$ref": "#/components/schemas/Collection" } } } } } } } }, "Cart": { "type": "object", "properties": { "token": { "type": "string" }, "item_count": { "type": "integer" }, "total_price": { "type": "integer", "description": "In the currency's minor units (cents)." }, "currency": { "type": "string" }, "items": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer" }, "quantity": { "type": "integer" }, "title": { "type": "string" }, "properties": { "type": ["object", "null"], "description": "Line item properties such as Engraving and Font." } } } } } }, "GraphQLRequest": { "type": "object", "required": ["query"], "properties": { "query": { "type": "string" }, "variables": { "type": ["object", "null"] }, "operationName": { "type": ["string", "null"] } } }, "GraphQLResponse": { "type": "object", "properties": { "data": { "type": ["object", "null"] }, "errors": { "type": "array", "items": { "$ref": "#/components/schemas/Error" } }, "extensions": { "type": "object", "properties": { "cost": { "type": "object", "properties": { "requestedQueryCost": { "type": "integer" }, "actualQueryCost": { "type": "integer" } } } } } } }, "Error": { "type": "object", "properties": { "message": { "type": "string", "description": "Human-readable description of the problem." }, "extensions": { "type": "object", "properties": { "code": { "type": "string", "description": "Machine-readable error code." } } } } } } } }