# Exponata API Docs > Public Integration API documentation for Exponata This document contains the full content of all documentation pages for AI consumption. --- ## Exponata Public Integration API **URL:** https://docs.expo.wie.dev/docs **Description:** Integrate external systems with Exponata stores, expositions, expectations, protocols, photos, and fill-rate analytics. # Exponata Public Integration API Use this API to synchronize external store data and read protocol/photo analytics from Exponata. ## Base URL ```txt https://expo.wie.dev ``` ## Versioning All public integration routes are currently under `/v1`. --- ## OpenAPI **URL:** https://docs.expo.wie.dev/docs/openapi **Description:** Download and consume the OpenAPI 3.1 schema. # OpenAPI The OpenAPI 3.1 schema is published with this documentation site. ```bash curl https://docs.expo.wie.dev/openapi.json ``` --- ## Authentication **URL:** https://docs.expo.wie.dev/docs/authentication **Description:** Bearer token authentication for the public integration API. # Authentication Every request must include the configured integration token: ```http Authorization: Bearer ## Error envelope ```json { "error": { "code": "validation_failed", "message": "Request validation failed", "issues": [ { "path": "limit", "message": "Limit must be between 1 and 100", "code": "invalid_value" } ] } } ``` --- ## Exponata Public Integration API **URL:** https://docs.expo.wie.dev/docs/api-reference **Description:** Bearer-token protected API for external store, exposition, expectation, protocol, photo, and fill-rate integrations. { "openapi": "3.2.0", "info": { "title": "Exponata Public Integration API", "version": "1.0.0", "description": "Bearer-token protected API for external store, exposition, expectation, protocol, photo, and fill-rate integrations." }, "servers": [ { "url": "https://expo.wie.dev", "description": "Production" } ], "security": [ { "bearerAuth": [] } ], "tags": [ { "name": "Stores" }, { "name": "Contacts" }, { "name": "Expectations" }, { "name": "Expositions" }, { "name": "Protocols" }, { "name": "Photos" }, { "name": "Fill rates" } ], "paths": { "/v1/stores": { "get": { "tags": [ "Stores" ], "summary": "List stores", "parameters": [ { "$ref": "#/components/parameters/Limit100" }, { "name": "cursor", "in": "query", "schema": { "type": "string" }, "description": "External ID returned as nextCursor from the previous page." } ], "responses": { "200": { "description": "Paged stores", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StoreListResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "503": { "$ref": "#/components/responses/NotConfigured" } } } }, "/v1/stores/{externalId}": { "get": { "tags": [ "Stores" ], "summary": "Get a store by external ID", "parameters": [ { "$ref": "#/components/parameters/ExternalId" } ], "responses": { "200": { "description": "Store", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Store" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } }, "put": { "tags": [ "Stores" ], "summary": "Create or update a store by external ID", "parameters": [ { "$ref": "#/components/parameters/ExternalId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StoreUpsert" } } } }, "responses": { "200": { "description": "Upserted store", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Store" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" } } } }, "/v1/stores/{externalId}/contacts": { "get": { "tags": [ "Contacts" ], "summary": "List store contacts", "parameters": [ { "$ref": "#/components/parameters/ExternalId" } ], "responses": { "200": { "description": "Contacts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactListResponse" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } }, "put": { "tags": [ "Contacts" ], "summary": "Replace store contacts", "parameters": [ { "$ref": "#/components/parameters/ExternalId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceContacts" } } } }, "responses": { "200": { "description": "Replaced contacts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactListResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/v1/stores/{externalId}/expectations": { "get": { "tags": [ "Expectations" ], "summary": "List fill-rate expectations", "parameters": [ { "$ref": "#/components/parameters/ExternalId" } ], "responses": { "200": { "description": "Expectations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExpectationListResponse" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } }, "put": { "tags": [ "Expectations" ], "summary": "Replace fill-rate expectations", "parameters": [ { "$ref": "#/components/parameters/ExternalId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplaceExpectations" } } } }, "responses": { "200": { "description": "Replaced expectations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExpectationListResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/v1/stores/{externalId}/expositions": { "get": { "tags": [ "Expositions" ], "summary": "List store expositions", "parameters": [ { "$ref": "#/components/parameters/ExternalId" } ], "responses": { "200": { "description": "Expositions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExpositionListResponse" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } }, "put": { "tags": [ "Expositions" ], "summary": "Upsert store expositions", "parameters": [ { "$ref": "#/components/parameters/ExternalId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PutExpositions" } } } }, "responses": { "200": { "description": "Upserted expositions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExpositionListResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/v1/stores/{externalId}/protocols": { "get": { "tags": [ "Protocols" ], "summary": "List protocols for a store", "parameters": [ { "$ref": "#/components/parameters/ExternalId" }, { "$ref": "#/components/parameters/From" }, { "$ref": "#/components/parameters/To" }, { "$ref": "#/components/parameters/ProtocolStatus" }, { "$ref": "#/components/parameters/Limit100" } ], "responses": { "200": { "description": "Protocols", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProtocolListResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/v1/stores/{externalId}/protocols/{protocolId}": { "get": { "tags": [ "Protocols" ], "summary": "Get protocol details", "parameters": [ { "$ref": "#/components/parameters/ExternalId" }, { "name": "protocolId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Protocol", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProtocolDetail" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/v1/stores/{externalId}/photos": { "get": { "tags": [ "Photos" ], "summary": "List photos for a store", "parameters": [ { "$ref": "#/components/parameters/ExternalId" }, { "$ref": "#/components/parameters/From" }, { "$ref": "#/components/parameters/To" }, { "$ref": "#/components/parameters/Limit500" }, { "$ref": "#/components/parameters/ProtocolStatus" }, { "$ref": "#/components/parameters/ImageStatus" }, { "name": "protocolId", "in": "query", "schema": { "type": "string" } }, { "name": "expositionId", "in": "query", "schema": { "type": "string", "format": "uuid" } }, { "name": "cursor", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Photos", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PhotoListResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/v1/stores/{externalId}/fill-rates": { "get": { "tags": [ "Fill rates" ], "summary": "Get store fill rates", "parameters": [ { "$ref": "#/components/parameters/ExternalId" }, { "$ref": "#/components/parameters/From" }, { "$ref": "#/components/parameters/To" }, { "$ref": "#/components/parameters/ProtocolStatusWithDefault" }, { "name": "groupBy", "in": "query", "schema": { "type": "string", "enum": [ "protocol", "exposition", "category" ], "default": "protocol" } } ], "responses": { "200": { "description": "Fill-rate groups", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FillRateResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/v1/stores/{externalId}/expositions/{expositionId}/fill-rate": { "get": { "tags": [ "Fill rates" ], "summary": "Get exposition photo fill rates", "parameters": [ { "$ref": "#/components/parameters/ExternalId" }, { "name": "expositionId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "$ref": "#/components/parameters/From" }, { "$ref": "#/components/parameters/To" }, { "$ref": "#/components/parameters/ProtocolStatusWithDefault" } ], "responses": { "200": { "description": "Exposition fill rates", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExpositionFillRateResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" }, "404": { "$ref": "#/components/responses/NotFound" } } } }, "/v1/fill-rate": { "get": { "tags": [ "Fill rates" ], "summary": "Get cross-store fill rates", "parameters": [ { "$ref": "#/components/parameters/From" }, { "$ref": "#/components/parameters/To" }, { "$ref": "#/components/parameters/ProtocolStatusWithDefault" }, { "name": "groupBy", "in": "query", "schema": { "type": "string", "enum": [ "store", "region", "expositionType", "productCategory", "day", "week" ], "default": "store" } }, { "name": "externalIds", "in": "query", "schema": { "type": "string" }, "description": "Comma-separated external store IDs." }, { "name": "minFillRate", "in": "query", "schema": { "type": "number", "minimum": 0, "maximum": 100 } }, { "name": "maxFillRate", "in": "query", "schema": { "type": "number", "minimum": 0, "maximum": 100 } }, { "name": "belowExpectationOnly", "in": "query", "schema": { "type": "boolean", "default": false } } ], "responses": { "200": { "description": "Cross-store fill-rate groups", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CrossStoreFillRateResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationFailed" } } } } }, "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" } }, "parameters": { "ExternalId": { "name": "externalId", "in": "path", "required": true, "schema": { "type": "string" } }, "From": { "name": "from", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time" } }, "To": { "name": "to", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time" } }, "Limit100": { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 100 } }, "Limit500": { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 500, "default": 100 } }, "ProtocolStatus": { "name": "status", "in": "query", "schema": { "$ref": "#/components/schemas/ProtocolStatus" } }, "ProtocolStatusWithDefault": { "name": "status", "in": "query", "schema": { "allOf": [ { "$ref": "#/components/schemas/ProtocolStatus" } ], "default": "completed" } }, "ImageStatus": { "name": "status", "in": "query", "schema": { "$ref": "#/components/schemas/ImageStatus" } } }, "responses": { "ValidationFailed": { "description": "Validation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "Unauthorized": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "NotFound": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "NotConfigured": { "description": "API token is not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "schemas": { "Error": { "type": "object", "required": [ "error" ], "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "not_configured", "unauthorized", "validation_failed", "not_found" ] }, "message": { "type": "string" }, "issues": { "type": "array", "items": { "$ref": "#/components/schemas/Issue" } } } } } }, "Issue": { "type": "object", "required": [ "path", "message" ], "properties": { "path": { "type": "string" }, "message": { "type": "string" }, "code": { "type": "string" } } }, "StoreType": { "type": [ "string", "null" ], "enum": [ "Biuro", "Centrum Handlowe", "Dark Store", "Dworzec", "Kiosk", "Publiczny", "Stacja Benzynowa", "Ulica", null ] }, "ProtocolStatus": { "type": "string", "enum": [ "awaiting_submission", "awaiting_processing", "processing", "completed", "failed" ] }, "ImageStatus": { "type": "string", "enum": [ "pending", "uploaded", "annotating", "annotated", "evaluating", "completed", "failed" ] }, "ProductCategory": { "type": "string", "enum": [ "SANDWICHES", "SWEET_SNACKS", "SALTY_SNACKS", "SALADS_PASTES", "READY_MEALS", "DRINKS", "ROLLS", "BAGUETTES", "BREADS" ] }, "ExpositionType": { "type": "string", "enum": [ "FRIDGE_DRINKS", "FRIDGE_SALADS", "SANDWICHES_CHILLED_COUNTER", "SWEET_SNACKS_NEUTRAL_COUNTER", "SWEET_SNACKS_HEATED_COUNTER", "SALTY_SNACKS_NEUTRAL_COUNTER", "SALTY_SNACKS_HEATED_COUNTER", "SALTY_SNACKS_CHILLED_COUNTER", "SALADS_PASTES_GOURMET_RACK", "SALADS_PASTES_CHILLED_DISPLAY", "READY_MEALS_GOURMET_RACK", "READY_MEALS_CHILLED_DISPLAY", "READY_MEALS_NOT_OFFERED", "DRINKS_GOURMET_RACK", "DRINKS_CHILLED_DISPLAY", "DRINKS_DRINK_FRIDGE", "ROLLS_BREAD_RACK", "ROLLS_BACKBAR_CRATES", "ROLLS_BREAD_BASKETS", "ROLLS_NEUTRAL_COUNTER", "ROLLS_LIMITED_OFFER", "ROLLS_NOT_OFFERED", "BAGUETTES_BREAD_RACK", "BAGUETTES_BACKBAR_CRATES", "BAGUETTES_BREAD_BASKETS", "BAGUETTES_NEUTRAL_COUNTER", "BAGUETTES_LIMITED_OFFER", "BAGUETTES_NOT_OFFERED", "BREADS_BREAD_RACK", "BREADS_BACKBAR_CRATES", "BREADS_BREAD_BASKETS", "BREADS_NEUTRAL_COUNTER", "BREADS_LIMITED_OFFER", "BREADS_NOT_OFFERED" ] }, "OpeningTime": { "type": "object", "required": [ "weekday", "from", "to" ], "properties": { "weekday": { "type": "integer", "minimum": 0, "maximum": 6 }, "from": { "type": "string" }, "to": { "type": "string" } } }, "Store": { "type": "object", "required": [ "storeId", "externalId", "name", "location", "regionId", "storeType", "openingTimes", "protocolScheduleId", "protocolCronEnabled", "onboardingComplete", "loginCode" ], "properties": { "storeId": { "type": "string", "format": "uuid" }, "externalId": { "type": [ "string", "null" ] }, "name": { "type": "string" }, "location": { "type": [ "string", "null" ] }, "regionId": { "type": [ "string", "null" ], "format": "uuid" }, "storeType": { "$ref": "#/components/schemas/StoreType" }, "openingTimes": { "type": "array", "items": { "$ref": "#/components/schemas/OpeningTime" } }, "protocolScheduleId": { "type": "string", "format": "uuid" }, "protocolCronEnabled": { "type": "boolean" }, "onboardingComplete": { "type": "boolean" }, "loginCode": { "type": "string" } } }, "StoreUpsert": { "type": "object", "properties": { "externalId": { "type": "string" }, "name": { "type": "string" }, "location": { "type": [ "string", "null" ] }, "regionId": { "type": [ "string", "null" ], "format": "uuid" }, "storeType": { "$ref": "#/components/schemas/StoreType" }, "openingTimes": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/OpeningTime" } }, "protocolScheduleId": { "type": "string", "format": "uuid" }, "protocolCronEnabled": { "type": "boolean" }, "onboardingComplete": { "type": "boolean" }, "loginCode": { "type": "string" } } }, "StoreListResponse": { "type": "object", "required": [ "items", "nextCursor" ], "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Store" } }, "nextCursor": { "type": [ "string", "null" ] } } }, "Contact": { "type": "object", "required": [ "contactId", "contactType", "name", "phone", "email", "hasWhatsapp", "createdAt" ], "properties": { "contactId": { "type": "string", "format": "uuid" }, "contactType": { "type": "string", "enum": [ "store", "regional_manager" ] }, "name": { "type": "string" }, "phone": { "type": "string" }, "email": { "type": [ "string", "null" ], "format": "email" }, "hasWhatsapp": { "type": "boolean" }, "createdAt": { "type": "string", "format": "date-time" } } }, "ReplaceContacts": { "type": "object", "required": [ "contacts" ], "properties": { "contacts": { "type": "array", "items": { "type": "object", "required": [ "name", "phone" ], "properties": { "contactType": { "type": "string", "enum": [ "store", "regional_manager" ], "default": "store" }, "name": { "type": "string" }, "phone": { "type": "string" }, "email": { "type": [ "string", "null" ], "format": "email" }, "hasWhatsapp": { "type": "boolean", "default": false } } } } } }, "ContactListResponse": { "type": "object", "required": [ "externalId", "items" ], "properties": { "externalId": { "type": [ "string", "null" ] }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/Contact" } } } }, "Expectation": { "type": "object", "required": [ "expectationId", "productCategory", "displayType", "weekday", "protocolTime", "expectedFillRatio", "updatedAt" ], "properties": { "expectationId": { "type": "string", "format": "uuid" }, "productCategory": { "anyOf": [ { "$ref": "#/components/schemas/ProductCategory" }, { "type": "null" } ] }, "displayType": { "$ref": "#/components/schemas/ExpositionType" }, "weekday": { "type": "integer", "minimum": 0, "maximum": 6 }, "protocolTime": { "type": "string", "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$" }, "expectedFillRatio": { "type": "integer", "minimum": 0, "maximum": 100 }, "updatedAt": { "type": "string", "format": "date-time" } } }, "ReplaceExpectations": { "type": "object", "required": [ "expectations" ], "properties": { "expectations": { "type": "array", "items": { "$ref": "#/components/schemas/ExpectationInput" } } } }, "ExpectationInput": { "type": "object", "required": [ "productCategory", "displayType", "weekday", "protocolTime", "expectedFillRatio" ], "properties": { "productCategory": { "anyOf": [ { "$ref": "#/components/schemas/ProductCategory" }, { "type": "null" } ] }, "displayType": { "$ref": "#/components/schemas/ExpositionType" }, "weekday": { "type": "integer", "minimum": 0, "maximum": 6 }, "protocolTime": { "type": "string", "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$" }, "expectedFillRatio": { "type": "integer", "minimum": 0, "maximum": 100 } } }, "ExpectationListResponse": { "type": "object", "required": [ "externalId", "items" ], "properties": { "externalId": { "type": "string" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/Expectation" } } } }, "Exposition": { "type": "object", "required": [ "expositionId", "label", "friendlyTitle", "productCategories", "expositionType", "status" ], "properties": { "expositionId": { "type": "string", "format": "uuid" }, "label": { "type": "string" }, "friendlyTitle": { "type": [ "string", "null" ] }, "productCategories": { "type": "array", "items": { "$ref": "#/components/schemas/ProductCategory" } }, "expositionType": { "$ref": "#/components/schemas/ExpositionType" }, "status": { "type": "string", "enum": [ "active", "disabled" ] } } }, "PutExpositions": { "type": "object", "required": [ "expositions" ], "properties": { "expositions": { "type": "array", "maxItems": 500, "items": { "type": "object", "required": [ "label", "productCategories", "expositionType" ], "properties": { "expositionId": { "type": "string", "format": "uuid" }, "label": { "type": "string" }, "friendlyTitle": { "type": [ "string", "null" ] }, "productCategories": { "type": "array", "items": { "$ref": "#/components/schemas/ProductCategory" } }, "expositionType": { "$ref": "#/components/schemas/ExpositionType" }, "status": { "type": "string", "enum": [ "active", "disabled" ], "default": "active" } } } } } }, "ExpositionListResponse": { "type": "object", "required": [ "externalId", "storeId", "items" ], "properties": { "externalId": { "type": "string" }, "storeId": { "type": "string", "format": "uuid" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/Exposition" } } } }, "ProtocolSummary": { "type": "object", "additionalProperties": true }, "ProtocolDetail": { "allOf": [ { "$ref": "#/components/schemas/ProtocolSummary" }, { "type": "object", "properties": { "images": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } ] }, "ProtocolListResponse": { "type": "object", "required": [ "externalId", "items", "nextCursor" ], "properties": { "externalId": { "type": "string" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/ProtocolSummary" } }, "nextCursor": { "type": [ "string", "null" ] } } }, "PhotoListResponse": { "type": "object", "additionalProperties": true }, "FillRateResponse": { "type": "object", "additionalProperties": true }, "ExpositionFillRateResponse": { "type": "object", "additionalProperties": true }, "CrossStoreFillRateResponse": { "type": "object", "additionalProperties": true } } } } --- ## Links - [GitHub](https://github.com/asailabs/exponata) - [Support](mailto:support@wie.dev)