{ "openapi": "3.0.3", "info": { "title": "Cart Service API", "description": "HTTP API for shopping cart operations (cookie-based or explicit id): retrieve cart, add/replace items, update quantity, manage deliveries.", "version": "1.0.0" }, "servers": [ { "url": "https://cart.tornberg.me", "description": "Production server" }, { "url": "http://localhost:8080", "description": "Local development (cart API mounted under /cart)" } ], "paths": { "/cart": { "get": { "summary": "Get (or create) current cart (cookie based)", "description": "Returns the current cart. If no cartid cookie is present a new cart is created and Set-Cart-Id response header plus a Set-Cookie header are sent.", "responses": { "200": { "description": "Cart retrieved", "headers": { "Set-Cart-Id": { "description": "Returned when a new cart was created this request", "schema": { "type": "string" } }, "X-Pod-Name": { "description": "Pod identifier serving the request", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "500": { "description": "Server error" } } }, "post": { "summary": "Add single SKU (body)", "description": "Adds (or increases quantity of) a single SKU using request body.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddRequest" } } } }, "responses": { "200": { "description": "Item added", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid request body" }, "500": { "description": "Server error" } } }, "put": { "summary": "Change quantity of an item", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeQuantity" } } } }, "responses": { "200": { "description": "Quantity updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid request body" }, "500": { "description": "Server error" } } }, "delete": { "summary": "Clear cart cookie (logical cart reused only if referenced later)", "description": "Removes the cartid cookie by expiring it. Does not mutate server-side cart state.", "responses": { "200": { "description": "Cookie cleared (empty body)" } } } }, "/cart/add/{sku}": { "get": { "summary": "Add a SKU (path)", "description": "Adds a single SKU with implicit quantity 1. Country inferred from Host header (-se / -no).", "parameters": [{ "$ref": "#/components/parameters/SkuParam" }], "responses": { "200": { "description": "Item added", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "500": { "description": "Server error" } } } }, "/cart/add": { "post": { "summary": "Add multiple items (append)", "description": "Adds multiple items to the cart without clearing existing contents.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetCartItems" } } } }, "responses": { "200": { "description": "Items added", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/set": { "post": { "summary": "Replace cart contents", "description": "Clears the cart first, then adds the provided items (idempotent with respect to target set).", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetCartItems" } } } }, "responses": { "200": { "description": "Cart replaced", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/{itemId}": { "delete": { "summary": "Remove item by line id", "parameters": [ { "name": "itemId", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 0 }, "description": "Internal cart line item identifier (not SKU)." } ], "responses": { "200": { "description": "Item removed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Bad id" }, "500": { "description": "Server error" } } } }, "/cart/delivery": { "post": { "summary": "Set (add) delivery", "description": "Adds a delivery option referencing one or more line item ids.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetDeliveryRequest" } } } }, "responses": { "200": { "description": "Delivery added/updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/delivery/{deliveryId}": { "delete": { "summary": "Remove delivery", "parameters": [{ "$ref": "#/components/parameters/DeliveryIdParam" }], "responses": { "200": { "description": "Delivery removed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Bad id" }, "500": { "description": "Server error" } } } }, "/cart/delivery/{deliveryId}/pickupPoint": { "put": { "summary": "Set pickup point for delivery", "parameters": [{ "$ref": "#/components/parameters/DeliveryIdParam" }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PickupPoint" } } } }, "responses": { "200": { "description": "Pickup point set", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/voucher": { "put": { "summary": "Add voucher to cart", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddVoucherRequest" } } } }, "responses": { "200": { "description": "Voucher added", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/subscription-details": { "put": { "summary": "Upsert subscription details", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpsertSubscriptionDetails" } } } }, "responses": { "200": { "description": "Subscription details updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/voucher/{voucherId}": { "delete": { "summary": "Remove voucher from cart", "parameters": [{ "$ref": "#/components/parameters/VoucherIdParam" }], "responses": { "200": { "description": "Voucher removed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid id" }, "500": { "description": "Server error" } } } }, "/cart/byid/{id}": { "get": { "summary": "Get cart by explicit id", "parameters": [{ "$ref": "#/components/parameters/CartIdParam" }], "responses": { "200": { "description": "Cart retrieved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid id" }, "500": { "description": "Server error" } } }, "post": { "summary": "Add single SKU (body) by cart id", "parameters": [{ "$ref": "#/components/parameters/CartIdParam" }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddRequest" } } } }, "responses": { "200": { "description": "Item added", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } }, "put": { "summary": "Change quantity (by id variant)", "parameters": [{ "$ref": "#/components/parameters/CartIdParam" }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeQuantity" } } } }, "responses": { "200": { "description": "Quantity updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/byid/{id}/add/{sku}": { "get": { "summary": "Add SKU (path) by explicit cart id", "parameters": [ { "$ref": "#/components/parameters/CartIdParam" }, { "$ref": "#/components/parameters/SkuParam" } ], "responses": { "200": { "description": "Item added", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid id/sku" }, "500": { "description": "Server error" } } } }, "/cart/byid/{id}/{itemId}": { "delete": { "summary": "Remove item (by id variant)", "parameters": [ { "$ref": "#/components/parameters/CartIdParam" }, { "name": "itemId", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 0 } } ], "responses": { "200": { "description": "Item removed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid id" }, "500": { "description": "Server error" } } } }, "/cart/byid/{id}/delivery": { "post": { "summary": "Set delivery (by id variant)", "parameters": [{ "$ref": "#/components/parameters/CartIdParam" }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetDeliveryRequest" } } } }, "responses": { "200": { "description": "Delivery added/updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/byid/{id}/delivery/{deliveryId}": { "delete": { "summary": "Remove delivery (by id variant)", "parameters": [ { "$ref": "#/components/parameters/CartIdParam" }, { "$ref": "#/components/parameters/DeliveryIdParam" } ], "responses": { "200": { "description": "Delivery removed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid ids" }, "500": { "description": "Server error" } } } }, "/cart/byid/{id}/delivery/{deliveryId}/pickupPoint": { "put": { "summary": "Set pickup point (by id variant)", "parameters": [ { "$ref": "#/components/parameters/CartIdParam" }, { "$ref": "#/components/parameters/DeliveryIdParam" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PickupPoint" } } } }, "responses": { "200": { "description": "Pickup point updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/byid/{id}/voucher": { "put": { "summary": "Add voucher (by id variant)", "parameters": [{ "$ref": "#/components/parameters/CartIdParam" }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddVoucherRequest" } } } }, "responses": { "200": { "description": "Voucher added", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid body" }, "500": { "description": "Server error" } } } }, "/cart/byid/{id}/voucher/{voucherId}": { "delete": { "summary": "Remove voucher (by id variant)", "parameters": [ { "$ref": "#/components/parameters/CartIdParam" }, { "$ref": "#/components/parameters/VoucherIdParam" } ], "responses": { "200": { "description": "Voucher removed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CartGrain" } } } }, "400": { "description": "Invalid ids" }, "500": { "description": "Server error" } } } }, "/healthz": { "get": { "summary": "Liveness & capacity probe", "responses": { "200": { "description": "Healthy" }, "500": { "description": "Unhealthy" } } } }, "/readyz": { "get": { "summary": "Readiness probe", "responses": { "200": { "description": "Ready" } } } }, "/livez": { "get": { "summary": "Liveness probe", "responses": { "200": { "description": "Alive" } } } }, "/version": { "get": { "summary": "Service version", "responses": { "200": { "description": "Version string", "content": { "text/plain": { "schema": { "type": "string", "example": "1.0.0" } } } } } } } }, "components": { "parameters": { "SkuParam": { "name": "sku", "in": "path", "required": true, "schema": { "type": "string" } }, "CartIdParam": { "name": "id", "in": "path", "required": true, "description": "Base62 encoded cart id", "schema": { "type": "string", "pattern": "^[0-9A-Za-z]+$", "minLength": 1 } }, "DeliveryIdParam": { "name": "deliveryId", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 0 } }, "VoucherIdParam": { "name": "voucherId", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 0 } } }, "schemas": { "CartGrain": { "type": "object", "description": "Cart aggregate (actor state)", "properties": { "id": { "type": "string", "description": "Cart id (base62 encoded uint64)" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/CartItem" } }, "totalPrice": { "type": "integer", "format": "int64" }, "totalTax": { "type": "integer", "format": "int64" }, "totalDiscount": { "type": "integer", "format": "int64" }, "deliveries": { "type": "array", "items": { "$ref": "#/components/schemas/CartDelivery" } }, "processing": { "type": "boolean" }, "paymentInProgress": { "type": "boolean" }, "orderReference": { "type": "string" }, "paymentStatus": { "type": "string" }, "vouchers": { "type": "array", "items": { "$ref": "#/components/schemas/Voucher" } }, "subscriptionDetails": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/SubscriptionDetails" } } }, "required": ["id", "items", "totalPrice", "totalTax", "totalDiscount"] }, "CartItem": { "type": "object", "properties": { "id": { "type": "integer" }, "itemId": { "type": "integer" }, "parentId": { "type": "integer" }, "sku": { "type": "string" }, "name": { "type": "string" }, "price": { "type": "integer", "format": "int64" }, "totalPrice": { "type": "integer", "format": "int64" }, "totalTax": { "type": "integer", "format": "int64" }, "orgPrice": { "type": "integer", "format": "int64" }, "stock": { "type": "integer", "description": "0=OutOfStock,1=LowStock,2=InStock" }, "qty": { "type": "integer" }, "tax": { "type": "integer" }, "taxRate": { "type": "integer" }, "brand": { "type": "string" }, "category": { "type": "string" }, "category2": { "type": "string" }, "category3": { "type": "string" }, "category4": { "type": "string" }, "category5": { "type": "string" }, "disclaimer": { "type": "string" }, "sellerId": { "type": "string" }, "sellerName": { "type": "string" }, "type": { "type": "string", "description": "Article type" }, "image": { "type": "string" }, "outlet": { "type": "string", "nullable": true }, "storeId": { "type": "string", "nullable": true } }, "required": ["id", "sku", "name", "price", "qty", "tax"] }, "CartDelivery": { "type": "object", "properties": { "id": { "type": "integer" }, "provider": { "type": "string" }, "price": { "type": "integer", "format": "int64" }, "items": { "type": "array", "items": { "type": "integer" } }, "pickupPoint": { "$ref": "#/components/schemas/PickupPoint" } }, "required": ["id", "provider", "price", "items"] }, "PickupPoint": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string", "nullable": true }, "address": { "type": "string", "nullable": true }, "city": { "type": "string", "nullable": true }, "zip": { "type": "string", "nullable": true }, "country": { "type": "string", "nullable": true } }, "required": ["id"] }, "AddRequest": { "type": "object", "properties": { "quantity": { "type": "integer", "format": "int32", "minimum": 1, "default": 1 }, "sku": { "type": "string" }, "country": { "type": "string", "description": "Two-letter country code (inferred if omitted)" }, "storeId": { "type": "string", "nullable": true } }, "required": ["sku"] }, "ChangeQuantity": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64", "description": "Cart line item id" }, "quantity": { "type": "integer", "format": "int32", "minimum": 0 } }, "required": ["id", "quantity"] }, "Item": { "type": "object", "properties": { "sku": { "type": "string" }, "quantity": { "type": "integer", "minimum": 1 }, "storeId": { "type": "string", "nullable": true } }, "required": ["sku", "quantity"] }, "SetCartItems": { "type": "object", "properties": { "country": { "type": "string" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/Item" }, "minItems": 0 } }, "required": ["items"] }, "SetDeliveryRequest": { "type": "object", "properties": { "provider": { "type": "string" }, "items": { "type": "array", "items": { "type": "integer", "format": "int64" }, "description": "Line item ids served by this delivery" }, "pickupPoint": { "$ref": "#/components/schemas/PickupPoint" } }, "required": ["provider", "items"] }, "AddVoucherRequest": { "type": "object", "properties": { "code": { "type": "string" } }, "required": ["code"] }, "UpsertSubscriptionDetails": { "type": "object", "properties": { "id": { "type": "string" }, "offeringCode": { "type": "string" }, "signingType": { "type": "string" }, "data": { "type": "object" } }, "required": ["offeringCode", "signingType"] }, "Voucher": { "type": "object", "properties": { "code": { "type": "string" }, "applied": { "type": "boolean" }, "rules": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "id": { "type": "integer", "format": "int64" }, "value": { "type": "integer", "format": "int64" } }, "required": ["code", "applied", "rules", "id", "value"] }, "SubscriptionDetails": { "type": "object", "properties": { "id": { "type": "string" }, "offeringCode": { "type": "string" }, "signingType": { "type": "string" }, "data": { "type": "object" } }, "required": ["id"] } } }, "tags": [{ "name": "Cart" }, { "name": "Delivery" }, { "name": "System" }] }