diff --git a/adminapi.json b/adminapi.json
index 41b507a..e9abde8 100644
--- a/adminapi.json
+++ b/adminapi.json
@@ -77933,533 +77933,791 @@
}
}
},
- "/_action/order_transaction/{orderTransactionId}/state/{transition}": {
- "post": {
+ "/app-system/privileges/requested": {
+ "get": {
"tags": [
- "Order Management"
+ "App System"
],
- "summary": "Transition an order transaction to a new state",
- "description": "Changes the order transaction state and informs the customer via email if configured.",
- "operationId": "orderTransactionStateTransition",
- "parameters": [
- {
- "name": "orderTransactionId",
- "in": "path",
- "description": "Identifier of the order transaction.",
- "required": true,
- "schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
+ "summary": "Get requested privileges for all apps",
+ "description": "Returns the list of requested privileges for all apps. Requires admin scope and `acl_role:read` permission to read.",
+ "operationId": "getRequestedPrivileges",
+ "security": [
{
- "name": "transition",
- "in": "path",
- "description": "The `action_name` of the `state_machine_transition`. For example `process` if the order state should change from open to in progress.\n\nNote: If you choose a transition that is not available, you will get an error that lists possible transitions for the current state.",
- "required": true,
- "schema": {
- "type": "string"
- }
+ "oAuth": [
+ "admin"
+ ]
}
],
- "requestBody": {
- "required": false,
- "content": {
- "application/json": {
- "schema": {
- "properties": {
- "sendMail": {
- "description": "Controls if a mail should be sent to the customer."
- },
- "documentIds": {
- "description": "A list of document identifiers that should be attached",
- "type": "array",
- "items": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
- "mediaIds": {
- "description": "A list of media identifiers that should be attached",
- "type": "array",
- "items": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
+ "responses": {
+ "200": {
+ "description": "A JSON object containing requested privileges.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "privileges": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
}
- },
- "stateFieldName": {
- "description": "This is the state column within the order transaction database table. There should be no need to change it from the default.",
- "type": "string",
- "default": "stateId"
- },
- "internalComment": {
- "description": "An optional internal comment that will be saved with the state transition.",
- "type": "string"
}
},
- "type": "object"
+ "example": {
+ "privileges": {
+ "SwagAnalytics": [
+ "customer:read",
+ "order:read"
+ ],
+ "SwagExample": [
+ "product:write"
+ ]
+ }
+ }
}
}
- }
- },
- "responses": {
- "200": {
- "description": "Returns information about the transition that was made. `#/components/schemas/StateMachineTransition`"
- }
- }
- }
- },
- "/_info/openapi3.json": {
- "get": {
- "tags": [
- "System Info & Health Check"
- ],
- "summary": "Get OpenAPI Specification",
- "description": "Get information about the admin API in OpenAPI format.",
- "operationId": "api-info",
- "parameters": [
- {
- "name": "type",
- "in": "query",
- "description": "Type of the api",
- "schema": {
- "type": "string",
- "enum": [
- "jsonapi",
- "json"
- ]
- }
- }
- ],
- "responses": {
- "200": {
- "$ref": "#/components/responses/OpenApi3"
+ },
+ "400": {
+ "description": "Malformed request."
+ },
+ "401": {
+ "description": "Unauthorized Access."
+ },
+ "403": {
+ "description": "Forbidden. Not a valid integration source."
}
}
}
},
- "/_action/state-machine/{entityName}/{entityId}/state": {
+ "/app-system/{appName}/privileges/accepted": {
"get": {
"tags": [
- "State Machine"
+ "App System"
],
- "summary": "Get available transitions for an entity",
- "description": "Retrieves the available state transitions for the specified entity.",
- "operationId": "getEntityState",
+ "summary": "Get accepted privileges for an app",
+ "description": "Returns the list of accepted privileges for the current integration. Requires admin scope with an integration.",
+ "operationId": "getAcceptedPrivileges",
"parameters": [
{
- "name": "entityName",
+ "name": "appName",
"in": "path",
- "description": "Name of the entity.",
"required": true,
"schema": {
"type": "string"
}
- },
- {
- "name": "entityId",
- "in": "path",
- "description": "Identifier of the entity.",
- "required": true,
- "schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
+ }
+ ],
+ "security": [
{
- "name": "stateFieldName",
- "in": "query",
- "description": "This is the state column within the order delivery database table. There should be no need to change it from the default.",
- "required": false,
- "schema": {
- "type": "string",
- "default": "stateId"
- }
+ "oAuth": [
+ "admin"
+ ]
}
],
"responses": {
"200": {
- "description": "Available transitions for the current state.",
+ "description": "A JSON object containing accepted privileges.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
- "transitions": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "description": "The name of the transition."
- },
- "technicalName": {
- "type": "string",
- "description": "The technical name of the transition."
- },
- "actionName": {
- "type": "string",
- "description": "The action name of the transition."
- },
- "fromStateName": {
- "type": "string",
- "description": "The technical name of the state the transition starts from."
- },
- "toStateName": {
- "type": "string",
- "description": "The technical name of the state the transition goes to."
- },
- "url": {
- "type": "string",
- "description": "The URL to trigger the transition."
- }
- },
- "required": [
- "name",
- "technicalName",
- "actionName",
- "fromStateName",
- "toStateName",
- "url"
- ]
+ "privileges": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "boolean"
}
}
- },
- "required": [
- "transitions"
- ]
+ }
+ },
+ "example": {
+ "privileges": {
+ "customer:read": true,
+ "order:read": true
+ }
}
}
}
},
"400": {
- "description": "Unable to read the entity or entity field."
+ "description": "Malformed request."
+ },
+ "401": {
+ "description": "Unauthorized Access."
},
"403": {
- "description": "Forbidden. Missing privileges to access the entity."
+ "description": "Forbidden. Not a valid integration source."
+ },
+ "404": {
+ "description": "App not found."
}
}
}
},
- "/_action/state-machine/{entityName}/{entityId}/state/{transition}": {
- "post": {
+ "/app-system/{appName}/privileges": {
+ "patch": {
"tags": [
- "State Machine"
+ "App System"
],
- "summary": "Transition an entity to a new state",
- "description": "Changes the entity state by applying the given transition.",
- "operationId": "transitionEntityState",
+ "summary": "Accept or revoke privileges for an app",
+ "description": "Accepts or revokes specified privileges for the given app.",
+ "operationId": "managePrivileges",
"parameters": [
{
- "name": "entityName",
- "in": "path",
- "description": "Name of the entity.",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "entityId",
- "in": "path",
- "description": "Identifier of the entity.",
- "required": true,
- "schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
- {
- "name": "transition",
+ "name": "appName",
"in": "path",
- "description": "The `action_name` of the `state_machine_transition`.",
"required": true,
"schema": {
"type": "string"
}
- },
- {
- "name": "stateFieldName",
- "in": "query",
- "description": "This is the state column within the order delivery database table. There should be no need to change it from the default.",
- "required": false,
- "schema": {
- "type": "string",
- "default": "stateId"
- }
}
],
"requestBody": {
- "description": "Optional internal comment for the state transition.",
+ "required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
- "internalComment": {
- "type": "string",
- "description": "An optional internal comment that will be saved with the state transition."
+ "accept": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "revoke": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
}
}
+ },
+ "example": {
+ "accept": [
+ "customer:read",
+ "order:read"
+ ],
+ "revoke": [
+ "product:write"
+ ]
}
}
}
},
"responses": {
- "200": {
- "description": "State transition applied successfully."
+ "204": {
+ "description": "Returns no content if privileges were managed successfully."
},
"400": {
- "description": "Unable to read the entity or entity field, or invalid transition."
+ "description": "Malformed request."
+ },
+ "401": {
+ "description": "Unauthorized Access."
},
"403": {
- "description": "Forbidden. Missing privileges to access the entity."
+ "description": "Forbidden. Not a valid integration source."
+ },
+ "404": {
+ "description": "App not found."
}
- }
+ },
+ "security": [
+ {
+ "oAuth": [
+ "admin"
+ ]
+ }
+ ]
}
},
- "/_action/system-config": {
- "get": {
+ "/_action/app-system/secret/rotate": {
+ "post": {
"tags": [
- "System Config"
+ "App System"
],
- "summary": "Get configuration values",
- "description": "Returns the configuration values for the given domain and optional sales channel.",
- "operationId": "getConfigurationValues",
- "parameters": [
- {
- "name": "domain",
- "in": "query",
- "description": "The configuration domain.",
- "required": true,
- "schema": {
- "type": "string"
- }
+ "summary": "Initiate secret rotation for the calling app",
+ "description": "Initiates an app secret rotation for the calling app. Needs to be called with an integration token belonging to an app. Note that the secret rotation will only be scheduled and then handled asynchronously.",
+ "operationId": "appSecretRotation",
+ "responses": {
+ "202": {
+ "description": "Returns \"Accepted\" when secret rotation was scheduled."
},
- {
- "name": "salesChannelId",
- "in": "query",
- "description": "The sales channel ID to scope the configuration to.",
- "schema": {
- "type": "string"
- }
+ "400": {
+ "description": "Malformed request, e.g. when requested with non app integration source."
},
- {
- "name": "inherit",
- "in": "query",
- "description": "Whether to include inherited (global) values.",
- "schema": {
- "type": "boolean",
- "default": false
- }
+ "401": {
+ "description": "Unauthorized Access."
+ },
+ "403": {
+ "description": "Forbidden. Not a valid integration source."
+ },
+ "404": {
+ "description": "App not found."
}
- ],
- "responses": {
- "200": {
- "description": "Returns the configuration values as a key-value object."
+ },
+ "security": [
+ {
+ "oAuth": [
+ "admin"
+ ]
}
- }
- },
- "post": {
+ ]
+ }
+ },
+ "/app-system/shop/verify": {
+ "get": {
"tags": [
- "System Config"
+ "App System",
+ "Public"
],
- "summary": "Save configuration values",
- "description": "Saves the given configuration key-value pairs for the given sales channel.",
- "operationId": "saveConfiguration",
+ "summary": "Verify a shop's APP_URL",
+ "description": "Used to verify that a shop's APP_URL points to its self. The passed run ID and token are used to query the cache. It returns 204 no content if the given token can be verified using the run id.",
+ "operationId": "verifyAppUrl",
"parameters": [
{
- "name": "salesChannelId",
+ "name": "runId",
"in": "query",
- "description": "The sales channel ID to scope the configuration to.",
+ "description": "A unique identifier used to look up the token",
+ "required": true,
"schema": {
"type": "string"
}
},
{
- "name": "silent",
+ "name": "token",
"in": "query",
- "description": "If true, the HTTP cache will not be invalidated. Use this for internal configuration values that do not affect the storefront.",
+ "description": "A unique identifier",
+ "required": true,
"schema": {
- "type": "boolean",
- "default": false
+ "type": "string"
}
}
],
- "requestBody": {
- "description": "Key-value pairs of configuration values to save.",
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "additionalProperties": true
- }
- }
- }
- },
"responses": {
"204": {
- "description": "Configuration saved successfully."
+ "description": "An empty response signalling successful verification."
+ },
+ "400": {
+ "description": "Malformed request or unsuccessful verification."
}
}
}
},
- "/_action/system-config/check": {
- "get": {
+ "/_action/cache": {
+ "delete": {
"tags": [
- "System Config"
- ],
- "summary": "Check configuration",
- "description": "Checks if a configuration domain exists.",
- "operationId": "checkConfiguration",
- "parameters": [
- {
- "name": "domain",
- "in": "query",
- "description": "The configuration domain to check.",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
+ "System Operations"
],
+ "summary": "Clear caches",
+ "description": "The cache is immediately cleared synchronously for all used adapters.",
+ "operationId": "clearCache",
"responses": {
- "200": {
- "description": "Returns whether the configuration domain exists."
+ "204": {
+ "description": "Returns a no content response indicating that the cache has been cleared."
}
}
}
},
- "/_action/system-config/schema": {
- "get": {
+ "/_action/cache-delayed": {
+ "delete": {
"tags": [
- "System Config"
+ "System Operations"
],
- "summary": "Get configuration schema",
- "description": "Returns the configuration schema for the given domain.",
- "operationId": "getConfiguration",
+ "summary": "Clear all invalidated caches",
+ "description": "Directly triggers invalidation of all cache tags that were marked for invalidation.",
+ "operationId": "clearCacheDelayed",
"parameters": [
{
- "name": "domain",
+ "name": "refreshOpenSearch",
"in": "query",
- "description": "The configuration domain.",
- "required": true,
+ "required": false,
+ "description": "This parameter indicates that in addition to invalidating the delayed caches, the opensearch indices will also be refreshed, which should lead to a clean state on the next read requests. When OpenSearch is not used this parameter will be ignored.",
"schema": {
- "type": "string"
+ "type": "boolean",
+ "default": false
}
}
],
"responses": {
- "200": {
- "description": "Returns the configuration schema."
+ "204": {
+ "description": "Returns a no content response indicating that the cache has been cleared."
}
}
}
},
- "/_action/system-config/batch": {
- "post": {
+ "/_action/cache_info": {
+ "get": {
"tags": [
- "System Config"
- ],
- "summary": "Batch save configuration values",
- "description": "Saves configuration values for multiple sales channels at once. The request body is keyed by sales channel ID (use \"null\" for global scope).",
- "operationId": "batchSaveConfiguration",
- "parameters": [
- {
- "name": "silent",
- "in": "query",
- "description": "If true, the HTTP cache will not be invalidated. Use this for internal configuration values that do not affect the storefront.",
- "schema": {
- "type": "boolean",
- "default": false
- }
- }
+ "System Operations"
],
- "requestBody": {
- "description": "Object keyed by sales channel ID, each containing key-value pairs of configuration values.",
- "required": true,
+ "summary": "Get cache information",
+ "description": "Get information about the cache configuration",
+ "operationId": "info",
+ "responses": {
+ "200": {
+ "description": "Information about the cache state.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "required": [
+ "environment",
+ "httpCache",
+ "cacheAdapter",
+ "indexers"
+ ],
+ "properties": {
+ "environment": {
+ "description": "The active environment.",
+ "type": "string"
+ },
+ "httpCache": {
+ "description": "State of the HTTP cache.",
+ "type": "boolean"
+ },
+ "cacheAdapter": {
+ "description": "The active cache adapter.",
+ "type": "string"
+ },
+ "indexers": {
+ "description": "Normal-refresh indexers and their optional child updaters.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/_action/cleanup": {
+ "delete": {
+ "tags": [
+ "System Operations"
+ ],
+ "summary": "Clear old cache folders",
+ "description": "Removes cache folders that are not needed anymore.",
+ "operationId": "clearOldCacheFolders",
+ "responses": {
+ "204": {
+ "description": "Returns a no content response indicating that the cleanup finished."
+ }
+ }
+ }
+ },
+ "/_info/config": {
+ "get": {
+ "tags": [
+ "System Info & Health Check"
+ ],
+ "summary": "Get public runtime config & feature metadata",
+ "description": "Returns non-sensitive system/runtime metadata used by the administration UI for initialization, feature toggling, and diagnostics. Typical fields include platform/API version, active feature flags, environment mode, available capabilities (e.g. workers, queue, cache), limits, and other public configuration hints. Use this at admin startup to decide which features to enable and to display environment information.",
+ "operationId": "config",
+ "responses": {
+ "200": {
+ "description": "Public runtime configuration & feature metadata returned.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/infoConfigResponse"
+ },
+ "example": {
+ "version": "6.7.2.0",
+ "shopId": "NoiU8PfJtu7NBY8M",
+ "versionRevision": "98fcdbeab238fbef3b47bc258340124a1dba4852",
+ "adminWorker": {
+ "enableAdminWorker": true,
+ "enableNotificationWorker": true,
+ "transports": [
+ "webhook",
+ "async",
+ "low_priority"
+ ]
+ },
+ "bundles": {
+ "Administration": {
+ "css": [
+ "http://localhost:8000/bundles/administration/administration/assets/administration-DX5ywH2m.css"
+ ],
+ "js": [
+ "http://localhost:8000/bundles/administration/administration/assets/administration-DPiBX_LO.js"
+ ],
+ "baseUrl": null,
+ "type": "plugin"
+ },
+ "Storefront": {
+ "css": [
+ "http://localhost:8000/bundles/storefront/administration/assets/storefront-LFaCMnyI.css"
+ ],
+ "js": [
+ "http://localhost:8000/bundles/storefront/administration/assets/storefront-C-M6U7ZM.js"
+ ],
+ "baseUrl": null,
+ "type": "plugin"
+ }
+ },
+ "settings": {
+ "enableUrlFeature": true,
+ "appUrlReachable": true,
+ "appsRequireAppUrl": false,
+ "firstMigrationDate": "2025-01-01T12:00:00.000Z",
+ "private_allowed_extensions": [
+ "jpg",
+ "jpeg",
+ "png",
+ "webp",
+ "avif",
+ "gif",
+ "svg",
+ "bmp",
+ "tiff",
+ "tif",
+ "eps",
+ "webm",
+ "mkv",
+ "flv",
+ "ogv",
+ "ogg",
+ "mov",
+ "mp4",
+ "avi",
+ "wmv",
+ "pdf",
+ "aac",
+ "mp3",
+ "wav",
+ "flac",
+ "oga",
+ "wma",
+ "txt",
+ "doc",
+ "docx",
+ "ico",
+ "glb",
+ "zip",
+ "rar",
+ "csv",
+ "xls",
+ "xlsx",
+ "html",
+ "xml",
+ "epub"
+ ],
+ "private_allowed_mime_types_by_extension": {
+ "pdf": [
+ "application/pdf"
+ ],
+ "epub": [
+ "application/epub+zip"
+ ]
+ },
+ "enableHtmlSanitizer": true,
+ "enableStagingMode": false,
+ "disableExtensionManagement": false
+ },
+ "inAppPurchases": []
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/consents": {
+ "get": {
+ "tags": [
+ "Consent Management",
+ "Experimental"
+ ],
+ "summary": "List all consents for current user",
+ "description": "Returns a list of all available consents with their current status for the authenticated admin user. Each consent includes its name, identifier, and current state (requested, accepted, or revoked). Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "fetchConsents",
+ "responses": {
+ "200": {
+ "description": "List of consents with their status",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/ConsentState"
+ },
+ "example": {
+ "product_analytics": {
+ "name": "product_analytics",
+ "scopeName": "admin_user",
+ "identifier": "userId-12345",
+ "status": "accepted",
+ "actor": "userId-12345",
+ "updatedAt": "2024-01-15T10:20:30Z",
+ "acceptedUntil": "2024-01-15T10:20:30Z",
+ "acceptedRevision": "2026-02-01",
+ "latestRevision": "2026-02-01"
+ },
+ "backend_data": {
+ "name": "backend_data",
+ "scopeName": "system",
+ "identifier": "system",
+ "status": "unset",
+ "actor": null,
+ "updatedAt": null,
+ "acceptedUntil": null,
+ "acceptedRevision": null,
+ "latestRevision": null
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Unauthorized - User not logged in or invalid session"
+ }
+ }
+ }
+ },
+ "/consents/accept": {
+ "post": {
+ "tags": [
+ "Consent Management",
+ "Experimental"
+ ],
+ "summary": "Accept a consent",
+ "description": "Marks the specified consent as accepted for the authenticated admin user. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "acceptConsent",
+ "requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
- "additionalProperties": {
- "type": "object",
- "additionalProperties": true
+ "properties": {
+ "consent": {
+ "type": "string",
+ "description": "The name of the consent to accept"
+ },
+ "revision": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Optional accepted revision. Only the consent definition's latest revision is accepted. When omitted, the latest revision is used automatically."
+ }
+ },
+ "required": [
+ "consent"
+ ],
+ "example": {
+ "consent": "product_analytics",
+ "revision": "2026-02-01"
}
}
}
}
},
"responses": {
- "204": {
- "description": "Configuration saved successfully."
+ "200": {
+ "description": "Consent status changed successfully. Returns the updated consent status.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ConsentState"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request - Consent revision is invalid for current acceptance"
+ },
+ "404": {
+ "description": "Bad request - Consent not found or consent property was empty"
+ },
+ "401": {
+ "description": "Unauthorized - User not logged in or invalid session"
}
}
}
},
- "/_action/cleanup": {
+ "/consents/revoke": {
+ "post": {
+ "tags": [
+ "Consent Management",
+ "Experimental"
+ ],
+ "summary": "Revoke a consent",
+ "description": "Marks the specified consent as revoked for the authenticated admin user. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "revokeConsent",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "consent": {
+ "type": "string",
+ "description": "The name of the consent to accept"
+ }
+ },
+ "required": [
+ "consent"
+ ],
+ "example": {
+ "consent": "product_analytics"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Consent status changed successfully. Returns the updated consent status.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ConsentState"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Bad request - Consent not found or consent property was empty"
+ },
+ "401": {
+ "description": "Unauthorized - User not logged in or invalid session"
+ }
+ }
+ }
+ },
+ "/_action/container_cache": {
"delete": {
"tags": [
"System Operations"
],
- "summary": "Clear old cache folders",
- "description": "Removes cache folders that are not needed anymore.",
- "operationId": "clearOldCacheFolders",
+ "summary": "Clear container caches",
+ "description": "The container cache is immediately cleared synchronously.",
+ "operationId": "clearContainerCache",
"responses": {
"204": {
- "description": "Returns a no content response indicating that the cleanup finished."
+ "description": "Returns a no content response indicating that the container cache is cleared."
}
}
}
},
- "/_action/number-range/reserve/{type}/{saleschannel}": {
- "get": {
+ "/_action/customer-convert/{customerId}": {
+ "post": {
"tags": [
- "Number Range Management"
+ "Customer convert"
],
- "summary": "Reserve or preview a number-range / document number.",
- "description": "Reserves or previews the next value for a number range type, for example `order`, `customer`, `product`, or `document_invoice`. This route resolves the applicable number range by type and sales channel.\n\nThe generated number will be reserved and the number pointer will be incremented with every call. For preview purposes, add the `?preview=1` parameter to the request. In that case, the number will not be incremented.\n\nWhen editing an existing persisted number range and previewing its concrete state or unsaved pattern/start changes, use `/_action/number-range/{numberRangeId}/preview-pattern` instead.",
- "operationId": "numberRangeReserve",
+ "summary": "Convert guest customer to registered customer",
+ "description": "Converts an existing guest customer into a registered customer. If a password is provided, the customer can immediately log in using that password. If no password is provided, a password recovery email will be sent to the customer so they can set their password.",
+ "operationId": "convertGuestCustomer",
"parameters": [
{
- "name": "type",
+ "name": "customerId",
"in": "path",
- "description": "Technical name of the number range type, for example `order`, `customer`, `product`, or `document_invoice`.",
+ "description": "The id of the customer that should be converted.",
"required": true,
"schema": {
"type": "string"
}
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "description": "Optional data for the conversion process.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "password": {
+ "type": "string",
+ "description": "Optional password for the customer. If provided, the customer can log in immediately using this password. If omitted, a password recovery email will be sent."
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "204": {
+ "description": "Customer successfully converted to a registered customer."
},
- {
- "name": "saleschannel",
- "in": "path",
- "description": "Sales channel for the number range. Number ranges can be defined per sales channel, so you can pass a sales channel ID here.",
- "required": true,
- "schema": {
- "type": "string"
+ "401": {
+ "description": "The customer with the specified ID could not be found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/failure"
+ }
+ }
}
},
- {
- "name": "preview",
- "in": "query",
- "description": "If this parameter has a true value, the number will not actually be incremented, but only previewed.",
- "required": false,
- "schema": {
- "type": "boolean"
+ "400": {
+ "description": "The customer is not a guest, or the sales channel domain could not be found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/failure"
+ }
+ }
}
}
+ }
+ }
+ },
+ "/_proxy/generate-imitate-customer-token": {
+ "post": {
+ "tags": [
+ "Customer impersonation"
],
+ "summary": "Generate a customer impersonation token",
+ "description": "Generates a customer impersonation token for the given customer and sales channel.\n\nThe token can be used to authenticate as the customer in the sales channel.",
+ "operationId": "generateImitateCustomerToken",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "required": [
+ "customerId",
+ "salesChannelId"
+ ],
+ "properties": {
+ "customerId": {
+ "description": "ID of the customer",
+ "type": "string"
+ },
+ "salesChannelId": {
+ "description": "ID of the sales channel",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
"responses": {
"200": {
- "description": "The generated number",
+ "description": "The generated customer impersonation token.",
"content": {
"application/json": {
"schema": {
"properties": {
- "number": {
- "description": "The generated or previewed number range value.",
+ "token": {
+ "description": "The generated customer impersonation token",
"type": "string"
}
},
@@ -78467,26 +78725,23 @@
}
}
}
- },
- "400": {
- "description": "Number range not found"
}
}
}
},
- "/_action/number-range/{numberRangeId}/preview-pattern": {
+ "/_action/document/{documentId}/{deepLinkCode}": {
"get": {
"tags": [
- "Number Range Management"
+ "Document Management"
],
- "summary": "Preview a persisted number range",
- "description": "Previews the next value for a concrete persisted number range without incrementing its state. Optional `pattern` and `start` query parameters can be used to preview unsaved changes while editing the number range. Use `/_action/number-range/reserve/{type}` for actual allocation by business type and sales channel.",
- "operationId": "numberRangePreviewPatternById",
+ "summary": "Download a document",
+ "description": "Download a document by its identifier and deep link code.",
+ "operationId": "downloadDocument",
"parameters": [
{
- "name": "numberRangeId",
+ "name": "documentId",
"in": "path",
- "description": "Identifier of the number range to preview.",
+ "description": "Identifier of the document to be downloaded.",
"required": true,
"schema": {
"type": "string",
@@ -78494,261 +78749,94 @@
}
},
{
- "name": "pattern",
- "in": "query",
- "description": "Optional pattern override for the preview.",
- "required": false,
+ "name": "deepLinkCode",
+ "in": "path",
+ "description": "A unique hash code which was generated when the document was created.",
+ "required": true,
"schema": {
"type": "string"
}
},
{
- "name": "start",
+ "name": "download",
"in": "query",
- "description": "Optional start value override for the preview.",
- "required": false,
+ "description": "This parameter controls the `Content-Disposition` header. If set to `true` the header will be set to `attachment` else `inline`.",
"schema": {
- "type": "integer"
+ "type": "boolean",
+ "default": false
}
}
],
"responses": {
"200": {
- "description": "The previewed number",
+ "description": "The document.",
"content": {
- "application/json": {
+ "application/octet-stream": {
"schema": {
- "properties": {
- "number": {
- "description": "The previewed number.",
- "type": "string"
- }
- },
- "type": "object"
+ "type": "string",
+ "format": "binary"
}
}
}
- },
- "404": {
- "description": "Number range not found"
}
}
}
},
- "/_action/mail-template/send": {
+ "/_action/document/{documentId}/upload": {
"post": {
"tags": [
- "Mail Operations"
+ "Document Management"
],
- "summary": "Send a mail",
- "description": "Generates a mail and sends it to the customer. The mail content is rendered with data passed through the request.\n\nTake a look at the `salesChannel` entity for possible values. For example `{{ salesChannel.name }}` can be used.",
- "operationId": "send",
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "required": [
- "recipients",
- "salesChannelId",
- "contentHtml",
- "contentPlain",
- "subject"
+ "summary": "Upload a file for a document",
+ "description": "Uploads a file for a document. This prevents the document from being dynamically generated and delivers the uploaded file instead, when the document is downloaded.\n\nNote:\n* The document is required to be `static`\n* A document can only have one media file\n\nThe are two methods of providing a file to this route:\n * Use a typical file upload and provide the file in the request\n * Fetch the file from an url. This only works if the `shopware.media.enable_url_upload_feature` variable is set to true in the shop environment.\nTo use file upload via url, the content type has to be `application/json` and the parameter `url` has to be provided.",
+ "operationId": "uploadToDocument",
+ "parameters": [
+ {
+ "name": "documentId",
+ "in": "path",
+ "description": "Identifier of the document the new file should be added to.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ {
+ "name": "fileName",
+ "in": "query",
+ "description": "Name of the uploaded file.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "extension",
+ "in": "query",
+ "description": "Extension of the uploaded file. For example `pdf`",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/octet-stream": {
+ "schema": {
+ "type": "string",
+ "format": "binary"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "required": [
+ "url"
],
"properties": {
- "recipients": {
- "description": "A map of recipients with name and mail address.",
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- },
- "salesChannelId": {
- "description": "Identifier of the sales channel from which the mail should be send.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "contentHtml": {
- "description": "The content of the mail in HTML format.",
- "type": "string"
- },
- "contentPlain": {
- "description": "The content of the mail as plain text.",
- "type": "string"
- },
- "subject": {
- "description": "Subject of the mail.",
- "type": "string"
- },
- "senderName": {
- "description": "Name of the sender.",
+ "url": {
+ "description": "The url of the document that will be downloaded.",
"type": "string"
- },
- "senderEmail": {
- "description": "Mail address of the sender. If not set, `core.basicInformation.email` or `core.mailerSettings.senderAddress` will be used from the shop configuration.",
- "type": "string",
- "format": "email"
- },
- "mediaIds": {
- "description": "List of media identifiers which should be attached to the mail.",
- "type": "array",
- "items": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
- "documentIds": {
- "description": "List of document identifiers which should be attached to the mail.",
- "type": "array",
- "items": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
- "binAttachments": {
- "description": "A list of binary attachments which should be added to the mail.",
- "type": "array",
- "items": {
- "required": [
- "content",
- "fileName",
- "mimeType"
- ],
- "properties": {
- "content": {
- "description": "Binary content of the attachment.",
- "type": "string"
- },
- "fileName": {
- "description": "File name of the attachment.",
- "type": "string"
- },
- "mimeType": {
- "description": "Mime type of the attachment.",
- "type": "string"
- }
- },
- "type": "object"
- }
- },
- "recipientsBcc": {
- "description": "A mail address or a map of recipients with name and mail address to be set in BCC.",
- "oneOf": [
- {
- "type": "string",
- "format": "email"
- },
- {
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- }
- ]
- },
- "recipientsCc": {
- "description": "A mail address or a map of recipients with name and mail address to be set in CC.",
- "oneOf": [
- {
- "type": "string",
- "format": "email"
- },
- {
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- }
- ]
- },
- "replyTo": {
- "description": "A mail address or a map of mail addresses with name to be set in reply-to.",
- "oneOf": [
- {
- "type": "string",
- "format": "email"
- },
- {
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- }
- ]
- },
- "returnPath": {
- "description": "A mail address or a map of mail addresses with name to be set in return-path.",
- "oneOf": [
- {
- "type": "string",
- "format": "email"
- },
- {
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- }
- ]
- },
- "mailTemplateId": {
- "description": "Identifier of the mail template that should be used for attachments and sender defaults.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "mailTemplateData": {
- "description": "A map of available data that is used to fill the mail template. Values in this map override generated or entity-derived template data with the same top-level keys.",
- "type": "object",
- "additionalProperties": true,
- "example": {
- "salesChannel": {
- "name": "Storefront"
- }
- }
- },
- "testMode": {
- "description": "Enables mail test mode. The mail is still sent, but template rendering runs with the renderer's test mode enabled, a fallback `order.deepLinkCode` of `home` is injected when missing, and debug headers such as `X-Shopware-Language-Id` plus available event or sales-channel headers are added to the message.",
- "type": "boolean"
}
},
"type": "object"
@@ -78758,132 +78846,66 @@
},
"responses": {
"200": {
- "description": "The mail was sent successful",
+ "description": "Document uploaded successful",
"content": {
"application/json": {
"schema": {
- "required": [
- "size"
- ],
"properties": {
- "size": {
- "description": "Length of the email message",
- "type": "integer"
+ "documentId": {
+ "description": "Identifier of the document.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ },
+ "documentDeepLink": {
+ "description": "A unique hash code which is required to open the document.",
+ "type": "string"
}
},
"type": "object"
}
}
}
- },
- "400": {
- "description": "Invalid request data",
- "$ref": "#/components/responses/400"
}
}
}
},
- "/_action/mail-template/validate": {
- "post": {
+ "/_info/events.json": {
+ "get": {
"tags": [
- "Mail Operations"
+ "System Info & Health Check"
],
- "summary": "Validate a mail content",
- "description": "Validates if content for a mail can be rendered without sending an email.",
- "operationId": "validate",
- "deprecated": true,
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "required": [
- "contentHtml",
- "contentPlain"
- ],
- "properties": {
- "contentHtml": {
- "description": "The content of the mail in HTML format.",
- "type": "string"
- },
- "contentPlain": {
- "description": "The content of the mail as plain text.",
- "type": "string"
- }
- },
- "type": "object"
+ "summary": "Get Business events",
+ "description": "Get a list of about the business events.",
+ "operationId": "business-events",
+ "responses": {
+ "200": {
+ "description": "Returns a list of about the business events.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/businessEventsResponse"
+ }
}
}
}
- },
- "responses": {
- "204": {
- "description": "Returns a no content response indicating the mail content was rendered successfully."
- }
}
}
},
- "/_action/mail-template/build": {
- "post": {
+ "/_info/flow-actions.json": {
+ "get": {
"tags": [
- "Mail Operations"
+ "System Info & Health Check"
],
- "summary": "Build up a mail template",
- "description": "Generates a preview of a mail template when all the required data is passed through the request.",
- "operationId": "build",
- "deprecated": true,
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "required": [
- "mailTemplateType",
- "mailTemplate"
- ],
- "properties": {
- "mailTemplateType": {
- "description": "Only the property `templateData` is used. It provides additional variables to the templating engine.",
- "properties": {
- "templateData": {
- "description": "An associative array that is handed over to the templating engine and can be used as variables in the mail content.",
- "type": "object",
- "example": {
- "order": {
- "orderNumber": 5000,
- "customerName": "Example Customer"
- },
- "messageOfTheDay": "An apple a day keeps the doctor away!"
- },
- "additionalProperties": true
- }
- },
- "type": "object"
- },
- "mailTemplate": {
- "description": "The content of the mail as plain text.",
- "properties": {
- "contentHtml": {
- "description": "The content of the mail template in html format.",
- "type": "string",
- "example": "Hello {{ order.customerName }}, this is example mail content, the current date is {{ 'now'|date('d/m/Y') }}"
- }
- },
- "type": "object"
- }
- },
- "type": "object"
- }
- }
- }
- },
+ "summary": "Get actions for flow builder",
+ "description": "Get a list of action for flow builder.",
+ "operationId": "flow-actions",
"responses": {
"200": {
- "description": "The rendered simulation result of the mail template parts.",
+ "description": "Returns a list of action for flow builder.",
"content": {
"application/json": {
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/flowBuilderActionsResponse"
}
}
}
@@ -78891,87 +78913,75 @@
}
}
},
- "/_action/mail-template/simulate": {
- "post": {
+ "/_info/health-check": {
+ "get": {
"tags": [
- "Mail Operations"
+ "System Info & Health Check"
],
- "summary": "Simulate a mail template",
- "description": "Generates simulated data for a given event name and renders the provided mail template content against it.",
- "operationId": "simulateMailTemplate",
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "required": [
- "templateParts",
- "eventName"
- ],
- "properties": {
- "templateParts": {
- "description": "A map of mail template fields and their template content to render.",
- "type": "object",
- "additionalProperties": {
- "type": "string"
- },
- "example": {
- "subject": "Order {{ order.orderNumber }} confirmation",
- "senderName": "{{ salesChannel.name }}",
- "contentHtml": "
Hello {{ order.orderCustomer.firstName }}
",
- "contentPlain": "Hello {{ order.orderCustomer.firstName }}"
- }
- },
- "eventName": {
- "description": "The business event name used to generate simulated mail template data.",
- "type": "string",
- "example": "checkout.order.placed"
- },
- "salesChannelId": {
- "description": "Identifier of the sales channel that should be used for the simulate request.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "example": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a"
- },
- "strictRendering": {
- "description": "Enables strict variable rendering and surfaces errors for unknown variables. Defaults to `true`.",
- "type": "boolean",
- "default": true
- }
- },
- "type": "object"
- }
- }
+ "summary": "Check that the Application is running",
+ "operationId": "healthCheck",
+ "responses": {
+ "200": {
+ "description": "Returns empty response"
+ },
+ "500": {
+ "description": "Application is not working properly"
}
- },
+ }
+ }
+ },
+ "/_info/system-health-check": {
+ "get": {
+ "tags": [
+ "System Info & Health Check"
+ ],
+ "summary": "Perform a detailed system health check",
+ "operationId": "systemHealthCheck",
+ "parameters": [
+ {
+ "name": "verbose",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "Include detailed information in the response"
+ }
+ ],
"responses": {
"200": {
- "description": "The rendered preview of the mail template.",
+ "description": "Returns the system health check results",
"content": {
"application/json": {
"schema": {
"type": "object",
- "description": "A map of render results keyed by the same field names that were provided in the request's `templateParts` object.",
- "additionalProperties": {
- "type": "object",
- "required": [
- "type",
- "content"
- ],
- "properties": {
- "type": {
- "description": "The type of the render result (either `success` or `error`)",
- "type": "string",
- "enum": [
- "success",
- "error"
- ],
- "example": "success"
- },
- "content": {
- "description": "The rendered content of the mail template field. Also contains the error when rendering this field wasn't possible.",
- "type": "string",
- "example": "Example mail"
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "healthy": {
+ "type": "boolean"
+ },
+ "status": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "extra": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": true
+ }
+ }
+ }
}
}
}
@@ -78979,187 +78989,147 @@
}
}
},
- "400": {
- "description": "Invalid request data or invalid eventName",
- "$ref": "#/components/responses/400"
+ "500": {
+ "description": "Application is not working properly"
}
}
}
},
- "/_action/mail-template/preview": {
+ "/_action/increment/{pool}": {
"post": {
"tags": [
- "Mail Operations"
+ "Increment Storage"
+ ],
+ "summary": "Increment a value in the specified pool",
+ "description": "Increments a value by key in the specified increment pool. This operation increments the counter for the given key and returns a success response.",
+ "operationId": "incrementValue",
+ "parameters": [
+ {
+ "name": "pool",
+ "in": "path",
+ "description": "The name of the increment pool (e.g., 'user_activity', 'message_queue').",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "cluster",
+ "in": "query",
+ "description": "Optional cluster identifier for the increment operation.",
+ "required": false,
+ "schema": {
+ "type": "string"
+ }
+ }
],
- "summary": "Preview a mail template",
- "description": "Fetches the required data needed for the mail template and generates a preview.",
- "operationId": "mailTemplatePreview",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
+ "type": "object",
"required": [
- "mailTemplateId"
+ "key"
],
"properties": {
- "mailTemplateId": {
- "description": "Identifier of the mail template which should be rendered.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "example": "b3c4d5e6f7a8b90a1b2c3d4e5f678906"
- },
- "salesChannelId": {
- "description": "Identifier of the sales channel that should be used for the preview request.",
+ "key": {
"type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "example": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a"
- },
- "includeHeaderFooter": {
- "description": "Includes the sales channel mail header and footer in `contentHtml` and `contentPlain`. Defaults to `false`.",
- "type": "boolean",
- "default": false
- },
- "strictRendering": {
- "description": "Enables strict variable rendering and enables errors on e.g. unknown variables. Defaults to `false`.",
- "type": "boolean",
- "default": false
- },
- "entities": {
- "description": "A map of entity names and corresponding identifiers that define entities which should be used additionally during rendering.",
- "type": "object",
- "additionalProperties": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "example": {
- "order": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a",
- "customer": "a1b2c3d4e5f67890b3c4d5e6f7a8b90a"
- }
- },
- "templateData": {
- "description": "A map of template data that should be used additionally during rendering. Values in this map override generated or entity-derived template data with the same top-level keys.",
- "type": "object",
- "additionalProperties": true,
- "example": {
- "salesChannel": {
- "name": "Storefront"
- },
- "order": {
- "orderNumber": "SW10042"
- }
- }
+ "description": "The key to increment in the pool."
}
- },
- "type": "object"
+ }
}
}
}
},
"responses": {
"200": {
- "description": "The rendered preview of the mail template.",
+ "description": "Successfully incremented the value",
"content": {
"application/json": {
"schema": {
"type": "object",
- "required": [
- "subject",
- "senderName",
- "contentHtml",
- "contentPlain"
- ],
"properties": {
- "subject": {
- "type": "object",
- "required": [
- "type",
- "content"
- ],
- "properties": {
- "type": {
- "description": "The type of the render result (either `success` or `error`)",
- "type": "string",
- "enum": [
- "success",
- "error"
- ],
- "example": "success"
- },
- "content": {
- "description": "The rendered content of the mail template's subject. Also contains the error when rendering this field wasn't possible.",
- "type": "string",
- "example": "Example mail"
- }
- }
- },
- "senderName": {
- "type": "object",
- "required": [
- "type",
- "content"
- ],
- "properties": {
- "type": {
- "description": "The type of the render result (either `success` or `error`)",
- "type": "string",
- "enum": [
- "success",
- "error"
- ],
- "example": "success"
- },
- "content": {
- "description": "The rendered content of the mail template's sender name. Also contains the error when rendering this field wasn't possible.",
- "type": "string",
- "example": "Storefront"
- }
- }
- },
- "contentHtml": {
- "type": "object",
- "required": [
- "type",
- "content"
- ],
- "properties": {
- "type": {
- "description": "The type of the render result (either `success` or `error`)",
- "type": "string",
- "enum": [
- "success",
- "error"
- ],
- "example": "success"
- },
- "content": {
- "description": "The rendered content of the mail template in html format. Also contains the error when rendering this field wasn't possible.",
- "type": "string",
- "example": "Hello Mr. Mustermann,
this is example mail content, the current date is 16.03.2026.
"
- }
- }
- },
- "contentPlain": {
- "type": "object",
- "required": [
- "type",
- "content"
- ],
- "properties": {
- "type": {
- "description": "The type of the render result (either `success` or `error`)",
- "type": "string",
- "enum": [
- "success",
- "error"
- ],
- "example": "success"
- },
- "content": {
- "description": "The rendered content of the mail template in plain text format. Also contains the error when rendering this field wasn't possible.",
- "type": "string",
- "example": "Hello Mr. Mustermann, this is example mail content, the current date is 16.03.2026."
- }
+ "success": {
+ "type": "boolean",
+ "example": true
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request - key parameter missing or cluster parameter missing"
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Increment Storage"
+ ],
+ "summary": "List increment values from pool",
+ "description": "Retrieves a list of increment values from the specified pool with pagination support.",
+ "operationId": "getIncrementValues",
+ "parameters": [
+ {
+ "name": "pool",
+ "in": "path",
+ "description": "The name of the increment pool to list values from.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "cluster",
+ "in": "query",
+ "description": "Cluster identifier for the increment operation.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "description": "Maximum number of items to return.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 5,
+ "minimum": 1
+ }
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "description": "Number of items to skip for pagination.",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "List of increment values",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "type": "string",
+ "description": "The increment key"
+ },
+ "count": {
+ "type": "integer",
+ "description": "The current count value"
}
}
}
@@ -79168,371 +79138,174 @@
}
},
"400": {
- "description": "Invalid request data or invalid mailTemplateId",
- "$ref": "#/components/responses/400"
+ "description": "Bad request - cluster parameter missing"
}
}
}
},
- "/_action/mail-template/get-data-and-send": {
+ "/_action/decrement/{pool}": {
"post": {
"tags": [
- "Mail Operations"
+ "Increment Storage"
+ ],
+ "summary": "Decrement a value in the specified pool",
+ "description": "Decrements a value by key in the specified increment pool. This operation decrements the counter for the given key and returns a success response.",
+ "operationId": "decrementValue",
+ "parameters": [
+ {
+ "name": "pool",
+ "in": "path",
+ "description": "The name of the increment pool.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "cluster",
+ "in": "query",
+ "description": "Optional cluster identifier for the decrement operation.",
+ "required": false,
+ "schema": {
+ "type": "string"
+ }
+ }
],
- "summary": "Fetch the template data and send a mail",
- "description": "Generates the required data needed for the mail template, renders the mail content and sends it to the customer.",
- "operationId": "generateAndSendMail",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
+ "type": "object",
"required": [
- "mailTemplateId",
- "recipients",
- "salesChannelId"
+ "key"
],
"properties": {
- "mailTemplateId": {
- "description": "Identifier of the mail template which should be rendered.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "example": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a"
- },
- "recipients": {
- "description": "A map of recipients with name and mail address.",
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- },
- "salesChannelId": {
- "description": "Identifier of the sales channel from which the mail should be send.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "contentHtml": {
- "description": "The content of the mail in HTML format. If passed, this content will be used instead of the content from the mail template.",
- "type": "string"
- },
- "contentPlain": {
- "description": "The content of the mail as plain text. If passed, this content will be used instead of the content from the mail template.",
- "type": "string"
- },
- "subject": {
- "description": "Subject of the mail. If passed, this subject will be used instead of the subject from the mail template.",
- "type": "string"
- },
- "senderName": {
- "description": "Name of the sender. If passed, this sender name will be used instead of the sender name from the mail template.",
- "type": "string"
- },
- "senderEmail": {
- "description": "Mail address of the sender. If not set, `core.basicInformation.email` or `core.mailerSettings.senderAddress` will be used from the shop configuration.",
+ "key": {
"type": "string",
- "format": "email"
- },
- "mediaIds": {
- "description": "List of media identifiers which should be attached to the mail.",
- "type": "array",
- "items": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
- "documentIds": {
- "description": "List of document identifiers which should be attached to the mail.",
- "type": "array",
- "items": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
- "binAttachments": {
- "description": "A list of binary attachments which should be added to the mail.",
- "type": "array",
- "items": {
- "required": [
- "content",
- "fileName",
- "mimeType"
- ],
- "properties": {
- "content": {
- "description": "Binary content of the attachment.",
- "type": "string"
- },
- "fileName": {
- "description": "File name of the attachment.",
- "type": "string"
- },
- "mimeType": {
- "description": "Mime type of the attachment.",
- "type": "string"
- }
- },
- "type": "object"
- }
- },
- "recipientsBcc": {
- "description": "A mail address or a map of recipients with name and mail address to be set in BCC.",
- "oneOf": [
- {
- "type": "string",
- "format": "email"
- },
- {
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- }
- ]
- },
- "recipientsCc": {
- "description": "A mail address or a map of recipients with name and mail address to be set in CC.",
- "oneOf": [
- {
- "type": "string",
- "format": "email"
- },
- {
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- }
- ]
- },
- "replyTo": {
- "description": "A mail address or a map of mail addresses with name to be set in reply-to.",
- "oneOf": [
- {
- "type": "string",
- "format": "email"
- },
- {
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- }
- ]
- },
- "returnPath": {
- "description": "A mail address or a map of mail addresses with name to be set in return-path.",
- "oneOf": [
- {
- "type": "string",
- "format": "email"
- },
- {
- "type": "object",
- "example": {
- "test1@example.com": "Test user 1",
- "test2@example.com": "Test user 2"
- },
- "additionalProperties": {
- "description": "Name of the recipient. Can be null to omit the display name.",
- "type": [
- "string",
- "null"
- ]
- }
- }
- ]
- },
- "entities": {
- "description": "A map of entity names and corresponding identifiers that define entities which should be used additionally during rendering.",
- "type": "object",
- "additionalProperties": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "example": {
- "order": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a",
- "customer": "a1b2c3d4e5f67890b3c4d5e6f7a8b90a"
- }
- },
- "templateData": {
- "description": "A map of template data that should be used additionally during rendering. Values in this map override generated or entity-derived template data with the same top-level keys.",
- "type": "object",
- "additionalProperties": true,
- "example": {
- "salesChannel": {
- "name": "Storefront"
- },
- "order": {
- "orderNumber": "SW10042"
- }
- }
- },
- "testMode": {
- "description": "Enables mail test mode. The mail is still sent, but template rendering runs with the renderer's test mode enabled, a fallback `order.deepLinkCode` of `home` is injected when missing, and debug headers such as `X-Shopware-Language-Id` plus available event or sales-channel headers are added to the message.",
- "type": "boolean"
+ "description": "The key to decrement in the pool."
}
- },
- "type": "object"
+ }
}
}
}
},
"responses": {
"200": {
- "description": "The mail was sent successful",
+ "description": "Successfully decremented the value",
"content": {
"application/json": {
"schema": {
- "required": [
- "size"
- ],
+ "type": "object",
"properties": {
- "size": {
- "description": "Length of the email message",
- "type": "integer"
+ "success": {
+ "type": "boolean",
+ "example": true
}
- },
- "type": "object"
+ }
}
}
}
},
"400": {
- "description": "Invalid request data or invalid mailTemplateId",
- "$ref": "#/components/responses/400"
+ "description": "Bad request - key parameter missing or cluster parameter missing"
}
}
}
},
- "/_action/mail-template/available-variables": {
+ "/_action/reset-increment/{pool}": {
"post": {
"tags": [
- "Mail Operations"
+ "Increment Storage"
+ ],
+ "summary": "Reset increment values in pool",
+ "description": "Resets increment values in the specified pool. Can reset all values or a specific key if provided.",
+ "operationId": "resetIncrementValues",
+ "parameters": [
+ {
+ "name": "pool",
+ "in": "path",
+ "description": "The name of the increment pool to reset.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "cluster",
+ "in": "query",
+ "description": "Cluster identifier for the reset operation.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
],
- "summary": "Fetch the available variables for a business event and an optional parent variable path.",
- "description": "Fetches the available variables that a business event provides for a certain parent variable path to determine which variables can be used in a mail template.",
- "operationId": "mailTemplateAvailableVariables",
"requestBody": {
- "required": true,
+ "required": false,
"content": {
"application/json": {
"schema": {
- "required": [
- "eventName"
- ],
+ "type": "object",
"properties": {
- "eventName": {
- "description": "The business event name that provides the available variables.",
- "type": "string",
- "example": "checkout.order.placed"
- },
- "parentVariablePath": {
- "description": "The path to the parent field of which the available variables should be returned. If omitted or empty, the top-level variables of the business event are returned.",
+ "key": {
"type": "string",
- "example": "order.transactions"
+ "description": "Optional specific key to reset. If not provided, all values in the pool will be reset."
}
- },
- "type": "object"
+ }
}
}
}
},
"responses": {
"200": {
- "description": "The available variables got fetched successfully.",
+ "description": "Successfully reset the increment values",
"content": {
"application/json": {
"schema": {
- "items": {
- "type": "object",
- "required": [
- "fieldName",
- "hasChildren"
- ],
- "properties": {
- "fieldName": {
- "description": "The name of the variable.",
- "type": "string",
- "example": "salesChannel"
- },
- "hasChildren": {
- "description": "Shows if behind the variable are more nested variables which can be accessed by another request to this endpoint with the updated parent variable path: `.`",
- "type": "boolean",
- "example": true
- }
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean",
+ "example": true
}
- },
- "type": "array",
- "description": "A collection of the available variables which also show if behind the variables are more nested variables."
+ }
}
}
}
},
"400": {
- "description": "Invalid request data or invalid eventName",
- "$ref": "#/components/responses/400"
+ "description": "Bad request - cluster parameter missing"
}
}
}
},
- "/_action/integration/{integrationId}/mcp-allowlist": {
- "post": {
+ "/_action/delete-increment/{pool}": {
+ "delete": {
"tags": [
- "MCP",
- "Experimental"
+ "Increment Storage"
],
- "summary": "Save MCP allowlist for an integration",
- "description": "Saves the per-integration MCP allowlist covering tools, resources, and prompts. Pass `null` as the top-level value to allow all capabilities unrestricted. Pass an object with `tools`, `resources`, and `prompts` keys where each key is either `null` (unrestricted for that type) or a list of allowed names/URIs (empty array = deny all of that type). Requires `integration_mcp.editor` privilege. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "saveMcpAllowlist",
+ "summary": "Delete increment keys from pool",
+ "description": "Deletes specific increment keys from the specified pool.",
+ "operationId": "deleteIncrementKeys",
"parameters": [
{
- "name": "integrationId",
+ "name": "pool",
"in": "path",
+ "description": "The name of the increment pool to delete keys from.",
"required": true,
- "description": "The integration UUID.",
"schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
+ "type": "string"
}
- }
- ],
- "security": [
+ },
{
- "oAuth": [
- "write"
- ]
+ "name": "cluster",
+ "in": "query",
+ "description": "Cluster identifier for the delete operation.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
}
],
"requestBody": {
@@ -79542,67 +79315,15 @@
"schema": {
"type": "object",
"required": [
- "allowlist"
+ "keys"
],
"properties": {
- "allowlist": {
- "oneOf": [
- {
- "type": "object",
- "description": "Per-type allowlist. Each key is null (unrestricted) or a list of allowed names/URIs.",
- "properties": {
- "tools": {
- "oneOf": [
- {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "List of allowed tool names. Empty array = no tools allowed."
- },
- {
- "type": "null",
- "description": "Null = all tools allowed."
- }
- ]
- },
- "resources": {
- "oneOf": [
- {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "List of allowed resource URIs. Empty array = no resources allowed."
- },
- {
- "type": "null",
- "description": "Null = all resources allowed."
- }
- ]
- },
- "prompts": {
- "oneOf": [
- {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "List of allowed prompt names. Empty array = no prompts allowed."
- },
- {
- "type": "null",
- "description": "Null = all prompts allowed."
- }
- ]
- }
- }
- },
- {
- "type": "null",
- "description": "Null = all capabilities unrestricted."
- }
- ]
+ "keys": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Array of keys to delete from the pool."
}
}
}
@@ -79611,374 +79332,171 @@
},
"responses": {
"204": {
- "description": "Allowlist saved successfully."
+ "description": "Successfully deleted the increment keys"
},
"400": {
- "description": "Bad request — missing or invalid `allowlist` field."
- },
- "401": {
- "description": "Unauthorized — missing or invalid credentials."
- },
- "403": {
- "description": "Forbidden — caller lacks `integration_mcp.editor` privilege."
- },
- "404": {
- "description": "Integration not found."
+ "description": "Bad request - invalid keys parameter or cluster parameter missing"
}
}
}
},
- "/_action/user/{userId}/mcp-allowlist": {
+ "/_action/index-products": {
"post": {
"tags": [
- "MCP",
- "Experimental"
- ],
- "summary": "Save MCP allowlist for a user",
- "description": "Saves the per-user MCP allowlist covering tools, resources, and prompts. Pass `null` as the top-level value to allow all capabilities unrestricted. Pass an object with `tools`, `resources`, and `prompts` keys where each key is either `null` (unrestricted for that type) or a list of allowed names/URIs (empty array = deny all of that type). Requires `users_and_permissions.editor` privilege. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "saveMcpAllowlistUser",
- "parameters": [
- {
- "name": "userId",
- "in": "path",
- "required": true,
- "description": "The user UUID.",
- "schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- }
+ "System Operations"
],
- "security": [
- {
- "oAuth": [
- "write"
- ]
+ "summary": "Send product indexing message",
+ "description": "Dispatches a product indexing message to the message bus, with the provided ids",
+ "operationId": "productIndexing",
+ "responses": {
+ "204": {
+ "description": "Returns an empty response indicating that the message dispatched."
}
+ }
+ }
+ },
+ "/_action/index": {
+ "post": {
+ "tags": [
+ "System Operations"
],
+ "summary": "Run indexer",
+ "description": "Runs all registered indexer in the shop asynchronously.",
+ "operationId": "index",
"requestBody": {
- "required": true,
"content": {
"application/json": {
"schema": {
- "type": "object",
- "required": [
- "allowlist"
- ],
"properties": {
- "allowlist": {
- "oneOf": [
- {
- "type": "object",
- "description": "Per-type allowlist. Each key is null (unrestricted) or a list of allowed names/URIs.",
- "properties": {
- "tools": {
- "oneOf": [
- {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "List of allowed tool names. Empty array = no tools allowed."
- },
- {
- "type": "null",
- "description": "Null = all tools allowed."
- }
- ]
- },
- "resources": {
- "oneOf": [
- {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "List of allowed resource URIs. Empty array = no resources allowed."
- },
- {
- "type": "null",
- "description": "Null = all resources allowed."
- }
- ]
- },
- "prompts": {
- "oneOf": [
- {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "List of allowed prompt names. Empty array = no prompts allowed."
- },
- {
- "type": "null",
- "description": "Null = all prompts allowed."
- }
- ]
- }
- }
- },
- {
- "type": "null",
- "description": "Null = all capabilities unrestricted."
- }
- ]
+ "skip": {
+ "description": "Array of indexers/updaters to be skipped.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
}
- }
+ },
+ "type": "object"
}
}
}
},
"responses": {
"204": {
- "description": "Allowlist saved successfully."
- },
- "400": {
- "description": "Bad request — missing or invalid `allowlist` field."
- },
- "401": {
- "description": "Unauthorized — missing or invalid credentials."
- },
- "403": {
- "description": "Forbidden — caller lacks `users_and_permissions.editor` privilege."
- },
- "404": {
- "description": "User not found."
+ "description": "Returns a no content response indicating that the indexing progress startet."
}
}
}
},
- "/_action/mcp/tools": {
- "get": {
+ "/_action/indexing": {
+ "post": {
"tags": [
- "MCP",
- "Experimental"
+ "System Operations"
],
- "summary": "List registered MCP tools",
- "description": "Returns all MCP tools currently registered on this Shopware installation. For all capability types (tools, resources, prompts) use `GET /_action/mcp/capabilities` instead. Requires `integration.editor` privilege. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "mcpToolsList",
- "security": [
+ "summary": "Run indexer",
+ "description": "Runs all registered indexer in the shop asynchronously.",
+ "operationId": "indexing",
+ "responses": {
+ "200": {
+ "description": "Returns an empty response indicating that the indexing process started."
+ }
+ }
+ }
+ },
+ "/_action/indexing/{indexer}": {
+ "post": {
+ "tags": [
+ "System Operations"
+ ],
+ "summary": "Iterate an indexer",
+ "description": "Starts a defined indexer with an offset.\n\nfor the next request. `finish: true` in the response indicates that the indexer is finished",
+ "operationId": "iterate",
+ "parameters": [
{
- "oAuth": [
- "write"
- ]
+ "name": "indexer",
+ "in": "path",
+ "description": "Name of the indexer to iterate.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
}
],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "offset": {
+ "description": "The offset for the iteration.",
+ "type": "integer"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
"responses": {
"200": {
- "description": "Array of registered MCP tools.",
+ "description": "Returns information about the iteration.",
"content": {
"application/json": {
"schema": {
- "type": "array",
- "items": {
- "type": "object",
- "required": [
- "name"
- ],
- "properties": {
- "name": {
- "type": "string",
- "description": "Unique tool identifier used in `tools/call` requests.",
- "example": "shopware-entity-search"
- },
- "description": {
- "type": [
- "string",
- "null"
- ],
- "description": "Human-readable description of what the tool does.",
- "example": "Search Shopware entities and return matching records."
- },
- "dependencies": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "Tool names that are automatically included when this tool is selected."
- },
- "requiredPrivileges": {
- "oneOf": [
- {
- "type": "object",
- "properties": {
- "static": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "entityParam": {
- "type": [
- "string",
- "null"
- ]
- },
- "operations": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- {
- "type": "null"
- }
- ],
- "description": "ACL privileges required by this tool."
- }
+ "properties": {
+ "finish": {
+ "description": "Indicates if the indexing process finished.",
+ "type": "boolean"
+ },
+ "offset": {
+ "description": "Offset to be used for the next iteration.",
+ "type": "integer"
}
- }
+ },
+ "type": "object"
}
}
}
- },
- "401": {
- "description": "Unauthorized — missing or invalid credentials."
- },
- "403": {
- "description": "Forbidden — caller lacks `integration.editor` privilege."
}
}
}
},
- "/_action/mcp/capabilities": {
+ "/_info/routes": {
"get": {
+ "summary": "Get API routes",
+ "operationId": "getRoutes",
"tags": [
- "MCP",
- "Experimental"
- ],
- "summary": "List all registered MCP capabilities",
- "description": "Returns all registered MCP tools, resources, and prompts. Used by the Admin UI to populate the per-integration allowlist selector. Requires `integration.editor` privilege. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "mcpCapabilitiesList",
- "security": [
- {
- "oAuth": [
- "write"
- ]
- }
+ "System Info & Health Check"
],
"responses": {
"200": {
- "description": "Object containing all registered MCP capabilities.",
+ "description": "Successful operation",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
- "tools",
- "resources",
- "prompts"
+ "endpoints"
],
"properties": {
- "tools": {
+ "endpoints": {
"type": "array",
"items": {
"type": "object",
"required": [
- "name"
+ "methods",
+ "path"
],
"properties": {
- "name": {
- "type": "string",
- "example": "shopware-entity-search"
- },
- "description": {
- "type": [
- "string",
- "null"
- ]
- },
- "dependencies": {
+ "methods": {
"type": "array",
"items": {
"type": "string"
}
},
- "requiredPrivileges": {
- "oneOf": [
- {
- "type": "object",
- "properties": {
- "static": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "entityParam": {
- "type": [
- "string",
- "null"
- ]
- },
- "operations": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- {
- "type": "null"
- }
- ]
- }
- }
- }
- },
- "resources": {
- "type": "array",
- "items": {
- "type": "object",
- "required": [
- "uri",
- "name"
- ],
- "properties": {
- "uri": {
- "type": "string",
- "example": "shopware://entity-list"
- },
- "name": {
- "type": "string",
- "example": "shopware-entity-list"
- },
- "description": {
- "type": [
- "string",
- "null"
- ]
- },
- "mimeType": {
- "type": [
- "string",
- "null"
- ]
- }
- }
- }
- },
- "prompts": {
- "type": "array",
- "items": {
- "type": "object",
- "required": [
- "name"
- ],
- "properties": {
- "name": {
- "type": "string",
- "example": "shopware-context"
- },
- "description": {
- "type": [
- "string",
- "null"
- ]
+ "path": {
+ "type": "string"
}
}
}
@@ -79987,839 +79505,1129 @@
}
}
}
- },
- "401": {
- "description": "Unauthorized — missing or invalid credentials."
- },
- "403": {
- "description": "Forbidden — caller lacks `integration.editor` privilege."
}
}
}
},
- "/_mcp": {
+ "/_action/mail-template/send": {
"post": {
"tags": [
- "MCP",
- "Experimental"
- ],
- "summary": "MCP JSON-RPC endpoint",
- "description": "Handles Model Context Protocol (MCP) requests using the Streamable HTTP transport. Accepts JSON-RPC 2.0 messages for methods such as `initialize`, `tools/list`, `tools/call`, `prompts/list`, `prompts/get`, `resources/list`, and `resources/read`. Requires either an integration access key pair (`sw-access-key` + `sw-secret-access-key` headers) or a standard OAuth2 bearer token. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "mcpPost",
- "parameters": [
- {
- "name": "mcp-session-id",
- "in": "header",
- "required": false,
- "description": "Session ID returned by the server after `initialize`. Required for all requests except `initialize`.",
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "sw-access-key",
- "in": "header",
- "required": false,
- "description": "Integration access key for direct credential authentication (alternative to bearer token).",
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "sw-secret-access-key",
- "in": "header",
- "required": false,
- "description": "Integration secret access key. Required when `sw-access-key` is provided.",
- "schema": {
- "type": "string"
- }
- }
+ "Mail Operations"
],
+ "summary": "Send a mail",
+ "description": "Generates a mail and sends it to the customer. The mail content is rendered with data passed through the request.\n\nTake a look at the `salesChannel` entity for possible values. For example `{{ salesChannel.name }}` can be used.",
+ "operationId": "send",
"requestBody": {
"required": true,
- "description": "A JSON-RPC 2.0 request or batch.",
"content": {
"application/json": {
"schema": {
- "type": "object",
"required": [
- "jsonrpc",
- "method"
+ "recipients",
+ "salesChannelId",
+ "contentHtml",
+ "contentPlain",
+ "subject"
],
"properties": {
- "jsonrpc": {
+ "recipients": {
+ "description": "A map of recipients with name and mail address.",
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "salesChannelId": {
+ "description": "Identifier of the sales channel from which the mail should be send.",
"type": "string",
- "enum": [
- "2.0"
+ "pattern": "^[0-9a-f]{32}$"
+ },
+ "contentHtml": {
+ "description": "The content of the mail in HTML format.",
+ "type": "string"
+ },
+ "contentPlain": {
+ "description": "The content of the mail as plain text.",
+ "type": "string"
+ },
+ "subject": {
+ "description": "Subject of the mail.",
+ "type": "string"
+ },
+ "senderName": {
+ "description": "Name of the sender.",
+ "type": "string"
+ },
+ "senderEmail": {
+ "description": "Mail address of the sender. If not set, `core.basicInformation.email` or `core.mailerSettings.senderAddress` will be used from the shop configuration.",
+ "type": "string",
+ "format": "email"
+ },
+ "mediaIds": {
+ "description": "List of media identifiers which should be attached to the mail.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ "documentIds": {
+ "description": "List of document identifiers which should be attached to the mail.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ "binAttachments": {
+ "description": "A list of binary attachments which should be added to the mail.",
+ "type": "array",
+ "items": {
+ "required": [
+ "content",
+ "fileName",
+ "mimeType"
+ ],
+ "properties": {
+ "content": {
+ "description": "Binary content of the attachment.",
+ "type": "string"
+ },
+ "fileName": {
+ "description": "File name of the attachment.",
+ "type": "string"
+ },
+ "mimeType": {
+ "description": "Mime type of the attachment.",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "recipientsBcc": {
+ "description": "A mail address or a map of recipients with name and mail address to be set in BCC.",
+ "oneOf": [
+ {
+ "type": "string",
+ "format": "email"
+ },
+ {
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
]
},
- "id": {
+ "recipientsCc": {
+ "description": "A mail address or a map of recipients with name and mail address to be set in CC.",
"oneOf": [
{
- "type": "string"
+ "type": "string",
+ "format": "email"
},
{
- "type": "integer"
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ ]
+ },
+ "replyTo": {
+ "description": "A mail address or a map of mail addresses with name to be set in reply-to.",
+ "oneOf": [
+ {
+ "type": "string",
+ "format": "email"
},
{
- "type": "null"
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
}
]
},
- "method": {
+ "returnPath": {
+ "description": "A mail address or a map of mail addresses with name to be set in return-path.",
+ "oneOf": [
+ {
+ "type": "string",
+ "format": "email"
+ },
+ {
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ ]
+ },
+ "mailTemplateId": {
+ "description": "Identifier of the mail template that should be used for attachments and sender defaults.",
"type": "string",
- "example": "tools/call"
+ "pattern": "^[0-9a-f]{32}$"
},
- "params": {
+ "mailTemplateData": {
+ "description": "A map of available data that is used to fill the mail template. Values in this map override generated or entity-derived template data with the same top-level keys.",
"type": "object",
- "additionalProperties": true
+ "additionalProperties": true,
+ "example": {
+ "salesChannel": {
+ "name": "Storefront"
+ }
+ }
+ },
+ "testMode": {
+ "description": "Enables mail test mode. The mail is still sent, but template rendering runs with the renderer's test mode enabled, a fallback `order.deepLinkCode` of `home` is injected when missing, and debug headers such as `X-Shopware-Language-Id` plus available event or sales-channel headers are added to the message.",
+ "type": "boolean"
}
- }
+ },
+ "type": "object"
}
}
}
},
"responses": {
"200": {
- "description": "JSON-RPC response or Server-Sent Events stream for long-running operations.",
+ "description": "The mail was sent successful",
"content": {
"application/json": {
"schema": {
- "type": "object",
- "properties": {
- "jsonrpc": {
- "type": "string",
- "enum": [
- "2.0"
- ]
- },
- "id": {
- "oneOf": [
- {
- "type": "string"
- },
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ]
- },
- "result": {
- "type": "object",
- "additionalProperties": true
- },
- "error": {
- "type": "object",
- "properties": {
- "code": {
- "type": "integer"
- },
- "message": {
- "type": "string"
- }
- }
- }
- }
- }
- },
- "text/event-stream": {
- "itemSchema": {
- "type": "object",
- "description": "Parsed Server-Sent Events message. The `data` field contains a serialized JSON-RPC response object.",
+ "required": [
+ "size"
+ ],
"properties": {
- "event": {
- "type": "string"
- },
- "id": {
- "type": "string"
- },
- "retry": {
+ "size": {
+ "description": "Length of the email message",
"type": "integer"
- },
- "data": {
- "type": "string",
- "contentMediaType": "application/json",
- "contentSchema": {
- "type": "object",
- "properties": {
- "jsonrpc": {
- "type": "string",
- "enum": [
- "2.0"
- ]
- },
- "id": {
- "oneOf": [
- {
- "type": "string"
- },
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ]
- },
- "result": {
- "type": "object",
- "additionalProperties": true
- },
- "error": {
- "type": "object",
- "properties": {
- "code": {
- "type": "integer"
- },
- "message": {
- "type": "string"
- }
- }
- }
- }
- }
}
- }
- },
- "schema": {
- "type": "string",
- "description": "Server-Sent Events stream for streaming responses."
+ },
+ "type": "object"
}
}
}
},
- "401": {
- "description": "Unauthorized — missing or invalid credentials."
- },
- "429": {
- "description": "Too many requests — rate limit exceeded."
+ "400": {
+ "description": "Invalid request data",
+ "$ref": "#/components/responses/400"
}
}
- },
- "get": {
+ }
+ },
+ "/_action/mail-template/validate": {
+ "post": {
"tags": [
- "MCP",
- "Experimental"
+ "Mail Operations"
],
- "summary": "MCP SSE stream",
- "description": "Opens a Server-Sent Events stream for receiving server-initiated messages. Used by MCP clients that support the SSE transport variant. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "mcpGet",
- "parameters": [
- {
- "name": "mcp-session-id",
- "in": "header",
- "required": false,
- "schema": {
- "type": "string"
+ "summary": "Validate a mail content",
+ "description": "Validates if content for a mail can be rendered without sending an email.",
+ "operationId": "validate",
+ "deprecated": true,
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "required": [
+ "contentHtml",
+ "contentPlain"
+ ],
+ "properties": {
+ "contentHtml": {
+ "description": "The content of the mail in HTML format.",
+ "type": "string"
+ },
+ "contentPlain": {
+ "description": "The content of the mail as plain text.",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
}
}
- ],
- "responses": {
- "200": {
- "description": "Server-Sent Events stream.",
- "content": {
- "text/event-stream": {
- "itemSchema": {
- "type": "object",
- "description": "Parsed Server-Sent Events message. The `data` field contains a serialized MCP server message.",
- "properties": {
- "event": {
- "type": "string"
- },
- "id": {
- "type": "string"
- },
- "retry": {
- "type": "integer"
- },
- "data": {
- "type": "string",
- "contentMediaType": "application/json",
- "contentSchema": {
- "type": "object",
- "additionalProperties": true
- }
- }
- }
- },
- "schema": {
- "type": "string"
- }
- }
- }
- },
- "401": {
- "description": "Unauthorized."
- }
- }
- },
- "delete": {
- "tags": [
- "MCP",
- "Experimental"
- ],
- "summary": "Close MCP session",
- "description": "Terminates an active MCP session identified by the `mcp-session-id` header. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "mcpDelete",
- "parameters": [
- {
- "name": "mcp-session-id",
- "in": "header",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "204": {
- "description": "Session closed successfully."
- },
- "401": {
- "description": "Unauthorized."
- }
- }
- },
- "options": {
- "tags": [
- "MCP",
- "Experimental"
- ],
- "summary": "MCP CORS preflight",
- "description": "Handles CORS preflight requests for the MCP endpoint. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "mcpOptions",
+ },
"responses": {
"204": {
- "description": "CORS preflight accepted."
+ "description": "Returns a no content response indicating the mail content was rendered successfully."
}
}
}
},
- "/_action/customer-convert/{customerId}": {
+ "/_action/mail-template/build": {
"post": {
"tags": [
- "Customer convert"
- ],
- "summary": "Convert guest customer to registered customer",
- "description": "Converts an existing guest customer into a registered customer. If a password is provided, the customer can immediately log in using that password. If no password is provided, a password recovery email will be sent to the customer so they can set their password.",
- "operationId": "convertGuestCustomer",
- "parameters": [
- {
- "name": "customerId",
- "in": "path",
- "description": "The id of the customer that should be converted.",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
+ "Mail Operations"
],
+ "summary": "Build up a mail template",
+ "description": "Generates a preview of a mail template when all the required data is passed through the request.",
+ "operationId": "build",
+ "deprecated": true,
"requestBody": {
- "required": false,
- "description": "Optional data for the conversion process.",
+ "required": true,
"content": {
"application/json": {
"schema": {
- "type": "object",
+ "required": [
+ "mailTemplateType",
+ "mailTemplate"
+ ],
"properties": {
- "password": {
- "type": "string",
- "description": "Optional password for the customer. If provided, the customer can log in immediately using this password. If omitted, a password recovery email will be sent."
- }
- }
- }
- }
- }
- },
- "responses": {
- "204": {
- "description": "Customer successfully converted to a registered customer."
- },
- "401": {
- "description": "The customer with the specified ID could not be found.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/failure"
- }
- }
- }
- },
- "400": {
- "description": "The customer is not a guest, or the sales channel domain could not be found.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/failure"
- }
- }
- }
- }
- }
- }
- },
- "/consents": {
- "get": {
- "tags": [
- "Consent Management",
- "Experimental"
- ],
- "summary": "List all consents for current user",
- "description": "Returns a list of all available consents with their current status for the authenticated admin user. Each consent includes its name, identifier, and current state (requested, accepted, or revoked). Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "fetchConsents",
- "responses": {
- "200": {
- "description": "List of consents with their status",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "additionalProperties": {
- "$ref": "#/components/schemas/ConsentState"
- },
- "example": {
- "product_analytics": {
- "name": "product_analytics",
- "scopeName": "admin_user",
- "identifier": "userId-12345",
- "status": "accepted",
- "actor": "userId-12345",
- "updatedAt": "2024-01-15T10:20:30Z",
- "acceptedUntil": "2024-01-15T10:20:30Z",
- "acceptedRevision": "2026-02-01",
- "latestRevision": "2026-02-01"
+ "mailTemplateType": {
+ "description": "Only the property `templateData` is used. It provides additional variables to the templating engine.",
+ "properties": {
+ "templateData": {
+ "description": "An associative array that is handed over to the templating engine and can be used as variables in the mail content.",
+ "type": "object",
+ "example": {
+ "order": {
+ "orderNumber": 5000,
+ "customerName": "Example Customer"
+ },
+ "messageOfTheDay": "An apple a day keeps the doctor away!"
+ },
+ "additionalProperties": true
+ }
},
- "backend_data": {
- "name": "backend_data",
- "scopeName": "system",
- "identifier": "system",
- "status": "unset",
- "actor": null,
- "updatedAt": null,
- "acceptedUntil": null,
- "acceptedRevision": null,
- "latestRevision": null
- }
- }
- }
- }
- }
- },
- "401": {
- "description": "Unauthorized - User not logged in or invalid session"
- }
- }
- }
- },
- "/consents/accept": {
- "post": {
- "tags": [
- "Consent Management",
- "Experimental"
- ],
- "summary": "Accept a consent",
- "description": "Marks the specified consent as accepted for the authenticated admin user. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "acceptConsent",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "consent": {
- "type": "string",
- "description": "The name of the consent to accept"
+ "type": "object"
},
- "revision": {
- "type": [
- "string",
- "null"
- ],
- "description": "Optional accepted revision. Only the consent definition's latest revision is accepted. When omitted, the latest revision is used automatically."
+ "mailTemplate": {
+ "description": "The content of the mail as plain text.",
+ "properties": {
+ "contentHtml": {
+ "description": "The content of the mail template in html format.",
+ "type": "string",
+ "example": "Hello {{ order.customerName }}, this is example mail content, the current date is {{ 'now'|date('d/m/Y') }}"
+ }
+ },
+ "type": "object"
}
},
- "required": [
- "consent"
- ],
- "example": {
- "consent": "product_analytics",
- "revision": "2026-02-01"
- }
+ "type": "object"
}
}
}
},
"responses": {
"200": {
- "description": "Consent status changed successfully. Returns the updated consent status.",
+ "description": "The rendered simulation result of the mail template parts.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ConsentState"
+ "type": "string"
}
}
}
- },
- "400": {
- "description": "Bad request - Consent revision is invalid for current acceptance"
- },
- "404": {
- "description": "Bad request - Consent not found or consent property was empty"
- },
- "401": {
- "description": "Unauthorized - User not logged in or invalid session"
}
}
}
},
- "/consents/revoke": {
+ "/_action/mail-template/simulate": {
"post": {
"tags": [
- "Consent Management",
- "Experimental"
+ "Mail Operations"
],
- "summary": "Revoke a consent",
- "description": "Marks the specified consent as revoked for the authenticated admin user. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
- "operationId": "revokeConsent",
+ "summary": "Simulate a mail template",
+ "description": "Generates simulated data for a given event name and renders the provided mail template content against it.",
+ "operationId": "simulateMailTemplate",
"requestBody": {
+ "required": true,
"content": {
"application/json": {
"schema": {
- "type": "object",
+ "required": [
+ "templateParts",
+ "eventName"
+ ],
"properties": {
- "consent": {
+ "templateParts": {
+ "description": "A map of mail template fields and their template content to render.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "example": {
+ "subject": "Order {{ order.orderNumber }} confirmation",
+ "senderName": "{{ salesChannel.name }}",
+ "contentHtml": "Hello {{ order.orderCustomer.firstName }}
",
+ "contentPlain": "Hello {{ order.orderCustomer.firstName }}"
+ }
+ },
+ "eventName": {
+ "description": "The business event name used to generate simulated mail template data.",
"type": "string",
- "description": "The name of the consent to accept"
+ "example": "checkout.order.placed"
+ },
+ "salesChannelId": {
+ "description": "Identifier of the sales channel that should be used for the simulate request.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "example": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a"
+ },
+ "strictRendering": {
+ "description": "Enables strict variable rendering and surfaces errors for unknown variables. Defaults to `true`.",
+ "type": "boolean",
+ "default": true
}
},
- "required": [
- "consent"
- ],
- "example": {
- "consent": "product_analytics"
- }
+ "type": "object"
}
}
}
},
"responses": {
"200": {
- "description": "Consent status changed successfully. Returns the updated consent status.",
+ "description": "The rendered preview of the mail template.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ConsentState"
+ "type": "object",
+ "description": "A map of render results keyed by the same field names that were provided in the request's `templateParts` object.",
+ "additionalProperties": {
+ "type": "object",
+ "required": [
+ "type",
+ "content"
+ ],
+ "properties": {
+ "type": {
+ "description": "The type of the render result (either `success` or `error`)",
+ "type": "string",
+ "enum": [
+ "success",
+ "error"
+ ],
+ "example": "success"
+ },
+ "content": {
+ "description": "The rendered content of the mail template field. Also contains the error when rendering this field wasn't possible.",
+ "type": "string",
+ "example": "Example mail"
+ }
+ }
+ }
}
}
}
},
- "404": {
- "description": "Bad request - Consent not found or consent property was empty"
- },
- "401": {
- "description": "Unauthorized - User not logged in or invalid session"
+ "400": {
+ "description": "Invalid request data or invalid eventName",
+ "$ref": "#/components/responses/400"
}
}
}
},
- "/oauth/token": {
+ "/_action/mail-template/preview": {
"post": {
"tags": [
- "Authorization & Authentication"
+ "Mail Operations"
],
- "summary": "Fetch an access token",
- "description": "Fetch a access token that can be used to perform authenticated requests. For more information take a look at the [Authentication documentation](https://shopware.stoplight.io/docs/admin-api/docs/concepts/authentication-authorisation.md).",
- "operationId": "token",
+ "summary": "Preview a mail template",
+ "description": "Fetches the required data needed for the mail template and generates a preview.",
+ "operationId": "mailTemplatePreview",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
- "oneOf": [
- {
- "$ref": "#/components/schemas/OAuthPasswordGrant"
+ "required": [
+ "mailTemplateId"
+ ],
+ "properties": {
+ "mailTemplateId": {
+ "description": "Identifier of the mail template which should be rendered.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "example": "b3c4d5e6f7a8b90a1b2c3d4e5f678906"
},
- {
- "$ref": "#/components/schemas/OAuthRefreshTokenGrant"
+ "salesChannelId": {
+ "description": "Identifier of the sales channel that should be used for the preview request.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "example": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a"
},
- {
- "$ref": "#/components/schemas/OAuthClientCredentialsGrant"
+ "includeHeaderFooter": {
+ "description": "Includes the sales channel mail header and footer in `contentHtml` and `contentPlain`. Defaults to `false`.",
+ "type": "boolean",
+ "default": false
+ },
+ "strictRendering": {
+ "description": "Enables strict variable rendering and enables errors on e.g. unknown variables. Defaults to `false`.",
+ "type": "boolean",
+ "default": false
+ },
+ "entities": {
+ "description": "A map of entity names and corresponding identifiers that define entities which should be used additionally during rendering.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ },
+ "example": {
+ "order": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a",
+ "customer": "a1b2c3d4e5f67890b3c4d5e6f7a8b90a"
+ }
+ },
+ "templateData": {
+ "description": "A map of template data that should be used additionally during rendering. Values in this map override generated or entity-derived template data with the same top-level keys.",
+ "type": "object",
+ "additionalProperties": true,
+ "example": {
+ "salesChannel": {
+ "name": "Storefront"
+ },
+ "order": {
+ "orderNumber": "SW10042"
+ }
+ }
}
- ]
+ },
+ "type": "object"
}
}
}
},
"responses": {
"200": {
- "description": "Authorized successfully.",
+ "description": "The rendered preview of the mail template.",
"content": {
"application/json": {
"schema": {
+ "type": "object",
"required": [
- "token_type",
- "expires_in",
- "access_token"
+ "subject",
+ "senderName",
+ "contentHtml",
+ "contentPlain"
],
"properties": {
- "token_type": {
- "description": "Type of the token.",
- "type": "string"
+ "subject": {
+ "type": "object",
+ "required": [
+ "type",
+ "content"
+ ],
+ "properties": {
+ "type": {
+ "description": "The type of the render result (either `success` or `error`)",
+ "type": "string",
+ "enum": [
+ "success",
+ "error"
+ ],
+ "example": "success"
+ },
+ "content": {
+ "description": "The rendered content of the mail template's subject. Also contains the error when rendering this field wasn't possible.",
+ "type": "string",
+ "example": "Example mail"
+ }
+ }
},
- "expires_in": {
- "description": "Token lifetime in seconds.",
- "type": "integer"
+ "senderName": {
+ "type": "object",
+ "required": [
+ "type",
+ "content"
+ ],
+ "properties": {
+ "type": {
+ "description": "The type of the render result (either `success` or `error`)",
+ "type": "string",
+ "enum": [
+ "success",
+ "error"
+ ],
+ "example": "success"
+ },
+ "content": {
+ "description": "The rendered content of the mail template's sender name. Also contains the error when rendering this field wasn't possible.",
+ "type": "string",
+ "example": "Storefront"
+ }
+ }
},
- "access_token": {
- "description": "The access token that can be used for subsequent requests",
- "type": "string"
+ "contentHtml": {
+ "type": "object",
+ "required": [
+ "type",
+ "content"
+ ],
+ "properties": {
+ "type": {
+ "description": "The type of the render result (either `success` or `error`)",
+ "type": "string",
+ "enum": [
+ "success",
+ "error"
+ ],
+ "example": "success"
+ },
+ "content": {
+ "description": "The rendered content of the mail template in html format. Also contains the error when rendering this field wasn't possible.",
+ "type": "string",
+ "example": "Hello Mr. Mustermann,
this is example mail content, the current date is 16.03.2026.
"
+ }
+ }
},
- "refresh_token": {
- "description": "The refresh token that can be used to refresh the access token. This field is not returned on grant type `refresh_token`.",
- "type": "string"
+ "contentPlain": {
+ "type": "object",
+ "required": [
+ "type",
+ "content"
+ ],
+ "properties": {
+ "type": {
+ "description": "The type of the render result (either `success` or `error`)",
+ "type": "string",
+ "enum": [
+ "success",
+ "error"
+ ],
+ "example": "success"
+ },
+ "content": {
+ "description": "The rendered content of the mail template in plain text format. Also contains the error when rendering this field wasn't possible.",
+ "type": "string",
+ "example": "Hello Mr. Mustermann, this is example mail content, the current date is 16.03.2026."
+ }
+ }
}
- },
- "type": "object"
+ }
}
}
}
},
"400": {
+ "description": "Invalid request data or invalid mailTemplateId",
"$ref": "#/components/responses/400"
}
}
}
},
- "/oauth/sso/config": {
- "get": {
+ "/_action/mail-template/get-data-and-send": {
+ "post": {
"tags": [
- "Experimental",
- "SSO Login configuration"
+ "Mail Operations"
],
- "summary": "Experimental: Loads SSO login configuration.",
- "description": "Experimental: Loads the SSO login configuration to configure the forward to the Shopware SSO login page.",
+ "summary": "Fetch the template data and send a mail",
+ "description": "Generates the required data needed for the mail template, renders the mail content and sends it to the customer.",
+ "operationId": "generateAndSendMail",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "required": [
+ "mailTemplateId",
+ "recipients",
+ "salesChannelId"
+ ],
+ "properties": {
+ "mailTemplateId": {
+ "description": "Identifier of the mail template which should be rendered.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "example": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a"
+ },
+ "recipients": {
+ "description": "A map of recipients with name and mail address.",
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "salesChannelId": {
+ "description": "Identifier of the sales channel from which the mail should be send.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ },
+ "contentHtml": {
+ "description": "The content of the mail in HTML format. If passed, this content will be used instead of the content from the mail template.",
+ "type": "string"
+ },
+ "contentPlain": {
+ "description": "The content of the mail as plain text. If passed, this content will be used instead of the content from the mail template.",
+ "type": "string"
+ },
+ "subject": {
+ "description": "Subject of the mail. If passed, this subject will be used instead of the subject from the mail template.",
+ "type": "string"
+ },
+ "senderName": {
+ "description": "Name of the sender. If passed, this sender name will be used instead of the sender name from the mail template.",
+ "type": "string"
+ },
+ "senderEmail": {
+ "description": "Mail address of the sender. If not set, `core.basicInformation.email` or `core.mailerSettings.senderAddress` will be used from the shop configuration.",
+ "type": "string",
+ "format": "email"
+ },
+ "mediaIds": {
+ "description": "List of media identifiers which should be attached to the mail.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ "documentIds": {
+ "description": "List of document identifiers which should be attached to the mail.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ "binAttachments": {
+ "description": "A list of binary attachments which should be added to the mail.",
+ "type": "array",
+ "items": {
+ "required": [
+ "content",
+ "fileName",
+ "mimeType"
+ ],
+ "properties": {
+ "content": {
+ "description": "Binary content of the attachment.",
+ "type": "string"
+ },
+ "fileName": {
+ "description": "File name of the attachment.",
+ "type": "string"
+ },
+ "mimeType": {
+ "description": "Mime type of the attachment.",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "recipientsBcc": {
+ "description": "A mail address or a map of recipients with name and mail address to be set in BCC.",
+ "oneOf": [
+ {
+ "type": "string",
+ "format": "email"
+ },
+ {
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ ]
+ },
+ "recipientsCc": {
+ "description": "A mail address or a map of recipients with name and mail address to be set in CC.",
+ "oneOf": [
+ {
+ "type": "string",
+ "format": "email"
+ },
+ {
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ ]
+ },
+ "replyTo": {
+ "description": "A mail address or a map of mail addresses with name to be set in reply-to.",
+ "oneOf": [
+ {
+ "type": "string",
+ "format": "email"
+ },
+ {
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ ]
+ },
+ "returnPath": {
+ "description": "A mail address or a map of mail addresses with name to be set in return-path.",
+ "oneOf": [
+ {
+ "type": "string",
+ "format": "email"
+ },
+ {
+ "type": "object",
+ "example": {
+ "test1@example.com": "Test user 1",
+ "test2@example.com": "Test user 2"
+ },
+ "additionalProperties": {
+ "description": "Name of the recipient. Can be null to omit the display name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ ]
+ },
+ "entities": {
+ "description": "A map of entity names and corresponding identifiers that define entities which should be used additionally during rendering.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ },
+ "example": {
+ "order": "b3c4d5e6f7a8b90a1b2c3d4e5f67890a",
+ "customer": "a1b2c3d4e5f67890b3c4d5e6f7a8b90a"
+ }
+ },
+ "templateData": {
+ "description": "A map of template data that should be used additionally during rendering. Values in this map override generated or entity-derived template data with the same top-level keys.",
+ "type": "object",
+ "additionalProperties": true,
+ "example": {
+ "salesChannel": {
+ "name": "Storefront"
+ },
+ "order": {
+ "orderNumber": "SW10042"
+ }
+ }
+ },
+ "testMode": {
+ "description": "Enables mail test mode. The mail is still sent, but template rendering runs with the renderer's test mode enabled, a fallback `order.deepLinkCode` of `home` is injected when missing, and debug headers such as `X-Shopware-Language-Id` plus available event or sales-channel headers are added to the message.",
+ "type": "boolean"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
"responses": {
"200": {
- "description": "Experimental: Returns the configuration for the SSO login page forward.",
+ "description": "The mail was sent successful",
"content": {
"application/json": {
"schema": {
- "type": "object",
+ "required": [
+ "size"
+ ],
"properties": {
- "useDefault": {
- "description": "Experimental: Indicates which login is used. Default or SSO.",
- "type": "boolean"
- },
- "url": {
- "description": "Experimental: Contains the return url for the Shopware SSO login.",
- "type": "string"
+ "size": {
+ "description": "Length of the email message",
+ "type": "integer"
}
- }
+ },
+ "type": "object"
}
}
}
+ },
+ "400": {
+ "description": "Invalid request data or invalid mailTemplateId",
+ "$ref": "#/components/responses/400"
}
- },
- "operationId": "loadSsoLoginConfig"
+ }
}
},
- "/oauth/sso/code": {
- "get": {
+ "/_action/mail-template/available-variables": {
+ "post": {
"tags": [
- "Experimental",
- "SSO Login callback"
+ "Mail Operations"
],
- "summary": "Experimental: Callback for SSO login",
- "description": "Experimental: Logs in the user into the Shopware shop and forwards to the admin",
+ "summary": "Fetch the available variables for a business event and an optional parent variable path.",
+ "description": "Fetches the available variables that a business event provides for a certain parent variable path to determine which variables can be used in a mail template.",
+ "operationId": "mailTemplateAvailableVariables",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "required": [
+ "eventName"
+ ],
+ "properties": {
+ "eventName": {
+ "description": "The business event name that provides the available variables.",
+ "type": "string",
+ "example": "checkout.order.placed"
+ },
+ "parentVariablePath": {
+ "description": "The path to the parent field of which the available variables should be returned. If omitted or empty, the top-level variables of the business event are returned.",
+ "type": "string",
+ "example": "order.transactions"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
"responses": {
"200": {
- "description": "Authorisation process continues",
+ "description": "The available variables got fetched successfully.",
"content": {
"application/json": {
"schema": {
- "type": "object"
+ "items": {
+ "type": "object",
+ "required": [
+ "fieldName",
+ "hasChildren"
+ ],
+ "properties": {
+ "fieldName": {
+ "description": "The name of the variable.",
+ "type": "string",
+ "example": "salesChannel"
+ },
+ "hasChildren": {
+ "description": "Shows if behind the variable are more nested variables which can be accessed by another request to this endpoint with the updated parent variable path: `.`",
+ "type": "boolean",
+ "example": true
+ }
+ }
+ },
+ "type": "array",
+ "description": "A collection of the available variables which also show if behind the variables are more nested variables."
}
}
}
},
- "302": {
- "description": "Experimental: Forwards to the Shopware admin"
+ "400": {
+ "description": "Invalid request data or invalid eventName",
+ "$ref": "#/components/responses/400"
}
- },
- "operationId": "callBackWithCode"
+ }
}
},
- "/_action/order/{orderId}/order-address": {
+ "/_action/integration/{integrationId}/mcp-allowlist": {
"post": {
"tags": [
- "Order address"
+ "MCP",
+ "Experimental"
],
- "summary": "Update order addresses",
- "description": "Endpoint which takes a list of mapping objects as payload and updates the order addresses accordingly",
- "operationId": "updateOrderAddresses",
+ "summary": "Save MCP allowlist for an integration",
+ "description": "Saves the per-integration MCP allowlist covering tools, resources, and prompts. Pass `null` as the top-level value to allow all capabilities unrestricted. Pass an object with `tools`, `resources`, and `prompts` keys where each key is either `null` (unrestricted for that type) or a list of allowed names/URIs (empty array = deny all of that type). Requires `integration_mcp.editor` privilege. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "saveMcpAllowlist",
"parameters": [
{
- "name": "orderId",
+ "name": "integrationId",
"in": "path",
- "description": "Identifier of the order.",
"required": true,
+ "description": "The integration UUID.",
"schema": {
"type": "string",
"pattern": "^[0-9a-f]{32}$"
}
}
],
+ "security": [
+ {
+ "oAuth": [
+ "write"
+ ]
+ }
+ ],
"requestBody": {
+ "required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
+ "required": [
+ "allowlist"
+ ],
"properties": {
- "mapping": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "customerAddressId": {
- "type": "string",
- "description": "The ID of the customer address"
- },
- "type": {
- "type": "string",
- "description": "The type of the address"
- },
- "deliveryId": {
- "description": "The ID of the delivery (optional)",
- "oneOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ]
+ "allowlist": {
+ "oneOf": [
+ {
+ "type": "object",
+ "description": "Per-type allowlist. Each key is null (unrestricted) or a list of allowed names/URIs.",
+ "properties": {
+ "tools": {
+ "oneOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of allowed tool names. Empty array = no tools allowed."
+ },
+ {
+ "type": "null",
+ "description": "Null = all tools allowed."
+ }
+ ]
+ },
+ "resources": {
+ "oneOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of allowed resource URIs. Empty array = no resources allowed."
+ },
+ {
+ "type": "null",
+ "description": "Null = all resources allowed."
+ }
+ ]
+ },
+ "prompts": {
+ "oneOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of allowed prompt names. Empty array = no prompts allowed."
+ },
+ {
+ "type": "null",
+ "description": "Null = all prompts allowed."
+ }
+ ]
+ }
}
},
- "required": [
- "customerAddressId",
- "type"
- ]
- },
- "description": "The mapping of order addresses"
+ {
+ "type": "null",
+ "description": "Null = all capabilities unrestricted."
+ }
+ ]
}
}
}
}
- },
- "required": true
+ }
},
"responses": {
"204": {
- "description": "Returns a no content response indicating that the update has been made."
+ "description": "Allowlist saved successfully."
+ },
+ "400": {
+ "description": "Bad request — missing or invalid `allowlist` field."
+ },
+ "401": {
+ "description": "Unauthorized — missing or invalid credentials."
+ },
+ "403": {
+ "description": "Forbidden — caller lacks `integration_mcp.editor` privilege."
+ },
+ "404": {
+ "description": "Integration not found."
}
}
}
},
- "/_action/order_transaction_capture_refund/{refundId}": {
+ "/_action/user/{userId}/mcp-allowlist": {
"post": {
"tags": [
- "Order Management"
+ "MCP",
+ "Experimental"
],
- "summary": "Refund an order transaction capture",
- "description": "Refunds an order transaction capture.",
- "operationId": "orderTransactionCaptureRefund",
+ "summary": "Save MCP allowlist for a user",
+ "description": "Saves the per-user MCP allowlist covering tools, resources, and prompts. Pass `null` as the top-level value to allow all capabilities unrestricted. Pass an object with `tools`, `resources`, and `prompts` keys where each key is either `null` (unrestricted for that type) or a list of allowed names/URIs (empty array = deny all of that type). Requires `users_and_permissions.editor` privilege. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "saveMcpAllowlistUser",
"parameters": [
{
- "name": "refundId",
+ "name": "userId",
"in": "path",
- "description": "Identifier of the order transaction capture refund.",
"required": true,
+ "description": "The user UUID.",
"schema": {
"type": "string",
"pattern": "^[0-9a-f]{32}$"
}
}
],
- "responses": {
- "204": {
- "description": "Refund was successful"
- },
- "400": {
- "description": "Something went wrong, while processing the refund"
- },
- "404": {
- "description": "Refund with id not found"
- }
- }
- }
- },
- "/_action/cache_info": {
- "get": {
- "tags": [
- "System Operations"
- ],
- "summary": "Get cache information",
- "description": "Get information about the cache configuration",
- "operationId": "info",
- "responses": {
- "200": {
- "description": "Information about the cache state.",
- "content": {
- "application/json": {
- "schema": {
- "properties": {
- "environment": {
- "description": "The active environment.",
- "type": "string"
- },
- "httpCache": {
- "description": "State of the HTTP cache.",
- "type": "boolean"
- },
- "cacheAdapter": {
- "description": "The active cache adapter.",
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- }
- }
- }
- }
- },
- "/_action/sync": {
- "post": {
- "tags": [
- "Bulk Operations"
- ],
- "summary": "Bulk edit entities",
- "description": "Starts a sync process for the list of provided actions. This can be upserts and deletes on different entities to an asynchronous process in the background. You can control the behaviour with the `indexing-behavior` header.",
- "operationId": "sync",
- "parameters": [
- {
- "name": "fail-on-error",
- "in": "header",
- "description": "To continue upcoming actions on errors, set the `fail-on-error` header to `false`.",
- "schema": {
- "type": "boolean",
- "default": true
- }
- },
- {
- "name": "indexing-behavior",
- "in": "header",
- "description": "Controls the indexing behavior.\n - `disable-indexing`: Data indexing is completely disabled",
- "schema": {
- "type": "string",
- "enum": [
- "use-queue-indexing",
- "disable-indexing"
- ]
- }
+ "security": [
+ {
+ "oAuth": [
+ "write"
+ ]
}
],
"requestBody": {
@@ -80827,419 +80635,680 @@
"content": {
"application/json": {
"schema": {
- "type": "array",
- "items": {
- "required": [
- "action",
- "entity",
- "payload"
- ],
- "properties": {
- "action": {
- "description": "The action indicates what should happen with the provided payload.\n * `upsert`: The Sync API does not differ between create and update operations,\n but always performs an upsert operation. During an upsert, the system checks whether the entity already exists in the\n system and updates it if an identifier has been passed, otherwise a new entity is created with this identifier.\n * `delete`: Deletes entities with the provided identifiers",
- "type": "string",
- "enum": [
- "upsert",
- "delete"
- ]
- },
- "entity": {
- "description": "The entity that should be processed with the payload.",
- "type": "string",
- "example": "product"
- },
- "payload": {
- "description": "Contains a list of changesets for an entity. If the action type is `delete`,\n a list of identifiers can be provided.",
- "type": "array",
- "items": {
- "type": "object"
- }
- },
- "criteria": {
- "description": "Only for delete operations: Instead of providing IDs in the payload, the filter by which should be deleted can be provided directly.",
- "type": "array",
- "items": {
- "anyOf": [
- {
- "$ref": "#/components/schemas/SimpleFilter"
- },
- {
- "$ref": "#/components/schemas/EqualsFilter"
+ "type": "object",
+ "required": [
+ "allowlist"
+ ],
+ "properties": {
+ "allowlist": {
+ "oneOf": [
+ {
+ "type": "object",
+ "description": "Per-type allowlist. Each key is null (unrestricted) or a list of allowed names/URIs.",
+ "properties": {
+ "tools": {
+ "oneOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of allowed tool names. Empty array = no tools allowed."
+ },
+ {
+ "type": "null",
+ "description": "Null = all tools allowed."
+ }
+ ]
},
- {
- "$ref": "#/components/schemas/MultiNotFilter"
+ "resources": {
+ "oneOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of allowed resource URIs. Empty array = no resources allowed."
+ },
+ {
+ "type": "null",
+ "description": "Null = all resources allowed."
+ }
+ ]
},
- {
- "$ref": "#/components/schemas/RangeFilter"
+ "prompts": {
+ "oneOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "List of allowed prompt names. Empty array = no prompts allowed."
+ },
+ {
+ "type": "null",
+ "description": "Null = all prompts allowed."
+ }
+ ]
}
- ]
+ }
+ },
+ {
+ "type": "null",
+ "description": "Null = all capabilities unrestricted."
}
- }
- },
- "type": "object"
+ ]
+ }
}
}
}
}
},
"responses": {
- "200": {
- "description": "Returns a sync result containing information about the updated entities",
- "content": {
- "application/json": {
- "schema": {
- "properties": {
- "data": {
- "description": "Object with information about updated entities",
- "type": "object"
- },
- "notFound": {
- "description": "Object with information about not found entities",
- "type": "object"
- },
- "deleted": {
- "description": "Object with information about deleted entities",
- "type": "object"
- }
- },
- "type": "object"
- }
- }
- }
+ "204": {
+ "description": "Allowlist saved successfully."
+ },
+ "400": {
+ "description": "Bad request — missing or invalid `allowlist` field."
+ },
+ "401": {
+ "description": "Unauthorized — missing or invalid credentials."
+ },
+ "403": {
+ "description": "Forbidden — caller lacks `users_and_permissions.editor` privilege."
+ },
+ "404": {
+ "description": "User not found."
}
}
}
},
- "/_action/sales-channel-file/{fileFamily}/{salesChannelId}": {
+ "/_action/mcp/tools": {
"get": {
"tags": [
- "Sales Channel Files"
+ "MCP",
+ "Experimental"
],
- "summary": "List discovered sales channel files",
- "description": "Lists all discovered public files for a file family and sales channel, including content type and the stored sales-channel configuration when one exists.",
- "operationId": "listSalesChannelFiles",
- "parameters": [
- {
- "name": "fileFamily",
- "in": "path",
- "description": "File family below `Resources/views/files`, for example `agentic`.",
- "required": true,
- "schema": {
- "type": "string",
- "maxLength": 64,
- "pattern": "^[A-Za-z0-9_-]+$"
- }
- },
+ "summary": "List registered MCP tools",
+ "description": "Returns all MCP tools currently registered on this Shopware installation. For all capability types (tools, resources, prompts) use `GET /_action/mcp/capabilities` instead. Requires `integration.editor` privilege. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "mcpToolsList",
+ "security": [
{
- "name": "salesChannelId",
- "in": "path",
- "description": "Identifier of the sales channel for which stored configuration should be loaded.",
- "required": true,
- "schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
+ "oAuth": [
+ "write"
+ ]
}
],
"responses": {
"200": {
- "description": "Discovered sales channel files for the given file family.",
+ "description": "Array of registered MCP tools.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/SalesChannelFileListResponse"
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Unique tool identifier used in `tools/call` requests.",
+ "example": "shopware-entity-search"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Human-readable description of what the tool does.",
+ "example": "Search Shopware entities and return matching records."
+ },
+ "dependencies": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Tool names that are automatically included when this tool is selected."
+ },
+ "requiredPrivileges": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "static": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "entityParam": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "operations": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "description": "ACL privileges required by this tool."
+ }
+ }
+ }
}
}
}
},
- "400": {
- "description": "Invalid file family.",
- "$ref": "#/components/responses/400"
+ "401": {
+ "description": "Unauthorized — missing or invalid credentials."
+ },
+ "403": {
+ "description": "Forbidden — caller lacks `integration.editor` privilege."
}
}
}
},
- "/_action/sales-channel-file/{fileFamily}/{salesChannelId}/detail": {
+ "/_action/mcp/capabilities": {
"get": {
"tags": [
- "Sales Channel Files"
+ "MCP",
+ "Experimental"
],
- "summary": "Load sales channel file detail",
- "description": "Loads detail data for a discovered public file, including contributing Twig templates, their source content, and the stored sales-channel configuration when one exists.",
- "operationId": "getSalesChannelFileDetail",
- "parameters": [
- {
- "name": "fileFamily",
- "in": "path",
- "description": "File family below `Resources/views/files`, for example `agentic`.",
- "required": true,
- "schema": {
- "type": "string",
- "maxLength": 64,
- "pattern": "^[A-Za-z0-9_-]+$"
- }
- },
- {
- "name": "salesChannelId",
- "in": "path",
- "description": "Identifier of the sales channel for which stored configuration should be loaded.",
- "required": true,
- "schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- }
- },
+ "summary": "List all registered MCP capabilities",
+ "description": "Returns all registered MCP tools, resources, and prompts. Used by the Admin UI to populate the per-integration allowlist selector. Requires `integration.editor` privilege. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "mcpCapabilitiesList",
+ "security": [
{
- "name": "fileName",
- "in": "query",
- "description": "Public file path without a leading slash. Subfolders are supported, for example `.well-known/ucp.json`.",
- "required": true,
- "schema": {
- "type": "string",
- "examples": [
- "llms.txt",
- ".well-known/ucp.json"
- ]
- }
+ "oAuth": [
+ "write"
+ ]
}
],
"responses": {
"200": {
- "description": "Detail data for the discovered sales channel file.",
+ "description": "Object containing all registered MCP capabilities.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/SalesChannelFileDetailResponse"
+ "type": "object",
+ "required": [
+ "tools",
+ "resources",
+ "prompts"
+ ],
+ "properties": {
+ "tools": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "example": "shopware-entity-search"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "dependencies": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "requiredPrivileges": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "static": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "entityParam": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "operations": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "resources": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "uri",
+ "name"
+ ],
+ "properties": {
+ "uri": {
+ "type": "string",
+ "example": "shopware://entity-list"
+ },
+ "name": {
+ "type": "string",
+ "example": "shopware-entity-list"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "mimeType": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ }
+ },
+ "prompts": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "example": "shopware-context"
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ }
+ }
+ }
}
}
}
},
- "400": {
- "description": "Invalid file family or file name.",
- "$ref": "#/components/responses/400"
+ "401": {
+ "description": "Unauthorized — missing or invalid credentials."
},
- "404": {
- "description": "The requested sales channel file was not discovered.",
- "$ref": "#/components/responses/404"
+ "403": {
+ "description": "Forbidden — caller lacks `integration.editor` privilege."
}
}
}
},
- "/_action/sales-channel-file/{fileFamily}/{salesChannelId}/preview": {
+ "/_mcp": {
"post": {
"tags": [
- "Sales Channel Files"
+ "MCP",
+ "Experimental"
],
- "summary": "Preview a sales channel file",
- "description": "Renders a discovered public file for a sales channel with the supplied Twig template overrides. This allows Administration previews without persisting the overrides first.",
- "operationId": "previewSalesChannelFile",
+ "summary": "MCP JSON-RPC endpoint",
+ "description": "Handles Model Context Protocol (MCP) requests using the Streamable HTTP transport. Accepts JSON-RPC 2.0 messages for methods such as `initialize`, `tools/list`, `tools/call`, `prompts/list`, `prompts/get`, `resources/list`, and `resources/read`. Requires either an integration access key pair (`sw-access-key` + `sw-secret-access-key` headers) or a standard OAuth2 bearer token. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "mcpPost",
"parameters": [
{
- "name": "fileFamily",
- "in": "path",
- "description": "File family below `Resources/views/files`, for example `agentic`.",
- "required": true,
+ "name": "mcp-session-id",
+ "in": "header",
+ "required": false,
+ "description": "Session ID returned by the server after `initialize`. Required for all requests except `initialize`.",
"schema": {
- "type": "string",
- "maxLength": 64,
- "pattern": "^[A-Za-z0-9_-]+$"
+ "type": "string"
}
},
{
- "name": "salesChannelId",
- "in": "path",
- "description": "Identifier of the sales channel used to build the rendering context.",
- "required": true,
+ "name": "sw-access-key",
+ "in": "header",
+ "required": false,
+ "description": "Integration access key for direct credential authentication (alternative to bearer token).",
"schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
+ "type": "string"
}
- }
- ],
- "requestBody": {
- "description": "Preview input containing the public file name and optional Twig overrides keyed by Twig namespace.",
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/SalesChannelFilePreviewRequest"
+ },
+ {
+ "name": "sw-secret-access-key",
+ "in": "header",
+ "required": false,
+ "description": "Integration secret access key. Required when `sw-access-key` is provided.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "description": "A JSON-RPC 2.0 request or batch.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "jsonrpc",
+ "method"
+ ],
+ "properties": {
+ "jsonrpc": {
+ "type": "string",
+ "enum": [
+ "2.0"
+ ]
+ },
+ "id": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "method": {
+ "type": "string",
+ "example": "tools/call"
+ },
+ "params": {
+ "type": "object",
+ "additionalProperties": true
+ }
+ }
}
}
}
},
"responses": {
"200": {
- "description": "Rendered preview content.",
+ "description": "JSON-RPC response or Server-Sent Events stream for long-running operations.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/SalesChannelFilePreviewResponse"
+ "type": "object",
+ "properties": {
+ "jsonrpc": {
+ "type": "string",
+ "enum": [
+ "2.0"
+ ]
+ },
+ "id": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "result": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "error": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "integer"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "text/event-stream": {
+ "itemSchema": {
+ "type": "object",
+ "description": "Parsed Server-Sent Events message. The `data` field contains a serialized JSON-RPC response object.",
+ "properties": {
+ "event": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "retry": {
+ "type": "integer"
+ },
+ "data": {
+ "type": "string",
+ "contentMediaType": "application/json",
+ "contentSchema": {
+ "type": "object",
+ "properties": {
+ "jsonrpc": {
+ "type": "string",
+ "enum": [
+ "2.0"
+ ]
+ },
+ "id": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "result": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "error": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "integer"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "schema": {
+ "type": "string",
+ "description": "Server-Sent Events stream for streaming responses."
}
}
}
},
- "400": {
- "description": "Invalid request payload, file family, or file name.",
- "$ref": "#/components/responses/400"
+ "401": {
+ "description": "Unauthorized — missing or invalid credentials."
},
- "404": {
- "description": "The requested sales channel file was not discovered.",
- "$ref": "#/components/responses/404"
+ "429": {
+ "description": "Too many requests — rate limit exceeded."
}
}
- }
- },
- "/_info/queue.json": {
+ },
"get": {
"tags": [
- "System Info & Health Check"
+ "MCP",
+ "Experimental"
+ ],
+ "summary": "MCP SSE stream",
+ "description": "Opens a Server-Sent Events stream for receiving server-initiated messages. Used by MCP clients that support the SSE transport variant. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "mcpGet",
+ "parameters": [
+ {
+ "name": "mcp-session-id",
+ "in": "header",
+ "required": false,
+ "schema": {
+ "type": "string"
+ }
+ }
],
- "summary": "Get message queue statistics (deprecated)",
- "description": "Returns increment-based message queue statistics.\n\n**Deprecated:** This endpoint is deprecated and will be removed in v6.8.0. Use `GET /_info/message-stats.json` instead for accurate message processing statistics.",
- "operationId": "queue",
- "deprecated": true,
"responses": {
"200": {
- "description": "Message queue statistics returned.",
+ "description": "Server-Sent Events stream.",
"content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "description": "Fully qualified class name of the message."
- },
- "size": {
- "type": "integer",
- "description": "Number of pending messages of this type."
- }
+ "text/event-stream": {
+ "itemSchema": {
+ "type": "object",
+ "description": "Parsed Server-Sent Events message. The `data` field contains a serialized MCP server message.",
+ "properties": {
+ "event": {
+ "type": "string"
},
- "required": [
- "name",
- "size"
- ]
+ "id": {
+ "type": "string"
+ },
+ "retry": {
+ "type": "integer"
+ },
+ "data": {
+ "type": "string",
+ "contentMediaType": "application/json",
+ "contentSchema": {
+ "type": "object",
+ "additionalProperties": true
+ }
+ }
}
},
- "example": [
- {
- "name": "Shopware\\Core\\Content\\Product\\DataAbstractionLayer\\ProductIndexingMessage",
- "size": 150
- },
- {
- "name": "Shopware\\Core\\Content\\Media\\Message\\GenerateThumbnailsMessage",
- "size": 25
- }
- ]
+ "schema": {
+ "type": "string"
+ }
}
}
+ },
+ "401": {
+ "description": "Unauthorized."
}
}
- }
- },
- "/_info/events.json": {
- "get": {
+ },
+ "delete": {
"tags": [
- "System Info & Health Check"
+ "MCP",
+ "Experimental"
],
- "summary": "Get Business events",
- "description": "Get a list of about the business events.",
- "operationId": "business-events",
- "responses": {
- "200": {
- "description": "Returns a list of about the business events.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/businessEventsResponse"
- }
- }
+ "summary": "Close MCP session",
+ "description": "Terminates an active MCP session identified by the `mcp-session-id` header. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "mcpDelete",
+ "parameters": [
+ {
+ "name": "mcp-session-id",
+ "in": "header",
+ "required": true,
+ "schema": {
+ "type": "string"
}
}
+ ],
+ "responses": {
+ "204": {
+ "description": "Session closed successfully."
+ },
+ "401": {
+ "description": "Unauthorized."
+ }
+ }
+ },
+ "options": {
+ "tags": [
+ "MCP",
+ "Experimental"
+ ],
+ "summary": "MCP CORS preflight",
+ "description": "Handles CORS preflight requests for the MCP endpoint. Experimental API, not part of our backwards compatibility promise, thus this API can introduce breaking changes at any time.",
+ "operationId": "mcpOptions",
+ "responses": {
+ "204": {
+ "description": "CORS preflight accepted."
+ }
}
}
},
- "/_action/validation/email": {
- "post": {
+ "/_action/media/{mediaId}/download": {
+ "get": {
"tags": [
- "Email support validation"
+ "Asset Management"
],
- "summary": "Email support.",
- "description": "Checks a given email string.",
- "operationId": "supportsEmail",
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "required": [
- "email"
- ],
- "properties": {
- "email": {
- "description": "The email to be verified.",
- "type": "string"
- }
- },
- "type": "object"
- }
+ "summary": "Download a media file",
+ "description": "Downloads a media file by its identifier.",
+ "operationId": "downloadMedia",
+ "parameters": [
+ {
+ "name": "mediaId",
+ "in": "path",
+ "description": "Identifier of the media entity.",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/MediaId"
}
}
- },
+ ],
"responses": {
- "204": {
- "description": "Email is supported"
- },
- "400": {
- "description": "Invalid request payload. The argument 'email' may be missing.",
+ "200": {
+ "description": "The media file.",
"content": {
- "application/json": {
+ "application/octet-stream": {
"schema": {
- "properties": {
- "errors": {
- "description": "Contains the error message.",
- "type": "array"
- }
- },
- "type": "object"
- },
- "example": {
- "errors": [
- {
- "code": "0",
- "status": "400",
- "title": "Unprocessable Content",
- "detail": "This value should not be blank."
- }
- ]
+ "type": "string",
+ "format": "binary"
}
}
}
},
- "422": {
- "description": "Email address is not supported.",
- "content": {
- "application/json": {
+ "302": {
+ "description": "Redirects to the resolved media download URL.",
+ "headers": {
+ "Location": {
+ "description": "Contains the resolved media download URL.",
"schema": {
- "properties": {
- "errors": {
- "description": "Contains the validation error.",
- "type": "array"
- }
- },
- "type": "object"
- },
- "example": {
- "errors": [
- {
- "code": "0",
- "status": "422",
- "title": "Unprocessable Content",
- "detail": "This value is not a supported email address."
- }
- ]
+ "type": "string"
}
}
}
@@ -81247,49 +81316,109 @@
}
}
},
- "/_action/indexing": {
- "post": {
+ "/_action/media/{mediaId}/download/prepare": {
+ "get": {
"tags": [
- "System Operations"
+ "Asset Management"
+ ],
+ "summary": "Prepare a media download",
+ "description": "Resolves the browser download URL for a media file by its identifier.",
+ "operationId": "prepareMediaDownload",
+ "parameters": [
+ {
+ "name": "mediaId",
+ "in": "path",
+ "description": "Identifier of the media entity.",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/MediaId"
+ }
+ }
],
- "summary": "Run indexer",
- "description": "Runs all registered indexer in the shop asynchronously.",
- "operationId": "indexing",
"responses": {
"200": {
- "description": "Returns an empty response indicating that the indexing process started."
+ "description": "The resolved browser download strategy.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "external",
+ "blob"
+ ],
+ "description": "Whether the frontend should trigger an external URL directly or fall back to an authenticated blob download."
+ },
+ "url": {
+ "type": "string",
+ "description": "External URL that should be used by the browser to start the download."
+ }
+ }
+ }
+ }
+ }
}
}
}
},
- "/_action/indexing/{indexer}": {
+ "/_action/media/{mediaId}/upload": {
"post": {
"tags": [
- "System Operations"
+ "Asset Management"
],
- "summary": "Iterate an indexer",
- "description": "Starts a defined indexer with an offset.\n\nfor the next request. `finish: true` in the response indicates that the indexer is finished",
- "operationId": "iterate",
+ "summary": "Upload a file to a media entity",
+ "description": "Adds a new file to a media entity. If the entity has an existing file, it will be replaced.\n\nThe are two methods of providing a file to this route:\n * Use a typical file upload and provide the file in the request\n * Fetch the file from an url. This only works if the `shopware.media.enable_url_upload_feature` variable is set to true in the shop environment.\nTo use file upload via url, the content type has to be `application/json` and the parameter `url` has to be provided.",
+ "operationId": "upload",
"parameters": [
{
- "name": "indexer",
+ "name": "mediaId",
"in": "path",
- "description": "Name of the indexer to iterate.",
+ "description": "Identifier of the media entity.",
"required": true,
"schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
+ "$ref": "#/components/schemas/MediaId"
+ }
+ },
+ {
+ "name": "fileName",
+ "in": "query",
+ "description": "Name of the uploaded file. If not provided the media identifier will be used as name",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "extension",
+ "in": "query",
+ "description": "Extension of the uploaded file. For example `png`",
+ "required": true,
+ "schema": {
+ "type": "string"
}
}
],
"requestBody": {
"content": {
+ "application/octet-stream": {
+ "schema": {
+ "type": "string",
+ "format": "binary"
+ }
+ },
"application/json": {
"schema": {
+ "required": [
+ "url"
+ ],
"properties": {
- "offset": {
- "description": "The offset for the iteration.",
- "type": "integer"
+ "url": {
+ "description": "The url of the media file that will be downloaded.",
+ "type": "string"
}
},
"type": "object"
@@ -81298,22 +81427,13 @@
}
},
"responses": {
- "200": {
- "description": "Returns information about the iteration.",
- "content": {
- "application/json": {
+ "204": {
+ "description": "Media file uploaded successful",
+ "headers": {
+ "Location": {
+ "description": "Contains the url to the uploaded media for a redirect.",
"schema": {
- "properties": {
- "finish": {
- "description": "Indicates if the indexing process finished.",
- "type": "boolean"
- },
- "offset": {
- "description": "Offset to be used for the next iteration.",
- "type": "integer"
- }
- },
- "type": "object"
+ "type": "string"
}
}
}
@@ -81321,46 +81441,73 @@
}
}
},
- "/_action/message-queue/consume": {
+ "/_action/media/upload": {
"post": {
"tags": [
- "System Operations"
+ "Asset Management"
],
- "summary": "Consume messages from the message queue.",
- "description": "This route can be used to consume messages from the message queue. It is intended to be used if\nno cronjob is configured to consume messages regularly.",
- "operationId": "consumeMessages",
+ "summary": "Upload a new media file",
+ "description": "Creates a new media entity and uploads a file to it using form-data file upload.",
+ "operationId": "uploadV2",
"requestBody": {
- "required": true,
"content": {
- "application/json": {
+ "multipart/form-data": {
"schema": {
- "required": [
- "receiver"
- ],
+ "type": "object",
"properties": {
- "receiver": {
- "description": "The name of the transport in the messenger that should be processed.\nSee the [Symfony Messenger documentation](https://symfony.com/doc/current/messenger.html) for more information",
- "type": "string"
+ "file": {
+ "type": "string",
+ "format": "binary",
+ "description": "The file to upload"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "Custom ID for the media entity"
+ },
+ "fileName": {
+ "type": "string",
+ "description": "Name of the uploaded file"
+ },
+ "private": {
+ "type": "boolean",
+ "description": "Whether the media should be private"
+ },
+ "mediaFolderId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the media folder"
+ },
+ "mimeType": {
+ "type": "string",
+ "description": "MIME type of the file"
+ },
+ "deduplicate": {
+ "type": "boolean",
+ "description": "Whether to deduplicate based on file hash"
}
},
- "type": "object"
+ "required": [
+ "file"
+ ]
}
}
}
},
"responses": {
"200": {
- "description": "Returns information about handled messages",
+ "description": "Media file uploaded successfully",
"content": {
- "application/json": {
+ "application\\/json": {
"schema": {
+ "type": "object",
"properties": {
- "handledMessages": {
- "description": "The number of messages processed.",
- "type": "integer"
+ "id": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the created media entity"
}
- },
- "type": "object"
+ }
}
}
}
@@ -81368,161 +81515,394 @@
}
}
},
- "/_action/container_cache": {
- "delete": {
+ "/_action/media/upload_by_url": {
+ "post": {
"tags": [
- "System Operations"
+ "Asset Management"
],
- "summary": "Clear container caches",
- "description": "The container cache is immediately cleared synchronously.",
- "operationId": "clearContainerCache",
+ "summary": "Upload a media file from URL",
+ "description": "Creates a new media entity by downloading and uploading a file from the provided URL. This only works if the `shopware.media.enable_url_upload_feature` variable is set to true in the shop environment.",
+ "operationId": "uploadByUrl",
+ "requestBody": {
+ "content": {
+ "application\\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "URL of the file to download and upload"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "Custom ID for the media entity"
+ },
+ "fileName": {
+ "type": "string",
+ "description": "Name of the uploaded file"
+ },
+ "private": {
+ "type": "boolean",
+ "description": "Whether the media should be private"
+ },
+ "mediaFolderId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the media folder"
+ },
+ "mimeType": {
+ "type": "string",
+ "description": "MIME type of the file"
+ },
+ "deduplicate": {
+ "type": "boolean",
+ "description": "Whether to deduplicate based on file hash"
+ }
+ },
+ "required": [
+ "url"
+ ]
+ }
+ }
+ }
+ },
"responses": {
- "204": {
- "description": "Returns a no content response indicating that the container cache is cleared."
+ "200": {
+ "description": "Media file uploaded successfully",
+ "content": {
+ "application\\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the created media entity"
+ }
+ }
+ }
+ }
+ }
}
}
}
},
- "/app-system/privileges/requested": {
- "get": {
+ "/_action/media/external-link": {
+ "post": {
"tags": [
- "App System"
+ "Asset Management"
],
- "summary": "Get requested privileges for all apps",
- "description": "Returns the list of requested privileges for all apps. Requires admin scope and `acl_role:read` permission to read.",
- "operationId": "getRequestedPrivileges",
- "security": [
- {
- "oAuth": [
- "admin"
- ]
+ "summary": "Create external media link",
+ "description": "Creates a new media entity that links to an external URL without downloading the file.",
+ "operationId": "externalLink",
+ "requestBody": {
+ "content": {
+ "application\\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "URL of the external media file"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "Custom ID for the media entity"
+ },
+ "fileName": {
+ "type": "string",
+ "description": "Name of the file"
+ },
+ "private": {
+ "type": "boolean",
+ "description": "Whether the media should be private"
+ },
+ "mediaFolderId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the media folder"
+ },
+ "mimeType": {
+ "type": "string",
+ "description": "MIME type of the file"
+ },
+ "deduplicate": {
+ "type": "boolean",
+ "description": "Whether to deduplicate based on path"
+ },
+ "thumbnails": {
+ "type": "array",
+ "description": "Optional list of external thumbnail URLs for the media entity. Used for CDNs that pre-generated thumbnails alongside the main media file.\nNot to be confused with [remote thumbnails](https://developer.shopware.com/docs/guides/plugins/plugins/content/media/remote-thumbnail-generation.html#remote-thumbnail-generation), which are generated based on a pattern.",
+ "items": {
+ "$ref": "#/components/schemas/ExternalThumbnail"
+ }
+ }
+ },
+ "required": [
+ "url",
+ "mimeType"
+ ]
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "External media link created successfully",
+ "content": {
+ "application\\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the created media entity"
+ }
+ }
+ }
+ }
+ }
}
+ }
+ }
+ },
+ "/_action/media/presign-upload": {
+ "post": {
+ "tags": [
+ "Asset Management"
],
+ "summary": "Prepare a presigned upload",
+ "description": "Creates or reuses a media entity and returns a presigned S3 URL for direct browser-to-storage upload. The client uploads the file directly to the returned URL, then calls the finalize endpoint.",
+ "operationId": "presignUpload",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "fileName",
+ "extension",
+ "mimeType"
+ ],
+ "properties": {
+ "fileName": {
+ "type": "string",
+ "description": "Name of the file without extension"
+ },
+ "extension": {
+ "type": "string",
+ "description": "File extension, e.g. `jpg`, `png`, `pdf`"
+ },
+ "mimeType": {
+ "type": "string",
+ "description": "MIME type of the file, e.g. `image/jpeg`"
+ },
+ "mediaFolderId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the media folder to place the new media in"
+ },
+ "private": {
+ "type": "boolean",
+ "default": false,
+ "description": "Whether the media should be private"
+ },
+ "mediaId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of an existing media entity to replace. If omitted, a new entity is created."
+ }
+ }
+ }
+ }
+ }
+ },
"responses": {
"200": {
- "description": "A JSON object containing requested privileges.",
+ "description": "Presigned upload prepared successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
+ "required": [
+ "mediaId",
+ "url",
+ "path",
+ "expiresAt",
+ "isDuplicate"
+ ],
"properties": {
- "privileges": {
- "type": "object",
- "additionalProperties": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
+ "mediaId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the media entity"
+ },
+ "url": {
+ "type": "string",
+ "description": "Presigned URL to upload the file to via HTTP PUT"
+ },
+ "path": {
+ "type": "string",
+ "description": "Storage path of the media file, required for the finalize call"
+ },
+ "expiresAt": {
+ "type": "string",
+ "format": "date-time",
+ "description": "Expiration time of the presigned URL"
+ },
+ "isDuplicate": {
+ "type": "boolean",
+ "description": "Whether a file with the same name already exists"
}
}
- },
- "example": {
- "privileges": {
- "SwagAnalytics": [
- "customer:read",
- "order:read"
- ],
- "SwagExample": [
- "product:write"
- ]
- }
}
}
}
},
"400": {
- "description": "Malformed request."
+ "description": "Bad request. The file extension is not supported or the file name is invalid.",
+ "$ref": "#/components/responses/400"
},
- "401": {
- "description": "Unauthorized Access."
+ "404": {
+ "description": "The media entity with the given `mediaId` was not found.",
+ "$ref": "#/components/responses/404"
},
- "403": {
- "description": "Forbidden. Not a valid integration source."
+ "422": {
+ "description": "Validation error. Required fields (`fileName`, `extension`, `mimeType`) must not be blank.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/failure"
+ }
+ }
+ }
}
}
}
},
- "/app-system/{appName}/privileges/accepted": {
- "get": {
+ "/_action/media/{mediaId}/finalize-upload": {
+ "post": {
"tags": [
- "App System"
+ "Asset Management"
],
- "summary": "Get accepted privileges for an app",
- "description": "Returns the list of accepted privileges for the current integration. Requires admin scope with an integration.",
- "operationId": "getAcceptedPrivileges",
+ "summary": "Finalize a presigned upload",
+ "description": "Confirms that the file has been uploaded to storage via the presigned URL and updates the media entity with file metadata.",
+ "operationId": "finalizeUpload",
"parameters": [
{
- "name": "appName",
+ "name": "mediaId",
"in": "path",
"required": true,
+ "description": "ID of the media entity to finalize",
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/MediaId"
}
}
],
- "security": [
- {
- "oAuth": [
- "admin"
- ]
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "fileName",
+ "extension",
+ "mimeType",
+ "path"
+ ],
+ "properties": {
+ "fileName": {
+ "type": "string",
+ "description": "Name of the file without extension"
+ },
+ "extension": {
+ "type": "string",
+ "description": "File extension, e.g. `jpg`, `png`, `pdf`"
+ },
+ "mimeType": {
+ "type": "string",
+ "description": "MIME type of the file"
+ },
+ "path": {
+ "type": "string",
+ "description": "Storage path returned by the presign-upload endpoint"
+ },
+ "width": {
+ "type": "integer",
+ "description": "Image width in pixels (optional, for images only)"
+ },
+ "height": {
+ "type": "integer",
+ "description": "Image height in pixels (optional, for images only)"
+ }
+ }
+ }
+ }
}
- ],
+ },
"responses": {
"200": {
- "description": "A JSON object containing accepted privileges.",
+ "description": "Upload finalized successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
+ "required": [
+ "mediaId"
+ ],
"properties": {
- "privileges": {
- "type": "object",
- "additionalProperties": {
- "type": "boolean"
- }
+ "mediaId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the finalized media entity"
}
}
- },
- "example": {
- "privileges": {
- "customer:read": true,
- "order:read": true
- }
}
}
}
},
"400": {
- "description": "Malformed request."
- },
- "401": {
- "description": "Unauthorized Access."
- },
- "403": {
- "description": "Forbidden. Not a valid integration source."
+ "description": "Bad request. The file extension is not supported, the storage path does not match, the file name is already taken, or the file could not be found on the remote storage.",
+ "$ref": "#/components/responses/400"
},
"404": {
- "description": "App not found."
+ "description": "The media entity with the given `mediaId` was not found.",
+ "$ref": "#/components/responses/404"
+ },
+ "422": {
+ "description": "Validation error. Required fields (`fileName`, `extension`, `mimeType`, `path`) must not be blank.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/failure"
+ }
+ }
+ }
}
}
}
},
- "/app-system/{appName}/privileges": {
- "patch": {
+ "/_action/media/{mediaId}/external-thumbnails": {
+ "post": {
"tags": [
- "App System"
+ "Asset Management"
],
- "summary": "Accept or revoke privileges for an app",
- "description": "Accepts or revokes specified privileges for the given app.",
- "operationId": "managePrivileges",
+ "summary": "Add external thumbnails to media",
+ "description": "Attaches external thumbnail URLs to an existing external media entity. The media must have an HTTP/HTTPS path (i.e. be an external media link).\n\nUsed for CDNs that pre-generated thumbnails alongside the main media file.\nNot to be confused with [remote thumbnails](https://developer.shopware.com/docs/guides/plugins/plugins/content/media/remote-thumbnail-generation.html#remote-thumbnail-generation), which are generated based on a pattern.\n\nThe thumbnail sized are matched against existing thumbnails sizes and a matching size will automatically be assigned. If there's not existing size, a **new thumbnail size will automatically be created** for each missing size.",
+ "operationId": "addExternalThumbnails",
"parameters": [
{
- "name": "appName",
+ "name": "mediaId",
"in": "path",
+ "description": "ID of the external media entity the thumbnails will be attached to.",
"required": true,
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/MediaId"
}
}
],
@@ -81533,197 +81913,322 @@
"schema": {
"type": "object",
"properties": {
- "accept": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "revoke": {
+ "thumbnails": {
"type": "array",
+ "description": "List of external thumbnails to attach",
"items": {
- "type": "string"
+ "$ref": "#/components/schemas/ExternalThumbnail"
}
}
}
- },
- "example": {
- "accept": [
- "customer:read",
- "order:read"
- ],
- "revoke": [
- "product:write"
- ]
}
}
}
},
"responses": {
- "204": {
- "description": "Returns no content if privileges were managed successfully."
- },
- "400": {
- "description": "Malformed request."
- },
- "401": {
- "description": "Unauthorized Access."
- },
- "403": {
- "description": "Forbidden. Not a valid integration source."
- },
- "404": {
- "description": "App not found."
- }
- },
- "security": [
- {
- "oAuth": [
- "admin"
- ]
+ "201": {
+ "description": "Thumbnails attached successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "mediaId": {
+ "description": "ID of the media entity the thumbnails were attached to.",
+ "$ref": "#/components/schemas/MediaId"
+ },
+ "thumbnailsCreated": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Media is not an external media entity or path is missing"
+ },
+ "404": {
+ "description": "Media entity not found"
}
- ]
- }
- },
- "/_action/app-system/secret/rotate": {
- "post": {
+ }
+ },
+ "delete": {
"tags": [
- "App System"
+ "Asset Management"
+ ],
+ "summary": "Delete all external thumbnails from media",
+ "description": "Removes all externally stored thumbnail entries from the given media entity. Only works on external media (media with an HTTP/HTTPS path). Used to replace outdated thumbnails with new ones.",
+ "operationId": "deleteExternalThumbnails",
+ "parameters": [
+ {
+ "name": "mediaId",
+ "in": "path",
+ "description": "ID of the external media entity the thumbnails will be deleted from..",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/MediaId"
+ }
+ }
],
- "summary": "Initiate secret rotation for the calling app",
- "description": "Initiates an app secret rotation for the calling app. Needs to be called with an integration token belonging to an app. Note that the secret rotation will only be scheduled and then handled asynchronously.",
- "operationId": "appSecretRotation",
"responses": {
- "202": {
- "description": "Returns \"Accepted\" when secret rotation was scheduled."
+ "200": {
+ "description": "Thumbnails deleted successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "mediaId": {
+ "description": "ID of the media entity the thumbnails were deleted from.",
+ "$ref": "#/components/schemas/MediaId"
+ }
+ }
+ }
+ }
+ }
},
"400": {
- "description": "Malformed request, e.g. when requested with non app integration source."
- },
- "401": {
- "description": "Unauthorized Access."
- },
- "403": {
- "description": "Forbidden. Not a valid integration source."
+ "description": "Media is not an external media entity or path is missing"
},
"404": {
- "description": "App not found."
- }
- },
- "security": [
- {
- "oAuth": [
- "admin"
- ]
+ "description": "Media entity not found"
}
- ]
+ }
}
},
- "/app-system/shop/verify": {
- "get": {
+ "/_action/media/{mediaId}/video-cover": {
+ "post": {
"tags": [
- "App System",
- "Public"
+ "Asset Management"
],
- "summary": "Verify a shop's APP_URL",
- "description": "Used to verify that a shop's APP_URL points to its self. The passed run ID and token are used to query the cache. It returns 204 no content if the given token can be verified using the run id.",
- "operationId": "verifyAppUrl",
+ "summary": "Assign or remove a video cover image",
+ "description": "Assigns an image as a cover for a video media entity, or removes the cover if `coverMediaId` is null.",
+ "operationId": "assignVideoCover",
"parameters": [
{
- "name": "runId",
- "in": "query",
- "description": "A unique identifier used to look up the token",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "token",
- "in": "query",
- "description": "A unique identifier",
+ "name": "mediaId",
+ "in": "path",
"required": true,
+ "description": "ID of the video media entity",
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/MediaId"
}
}
],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "coverMediaId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "ID of the image media entity to use as cover. Set to null to remove the cover."
+ }
+ }
+ }
+ }
+ }
+ },
"responses": {
"204": {
- "description": "An empty response signalling successful verification."
+ "description": "Video cover assigned or removed successfully"
},
"400": {
- "description": "Malformed request or unsuccessful verification."
+ "description": "Invalid request"
}
}
}
},
- "/_action/document/{documentId}/{deepLinkCode}": {
+ "/_action/message-queue/consume": {
+ "post": {
+ "tags": [
+ "System Operations"
+ ],
+ "summary": "Consume messages from the message queue.",
+ "description": "This route can be used to consume messages from the message queue. It is intended to be used if\nno cronjob is configured to consume messages regularly.",
+ "operationId": "consumeMessages",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "required": [
+ "receiver"
+ ],
+ "properties": {
+ "receiver": {
+ "description": "The name of the transport in the messenger that should be processed.\nSee the [Symfony Messenger documentation](https://symfony.com/doc/current/messenger.html) for more information",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Returns information about handled messages",
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "handledMessages": {
+ "description": "The number of messages processed.",
+ "type": "integer"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/_info/message-stats.json": {
"get": {
+ "summary": "Get statistics message queue",
+ "description": "Get statistics for recently processed messages in the message queue",
+ "operationId": "getMessageStats",
"tags": [
- "Document Management"
+ "System Info & Health Check"
],
- "summary": "Download a document",
- "description": "Download a document by its identifier and deep link code.",
- "operationId": "downloadDocument",
+ "responses": {
+ "200": {
+ "description": "Statistics received",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "enabled"
+ ],
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "description": "Whether message queue statistics are enabled in configuration"
+ },
+ "stats": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "properties": {
+ "totalMessagesProcessed": {
+ "type": "integer"
+ },
+ "processedSince": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "averageTimeInQueue": {
+ "type": "number",
+ "format": "float"
+ },
+ "messageTypeStats": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "count": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/_action/number-range/reserve/{type}/{saleschannel}": {
+ "get": {
+ "tags": [
+ "Number Range Management"
+ ],
+ "summary": "Reserve or preview a number-range / document number.",
+ "description": "Reserves or previews the next value for a number range type, for example `order`, `customer`, `product`, or `document_invoice`. This route resolves the applicable number range by type and sales channel.\n\nThe generated number will be reserved and the number pointer will be incremented with every call. For preview purposes, add the `?preview=1` parameter to the request. In that case, the number will not be incremented.\n\nWhen editing an existing persisted number range and previewing its concrete state or unsaved pattern/start changes, use `/_action/number-range/{numberRangeId}/preview-pattern` instead.",
+ "operationId": "numberRangeReserve",
"parameters": [
{
- "name": "documentId",
+ "name": "type",
"in": "path",
- "description": "Identifier of the document to be downloaded.",
+ "description": "Technical name of the number range type, for example `order`, `customer`, `product`, or `document_invoice`.",
"required": true,
"schema": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
+ "type": "string"
}
},
{
- "name": "deepLinkCode",
+ "name": "saleschannel",
"in": "path",
- "description": "A unique hash code which was generated when the document was created.",
+ "description": "Sales channel for the number range. Number ranges can be defined per sales channel, so you can pass a sales channel ID here.",
"required": true,
"schema": {
"type": "string"
}
},
{
- "name": "download",
+ "name": "preview",
"in": "query",
- "description": "This parameter controls the `Content-Disposition` header. If set to `true` the header will be set to `attachment` else `inline`.",
+ "description": "If this parameter has a true value, the number will not actually be incremented, but only previewed.",
+ "required": false,
"schema": {
- "type": "boolean",
- "default": false
+ "type": "boolean"
}
}
],
"responses": {
"200": {
- "description": "The document.",
+ "description": "The generated number",
"content": {
- "application/octet-stream": {
+ "application/json": {
"schema": {
- "type": "string",
- "format": "binary"
+ "properties": {
+ "number": {
+ "description": "The generated or previewed number range value.",
+ "type": "string"
+ }
+ },
+ "type": "object"
}
}
}
+ },
+ "400": {
+ "description": "Number range not found"
}
}
}
},
- "/_action/document/{documentId}/upload": {
- "post": {
+ "/_action/number-range/{numberRangeId}/preview-pattern": {
+ "get": {
"tags": [
- "Document Management"
+ "Number Range Management"
],
- "summary": "Upload a file for a document",
- "description": "Uploads a file for a document. This prevents the document from being dynamically generated and delivers the uploaded file instead, when the document is downloaded.\n\nNote:\n* The document is required to be `static`\n* A document can only have one media file\n\nThe are two methods of providing a file to this route:\n * Use a typical file upload and provide the file in the request\n * Fetch the file from an url. This only works if the `shopware.media.enable_url_upload_feature` variable is set to true in the shop environment.\nTo use file upload via url, the content type has to be `application/json` and the parameter `url` has to be provided.",
- "operationId": "uploadToDocument",
+ "summary": "Preview a persisted number range",
+ "description": "Previews the next value for a concrete persisted number range without incrementing its state. Optional `pattern` and `start` query parameters can be used to preview unsaved changes while editing the number range. Use `/_action/number-range/reserve/{type}` for actual allocation by business type and sales channel.",
+ "operationId": "numberRangePreviewPatternById",
"parameters": [
{
- "name": "documentId",
+ "name": "numberRangeId",
"in": "path",
- "description": "Identifier of the document the new file should be added to.",
+ "description": "Identifier of the number range to preview.",
"required": true,
"schema": {
"type": "string",
@@ -81731,62 +82236,33 @@
}
},
{
- "name": "fileName",
+ "name": "pattern",
"in": "query",
- "description": "Name of the uploaded file.",
- "required": true,
+ "description": "Optional pattern override for the preview.",
+ "required": false,
"schema": {
"type": "string"
}
},
{
- "name": "extension",
+ "name": "start",
"in": "query",
- "description": "Extension of the uploaded file. For example `pdf`",
- "required": true,
+ "description": "Optional start value override for the preview.",
+ "required": false,
"schema": {
- "type": "string"
+ "type": "integer"
}
}
],
- "requestBody": {
- "content": {
- "application/octet-stream": {
- "schema": {
- "type": "string",
- "format": "binary"
- }
- },
- "application/json": {
- "schema": {
- "required": [
- "url"
- ],
- "properties": {
- "url": {
- "description": "The url of the document that will be downloaded.",
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- }
- },
"responses": {
"200": {
- "description": "Document uploaded successful",
+ "description": "The previewed number",
"content": {
"application/json": {
"schema": {
"properties": {
- "documentId": {
- "description": "Identifier of the document.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "documentDeepLink": {
- "description": "A unique hash code which is required to open the document.",
+ "number": {
+ "description": "The previewed number.",
"type": "string"
}
},
@@ -81794,6 +82270,38 @@
}
}
}
+ },
+ "404": {
+ "description": "Number range not found"
+ }
+ }
+ }
+ },
+ "/_info/openapi3.json": {
+ "get": {
+ "tags": [
+ "System Info & Health Check"
+ ],
+ "summary": "Get OpenAPI Specification",
+ "description": "Get information about the admin API in OpenAPI format.",
+ "operationId": "api-info",
+ "parameters": [
+ {
+ "name": "type",
+ "in": "query",
+ "description": "Type of the api",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "jsonapi",
+ "json"
+ ]
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/components/responses/OpenApi3"
}
}
}
@@ -82644,483 +83152,73 @@
}
}
},
- "/oauth/sso/auth": {
- "get": {
- "tags": [
- "Experimental",
- "SSO Login forward"
- ],
- "summary": "Experimental: Redirect to SSO login",
- "description": "Experimental: Creates a redirection to the SSO login page",
- "operationId": "ssoAuth",
- "responses": {
- "200": {
- "description": "Starts the SSO login flow."
- },
- "302": {
- "description": "Experimental: Forwards to SSO login Page"
- }
- }
- }
- },
- "/_info/is-sso": {
- "get": {
- "tags": [
- "Experimental",
- "Is SSO environment"
- ],
- "summary": "Experimental: Is SSO environment",
- "description": "Experimental: Returns a boolean which indicates the it is a SSO environment or not",
- "operationId": "isSso",
- "responses": {
- "200": {
- "description": "Experimental: Returns if it is a SSO environment or not"
- }
- }
- }
- },
- "/_action/sso/invite-user": {
- "post": {
- "tags": [
- "Experimental",
- "Invite a new SSO user"
- ],
- "summary": "Experimental: Invite a new SSO user",
- "description": "Experimental: Invite a new SSO user and sends a e-mail with the invite",
- "operationId": "inviteUser",
- "responses": {
- "200": {
- "description": "Experimental: Invite a new SSO user and sends a e-mail with the invite"
- }
- }
- }
- },
- "/_info/message-stats.json": {
- "get": {
- "summary": "Get statistics message queue",
- "description": "Get statistics for recently processed messages in the message queue",
- "operationId": "getMessageStats",
- "tags": [
- "System Info & Health Check"
- ],
- "responses": {
- "200": {
- "description": "Statistics received",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "required": [
- "enabled"
- ],
- "properties": {
- "enabled": {
- "type": "boolean",
- "description": "Whether message queue statistics are enabled in configuration"
- },
- "stats": {
- "type": [
- "object",
- "null"
- ],
- "properties": {
- "totalMessagesProcessed": {
- "type": "integer"
- },
- "processedSince": {
- "type": "string",
- "format": "date-time"
- },
- "averageTimeInQueue": {
- "type": "number",
- "format": "float"
- },
- "messageTypeStats": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "type": {
- "type": "string"
- },
- "count": {
- "type": "integer"
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- },
- "/_proxy/generate-imitate-customer-token": {
+ "/_action/order/{orderId}/order-address": {
"post": {
"tags": [
- "Customer impersonation"
- ],
- "summary": "Generate a customer impersonation token",
- "description": "Generates a customer impersonation token for the given customer and sales channel.\n\nThe token can be used to authenticate as the customer in the sales channel.",
- "operationId": "generateImitateCustomerToken",
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "required": [
- "customerId",
- "salesChannelId"
- ],
- "properties": {
- "customerId": {
- "description": "ID of the customer",
- "type": "string"
- },
- "salesChannelId": {
- "description": "ID of the sales channel",
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- }
- },
- "responses": {
- "200": {
- "description": "The generated customer impersonation token.",
- "content": {
- "application/json": {
- "schema": {
- "properties": {
- "token": {
- "description": "The generated customer impersonation token",
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- }
- }
- }
- }
- },
- "/_info/config": {
- "get": {
- "tags": [
- "System Info & Health Check"
- ],
- "summary": "Get public runtime config & feature metadata",
- "description": "Returns non-sensitive system/runtime metadata used by the administration UI for initialization, feature toggling, and diagnostics. Typical fields include platform/API version, active feature flags, environment mode, available capabilities (e.g. workers, queue, cache), limits, and other public configuration hints. Use this at admin startup to decide which features to enable and to display environment information.",
- "operationId": "config",
- "responses": {
- "200": {
- "description": "Public runtime configuration & feature metadata returned.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/infoConfigResponse"
- },
- "example": {
- "version": "6.7.2.0",
- "shopId": "NoiU8PfJtu7NBY8M",
- "versionRevision": "98fcdbeab238fbef3b47bc258340124a1dba4852",
- "adminWorker": {
- "enableAdminWorker": true,
- "enableNotificationWorker": true,
- "transports": [
- "webhook",
- "async",
- "low_priority"
- ]
- },
- "bundles": {
- "Administration": {
- "css": [
- "http://localhost:8000/bundles/administration/administration/assets/administration-DX5ywH2m.css"
- ],
- "js": [
- "http://localhost:8000/bundles/administration/administration/assets/administration-DPiBX_LO.js"
- ],
- "baseUrl": null,
- "type": "plugin"
- },
- "Storefront": {
- "css": [
- "http://localhost:8000/bundles/storefront/administration/assets/storefront-LFaCMnyI.css"
- ],
- "js": [
- "http://localhost:8000/bundles/storefront/administration/assets/storefront-C-M6U7ZM.js"
- ],
- "baseUrl": null,
- "type": "plugin"
- }
- },
- "settings": {
- "enableUrlFeature": true,
- "appUrlReachable": true,
- "appsRequireAppUrl": false,
- "firstMigrationDate": "2025-01-01T12:00:00.000Z",
- "private_allowed_extensions": [
- "jpg",
- "jpeg",
- "png",
- "webp",
- "avif",
- "gif",
- "svg",
- "bmp",
- "tiff",
- "tif",
- "eps",
- "webm",
- "mkv",
- "flv",
- "ogv",
- "ogg",
- "mov",
- "mp4",
- "avi",
- "wmv",
- "pdf",
- "aac",
- "mp3",
- "wav",
- "flac",
- "oga",
- "wma",
- "txt",
- "doc",
- "docx",
- "ico",
- "glb",
- "zip",
- "rar",
- "csv",
- "xls",
- "xlsx",
- "html",
- "xml",
- "epub"
- ],
- "private_allowed_mime_types_by_extension": {
- "pdf": [
- "application/pdf"
- ],
- "epub": [
- "application/epub+zip"
- ]
- },
- "enableHtmlSanitizer": true,
- "enableStagingMode": false,
- "disableExtensionManagement": false
- },
- "inAppPurchases": []
- }
- }
- }
- }
- }
- }
- },
- "/_action/translation/list": {
- "get": {
- "tags": [
- "Translation Management"
+ "Order address"
],
- "summary": "List configured translation locales",
- "description": "Lists every locale configured for translation download together with its locally installed metadata.",
- "operationId": "translationList",
- "responses": {
- "200": {
- "description": "The configured locales and their installed metadata.",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "total": {
- "description": "Number of configured locales.",
- "type": "integer"
- },
- "items": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "locale": {
- "description": "The locale code, for example `de-DE`.",
- "type": "string"
- },
- "name": {
- "description": "The configured language name.",
- "type": "string"
- },
- "lastUpdate": {
- "description": "ISO-8601 timestamp of the last installation, or null if not installed.",
- "type": "string",
- "format": "date-time"
- },
- "progress": {
- "description": "Translation completeness in percent, or null if not installed.",
- "type": "integer"
- }
- }
- }
- }
- }
- }
- }
+ "summary": "Update order addresses",
+ "description": "Endpoint which takes a list of mapping objects as payload and updates the order addresses accordingly",
+ "operationId": "updateOrderAddresses",
+ "parameters": [
+ {
+ "name": "orderId",
+ "in": "path",
+ "description": "Identifier of the order.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
}
}
- }
- }
- },
- "/_action/translation/install": {
- "post": {
- "tags": [
- "Translation Management"
],
- "summary": "Install translations for locales",
- "description": "Downloads and installs translations for the given locales, or for all configured locales when `all` is set. Created languages are activated unless `activate` is set to `false`.",
- "operationId": "translationInstall",
"requestBody": {
- "required": false,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
- "locales": {
- "description": "Locale codes to install, for example `[\"de-DE\", \"fr-FR\"]`. Required unless `all` is true.",
+ "mapping": {
"type": "array",
"items": {
- "type": "string"
- }
- },
- "all": {
- "description": "Install all configured locales instead of the `locales` list.",
- "type": "boolean"
- },
- "activate": {
- "description": "Whether created languages are activated. Defaults to true.",
- "type": "boolean"
- }
- }
- }
- }
- }
- },
- "responses": {
- "200": {
- "description": "The locales that were updated and the ones skipped as already up to date.",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "updated": {
- "description": "Locale codes that were downloaded and installed.",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "skipped": {
- "description": "Locale codes that were already up to date.",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "unavailable": {
- "description": "Requested locale codes that have no translation available and were not installed.",
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- }
- }
- }
- },
- "/_action/translation/update": {
- "post": {
- "tags": [
- "Translation Management"
- ],
- "summary": "Update all installed translations",
- "description": "Updates all installed translations.",
- "operationId": "translationUpdate",
- "responses": {
- "200": {
- "description": "The locales that were updated and the ones skipped as already up to date.",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "updated": {
- "description": "Locale codes that were downloaded and installed.",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "skipped": {
- "description": "Locale codes that were already up to date.",
- "type": "array",
- "items": {
- "type": "string"
- }
+ "type": "object",
+ "properties": {
+ "customerAddressId": {
+ "type": "string",
+ "description": "The ID of the customer address"
+ },
+ "type": {
+ "type": "string",
+ "description": "The type of the address"
+ },
+ "deliveryId": {
+ "description": "The ID of the delivery (optional)",
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "customerAddressId",
+ "type"
+ ]
},
- "unavailable": {
- "description": "Requested locale codes that have no translation available and were not installed.",
- "type": "array",
- "items": {
- "type": "string"
- }
- }
+ "description": "The mapping of order addresses"
}
}
}
}
- }
- }
- }
- },
- "/_action/translation/{locale}": {
- "delete": {
- "tags": [
- "Translation Management"
- ],
- "summary": "Uninstall a translation",
- "description": "Removes the downloaded translation files and the metadata entry for the given locale. The associated language, locale and snippet set records are left untouched and can be managed through their regular admin API endpoints.",
- "operationId": "translationDelete",
- "parameters": [
- {
- "name": "locale",
- "in": "path",
- "description": "The locale code to uninstall, for example `de-DE`.",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
+ },
+ "required": true
+ },
"responses": {
"204": {
- "description": "The translation files and metadata entry were removed."
+ "description": "Returns a no content response indicating that the update has been made."
}
}
}
@@ -83201,299 +83299,365 @@
}
}
},
- "/_action/scheduled-task/run": {
+ "/_action/order_transaction/{orderTransactionId}/state/{transition}": {
"post": {
"tags": [
- "System Operations"
+ "Order Management"
],
- "summary": "Run scheduled tasks.",
- "description": "Starts the scheduled task worker to handle the next scheduled tasks.",
- "operationId": "runScheduledTasks",
- "responses": {
- "200": {
- "description": "Returns a success message indicating a successful run.",
- "content": {
- "application/json": {
- "schema": {
- "properties": {
- "message": {
- "description": "Success message",
- "type": "string"
+ "summary": "Transition an order transaction to a new state",
+ "description": "Changes the order transaction state and informs the customer via email if configured.",
+ "operationId": "orderTransactionStateTransition",
+ "parameters": [
+ {
+ "name": "orderTransactionId",
+ "in": "path",
+ "description": "Identifier of the order transaction.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ {
+ "name": "transition",
+ "in": "path",
+ "description": "The `action_name` of the `state_machine_transition`. For example `process` if the order state should change from open to in progress.\n\nNote: If you choose a transition that is not available, you will get an error that lists possible transitions for the current state.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "sendMail": {
+ "description": "Controls if a mail should be sent to the customer."
+ },
+ "documentIds": {
+ "description": "A list of document identifiers that should be attached",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
}
},
- "type": "object"
- }
+ "mediaIds": {
+ "description": "A list of media identifiers that should be attached",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ "stateFieldName": {
+ "description": "This is the state column within the order transaction database table. There should be no need to change it from the default.",
+ "type": "string",
+ "default": "stateId"
+ },
+ "internalComment": {
+ "description": "An optional internal comment that will be saved with the state transition.",
+ "type": "string"
+ }
+ },
+ "type": "object"
}
}
}
+ },
+ "responses": {
+ "200": {
+ "description": "Returns information about the transition that was made. `#/components/schemas/StateMachineTransition`"
+ }
+ }
+ }
+ },
+ "/_action/order_transaction_capture_refund/{refundId}": {
+ "post": {
+ "tags": [
+ "Order Management"
+ ],
+ "summary": "Refund an order transaction capture",
+ "description": "Refunds an order transaction capture.",
+ "operationId": "orderTransactionCaptureRefund",
+ "parameters": [
+ {
+ "name": "refundId",
+ "in": "path",
+ "description": "Identifier of the order transaction capture refund.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Refund was successful"
+ },
+ "400": {
+ "description": "Something went wrong, while processing the refund"
+ },
+ "404": {
+ "description": "Refund with id not found"
+ }
}
}
},
- "/_action/scheduled-task/min-run-interval": {
+ "/_info/queue.json": {
"get": {
"tags": [
- "System Operations"
+ "System Info & Health Check"
],
- "summary": "Get the minimum schedules task interval",
- "description": "Fetches the smallest interval that a scheduled task uses.",
- "operationId": "getMinRunInterval",
+ "summary": "Get message queue statistics (deprecated)",
+ "description": "Returns increment-based message queue statistics.\n\n**Deprecated:** This endpoint is deprecated and will be removed in v6.8.0. Use `GET /_info/message-stats.json` instead for accurate message processing statistics.",
+ "operationId": "queue",
+ "deprecated": true,
"responses": {
"200": {
- "description": "Returns the minimum interval.",
+ "description": "Message queue statistics returned.",
"content": {
"application/json": {
"schema": {
- "properties": {
- "minRunInterval": {
- "description": "Minimal interval in seconds.",
- "type": "string"
- }
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Fully qualified class name of the message."
+ },
+ "size": {
+ "type": "integer",
+ "description": "Number of pending messages of this type."
+ }
+ },
+ "required": [
+ "name",
+ "size"
+ ]
+ }
+ },
+ "example": [
+ {
+ "name": "Shopware\\Core\\Content\\Product\\DataAbstractionLayer\\ProductIndexingMessage",
+ "size": 150
},
- "type": "object"
- }
+ {
+ "name": "Shopware\\Core\\Content\\Media\\Message\\GenerateThumbnailsMessage",
+ "size": 25
+ }
+ ]
}
}
}
}
}
},
- "/_action/media/{mediaId}/download": {
+ "/_action/sales-channel-file/{fileFamily}/{salesChannelId}": {
"get": {
"tags": [
- "Asset Management"
+ "Sales Channel Files"
],
- "summary": "Download a media file",
- "description": "Downloads a media file by its identifier.",
- "operationId": "downloadMedia",
+ "summary": "List discovered sales channel files",
+ "description": "Lists all discovered public files for a file family and sales channel, including content type and the stored sales-channel configuration when one exists.",
+ "operationId": "listSalesChannelFiles",
"parameters": [
{
- "name": "mediaId",
+ "name": "fileFamily",
"in": "path",
- "description": "Identifier of the media entity.",
+ "description": "File family below `Resources/views/files`, for example `agentic`.",
"required": true,
"schema": {
- "$ref": "#/components/schemas/MediaId"
+ "type": "string",
+ "maxLength": 64,
+ "pattern": "^[A-Za-z0-9_-]+$"
+ }
+ },
+ {
+ "name": "salesChannelId",
+ "in": "path",
+ "description": "Identifier of the sales channel for which stored configuration should be loaded.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
}
}
],
"responses": {
"200": {
- "description": "The media file.",
+ "description": "Discovered sales channel files for the given file family.",
"content": {
- "application/octet-stream": {
+ "application/json": {
"schema": {
- "type": "string",
- "format": "binary"
+ "$ref": "#/components/schemas/SalesChannelFileListResponse"
}
}
}
},
- "302": {
- "description": "Redirects to the resolved media download URL.",
- "headers": {
- "Location": {
- "description": "Contains the resolved media download URL.",
- "schema": {
- "type": "string"
- }
- }
- }
+ "400": {
+ "description": "Invalid file family.",
+ "$ref": "#/components/responses/400"
}
}
}
},
- "/_action/media/{mediaId}/download/prepare": {
+ "/_action/sales-channel-file/{fileFamily}/{salesChannelId}/detail": {
"get": {
"tags": [
- "Asset Management"
+ "Sales Channel Files"
],
- "summary": "Prepare a media download",
- "description": "Resolves the browser download URL for a media file by its identifier.",
- "operationId": "prepareMediaDownload",
+ "summary": "Load sales channel file detail",
+ "description": "Loads detail data for a discovered public file, including contributing Twig templates, their source content, and the stored sales-channel configuration when one exists.",
+ "operationId": "getSalesChannelFileDetail",
"parameters": [
{
- "name": "mediaId",
+ "name": "fileFamily",
"in": "path",
- "description": "Identifier of the media entity.",
+ "description": "File family below `Resources/views/files`, for example `agentic`.",
"required": true,
"schema": {
- "$ref": "#/components/schemas/MediaId"
+ "type": "string",
+ "maxLength": 64,
+ "pattern": "^[A-Za-z0-9_-]+$"
+ }
+ },
+ {
+ "name": "salesChannelId",
+ "in": "path",
+ "description": "Identifier of the sales channel for which stored configuration should be loaded.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ {
+ "name": "fileName",
+ "in": "query",
+ "description": "Public file path without a leading slash. Subfolders are supported, for example `.well-known/ucp.json`.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "examples": [
+ "llms.txt",
+ ".well-known/ucp.json"
+ ]
}
}
],
"responses": {
"200": {
- "description": "The resolved browser download strategy.",
+ "description": "Detail data for the discovered sales channel file.",
"content": {
"application/json": {
"schema": {
- "type": "object",
- "required": [
- "type"
- ],
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "external",
- "blob"
- ],
- "description": "Whether the frontend should trigger an external URL directly or fall back to an authenticated blob download."
- },
- "url": {
- "type": "string",
- "description": "External URL that should be used by the browser to start the download."
- }
- }
+ "$ref": "#/components/schemas/SalesChannelFileDetailResponse"
}
}
}
+ },
+ "400": {
+ "description": "Invalid file family or file name.",
+ "$ref": "#/components/responses/400"
+ },
+ "404": {
+ "description": "The requested sales channel file was not discovered.",
+ "$ref": "#/components/responses/404"
}
}
}
},
- "/_action/media/{mediaId}/upload": {
+ "/_action/sales-channel-file/{fileFamily}/{salesChannelId}/preview": {
"post": {
"tags": [
- "Asset Management"
+ "Sales Channel Files"
],
- "summary": "Upload a file to a media entity",
- "description": "Adds a new file to a media entity. If the entity has an existing file, it will be replaced.\n\nThe are two methods of providing a file to this route:\n * Use a typical file upload and provide the file in the request\n * Fetch the file from an url. This only works if the `shopware.media.enable_url_upload_feature` variable is set to true in the shop environment.\nTo use file upload via url, the content type has to be `application/json` and the parameter `url` has to be provided.",
- "operationId": "upload",
+ "summary": "Preview a sales channel file",
+ "description": "Renders a discovered public file for a sales channel with the supplied Twig template overrides. This allows Administration previews without persisting the overrides first.",
+ "operationId": "previewSalesChannelFile",
"parameters": [
{
- "name": "mediaId",
+ "name": "fileFamily",
"in": "path",
- "description": "Identifier of the media entity.",
+ "description": "File family below `Resources/views/files`, for example `agentic`.",
"required": true,
"schema": {
- "$ref": "#/components/schemas/MediaId"
- }
- },
- {
- "name": "fileName",
- "in": "query",
- "description": "Name of the uploaded file. If not provided the media identifier will be used as name",
- "schema": {
- "type": "string"
+ "type": "string",
+ "maxLength": 64,
+ "pattern": "^[A-Za-z0-9_-]+$"
}
},
{
- "name": "extension",
- "in": "query",
- "description": "Extension of the uploaded file. For example `png`",
+ "name": "salesChannelId",
+ "in": "path",
+ "description": "Identifier of the sales channel used to build the rendering context.",
"required": true,
"schema": {
- "type": "string"
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
}
}
],
"requestBody": {
+ "description": "Preview input containing the public file name and optional Twig overrides keyed by Twig namespace.",
+ "required": true,
"content": {
- "application/octet-stream": {
- "schema": {
- "type": "string",
- "format": "binary"
- }
- },
"application/json": {
"schema": {
- "required": [
- "url"
- ],
- "properties": {
- "url": {
- "description": "The url of the media file that will be downloaded.",
- "type": "string"
- }
- },
- "type": "object"
+ "$ref": "#/components/schemas/SalesChannelFilePreviewRequest"
}
}
}
},
"responses": {
- "204": {
- "description": "Media file uploaded successful",
- "headers": {
- "Location": {
- "description": "Contains the url to the uploaded media for a redirect.",
+ "200": {
+ "description": "Rendered preview content.",
+ "content": {
+ "application/json": {
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/SalesChannelFilePreviewResponse"
}
}
}
+ },
+ "400": {
+ "description": "Invalid request payload, file family, or file name.",
+ "$ref": "#/components/responses/400"
+ },
+ "404": {
+ "description": "The requested sales channel file was not discovered.",
+ "$ref": "#/components/responses/404"
}
}
}
},
- "/_action/media/upload": {
+ "/_action/scheduled-task/run": {
"post": {
"tags": [
- "Asset Management"
+ "System Operations"
],
- "summary": "Upload a new media file",
- "description": "Creates a new media entity and uploads a file to it using form-data file upload.",
- "operationId": "uploadV2",
- "requestBody": {
- "content": {
- "multipart/form-data": {
- "schema": {
- "type": "object",
- "properties": {
- "file": {
- "type": "string",
- "format": "binary",
- "description": "The file to upload"
- },
- "id": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "Custom ID for the media entity"
- },
- "fileName": {
- "type": "string",
- "description": "Name of the uploaded file"
- },
- "private": {
- "type": "boolean",
- "description": "Whether the media should be private"
- },
- "mediaFolderId": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the media folder"
- },
- "mimeType": {
- "type": "string",
- "description": "MIME type of the file"
- },
- "deduplicate": {
- "type": "boolean",
- "description": "Whether to deduplicate based on file hash"
- }
- },
- "required": [
- "file"
- ]
- }
- }
- }
- },
+ "summary": "Run scheduled tasks.",
+ "description": "Starts the scheduled task worker to handle the next scheduled tasks.",
+ "operationId": "runScheduledTasks",
"responses": {
"200": {
- "description": "Media file uploaded successfully",
+ "description": "Returns a success message indicating a successful run.",
"content": {
- "application\\/json": {
+ "application/json": {
"schema": {
- "type": "object",
"properties": {
- "id": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the created media entity"
+ "message": {
+ "description": "Success message",
+ "type": "string"
}
- }
+ },
+ "type": "object"
}
}
}
@@ -83501,72 +83665,61 @@
}
}
},
- "/_action/media/upload_by_url": {
- "post": {
+ "/_action/scheduled-task/min-run-interval": {
+ "get": {
"tags": [
- "Asset Management"
+ "System Operations"
],
- "summary": "Upload a media file from URL",
- "description": "Creates a new media entity by downloading and uploading a file from the provided URL. This only works if the `shopware.media.enable_url_upload_feature` variable is set to true in the shop environment.",
- "operationId": "uploadByUrl",
- "requestBody": {
- "content": {
- "application\\/json": {
- "schema": {
- "type": "object",
- "properties": {
- "url": {
- "type": "string",
- "description": "URL of the file to download and upload"
- },
- "id": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "Custom ID for the media entity"
- },
- "fileName": {
- "type": "string",
- "description": "Name of the uploaded file"
- },
- "private": {
- "type": "boolean",
- "description": "Whether the media should be private"
- },
- "mediaFolderId": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the media folder"
- },
- "mimeType": {
- "type": "string",
- "description": "MIME type of the file"
+ "summary": "Get the minimum schedules task interval",
+ "description": "Fetches the smallest interval that a scheduled task uses.",
+ "operationId": "getMinRunInterval",
+ "responses": {
+ "200": {
+ "description": "Returns the minimum interval.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "minRunInterval": {
+ "description": "Minimal interval in seconds.",
+ "type": "string"
+ }
},
- "deduplicate": {
- "type": "boolean",
- "description": "Whether to deduplicate based on file hash"
- }
- },
- "required": [
- "url"
- ]
+ "type": "object"
+ }
}
}
}
- },
+ }
+ }
+ },
+ "/oauth/sso/config": {
+ "get": {
+ "tags": [
+ "Experimental",
+ "Authorization & Authentication",
+ "SSO"
+ ],
+ "summary": "Experimental: Loads SSO login configuration.",
+ "description": "Experimental: Loads the SSO login configuration to configure the forward to the Shopware SSO login page.",
+ "operationId": "loadSsoLoginConfig",
"responses": {
"200": {
- "description": "Media file uploaded successfully",
+ "description": "Experimental: Returns the configuration for the SSO login page forward.",
"content": {
- "application\\/json": {
+ "application/json": {
"schema": {
- "type": "object",
"properties": {
- "id": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the created media entity"
+ "useDefault": {
+ "description": "Experimental: Indicates which login is used. Default or SSO.",
+ "type": "boolean"
+ },
+ "url": {
+ "description": "Experimental: Contains the return url for the Shopware SSO login.",
+ "type": "string"
}
- }
+ },
+ "type": "object"
}
}
}
@@ -83574,447 +83727,249 @@
}
}
},
- "/_action/media/external-link": {
- "post": {
+ "/oauth/sso/code": {
+ "get": {
"tags": [
- "Asset Management"
+ "Experimental",
+ "Authorization & Authentication",
+ "SSO"
],
- "summary": "Create external media link",
- "description": "Creates a new media entity that links to an external URL without downloading the file.",
- "operationId": "externalLink",
- "requestBody": {
- "content": {
- "application\\/json": {
- "schema": {
- "type": "object",
- "properties": {
- "url": {
- "type": "string",
- "description": "URL of the external media file"
- },
- "id": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "Custom ID for the media entity"
- },
- "fileName": {
- "type": "string",
- "description": "Name of the file"
- },
- "private": {
- "type": "boolean",
- "description": "Whether the media should be private"
- },
- "mediaFolderId": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the media folder"
- },
- "mimeType": {
- "type": "string",
- "description": "MIME type of the file"
- },
- "deduplicate": {
- "type": "boolean",
- "description": "Whether to deduplicate based on path"
- },
- "thumbnails": {
- "type": "array",
- "description": "Optional list of external thumbnail URLs for the media entity. Used for CDNs that pre-generated thumbnails alongside the main media file.\nNot to be confused with [remote thumbnails](https://developer.shopware.com/docs/guides/plugins/plugins/content/media/remote-thumbnail-generation.html#remote-thumbnail-generation), which are generated based on a pattern.",
- "items": {
- "$ref": "#/components/schemas/ExternalThumbnail"
- }
- }
- },
- "required": [
- "url",
- "mimeType"
- ]
- }
- }
- }
- },
+ "summary": "Experimental: Callback for SSO login",
+ "description": "Experimental: Logs in the user into the Shopware shop and forwards to the admin",
+ "operationId": "callBackWithCode",
"responses": {
"200": {
- "description": "External media link created successfully",
+ "description": "Authorisation process continues",
"content": {
- "application\\/json": {
+ "application/json": {
"schema": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the created media entity"
- }
- }
+ "type": "object"
}
}
}
+ },
+ "302": {
+ "description": "Experimental: Forwards to the Shopware admin"
}
}
}
},
- "/_action/media/presign-upload": {
- "post": {
+ "/oauth/sso/auth": {
+ "get": {
"tags": [
- "Asset Management"
+ "Experimental",
+ "Authorization & Authentication",
+ "SSO"
],
- "summary": "Prepare a presigned upload",
- "description": "Creates or reuses a media entity and returns a presigned S3 URL for direct browser-to-storage upload. The client uploads the file directly to the returned URL, then calls the finalize endpoint.",
- "operationId": "presignUpload",
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "required": [
- "fileName",
- "extension",
- "mimeType"
- ],
- "properties": {
- "fileName": {
- "type": "string",
- "description": "Name of the file without extension"
- },
- "extension": {
- "type": "string",
- "description": "File extension, e.g. `jpg`, `png`, `pdf`"
- },
- "mimeType": {
- "type": "string",
- "description": "MIME type of the file, e.g. `image/jpeg`"
- },
- "mediaFolderId": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the media folder to place the new media in"
- },
- "private": {
- "type": "boolean",
- "default": false,
- "description": "Whether the media should be private"
- },
- "mediaId": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of an existing media entity to replace. If omitted, a new entity is created."
- }
- }
- }
- }
- }
- },
+ "summary": "Experimental: Redirect to SSO login",
+ "description": "Experimental: Creates a redirection to the SSO login page",
+ "operationId": "ssoAuth",
"responses": {
"200": {
- "description": "Presigned upload prepared successfully",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "required": [
- "mediaId",
- "url",
- "path",
- "expiresAt",
- "isDuplicate"
- ],
- "properties": {
- "mediaId": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the media entity"
- },
- "url": {
- "type": "string",
- "description": "Presigned URL to upload the file to via HTTP PUT"
- },
- "path": {
- "type": "string",
- "description": "Storage path of the media file, required for the finalize call"
- },
- "expiresAt": {
- "type": "string",
- "format": "date-time",
- "description": "Expiration time of the presigned URL"
- },
- "isDuplicate": {
- "type": "boolean",
- "description": "Whether a file with the same name already exists"
- }
- }
- }
- }
- }
- },
- "400": {
- "description": "Bad request. The file extension is not supported or the file name is invalid.",
- "$ref": "#/components/responses/400"
- },
- "404": {
- "description": "The media entity with the given `mediaId` was not found.",
- "$ref": "#/components/responses/404"
+ "description": "Starts the SSO login flow."
},
- "422": {
- "description": "Validation error. Required fields (`fileName`, `extension`, `mimeType`) must not be blank.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/failure"
- }
- }
- }
+ "302": {
+ "description": "Experimental: Forwards to SSO login Page"
}
}
}
},
- "/_action/media/{mediaId}/finalize-upload": {
- "post": {
+ "/_info/is-sso": {
+ "get": {
"tags": [
- "Asset Management"
+ "Experimental",
+ "Authorization & Authentication",
+ "SSO"
],
- "summary": "Finalize a presigned upload",
- "description": "Confirms that the file has been uploaded to storage via the presigned URL and updates the media entity with file metadata.",
- "operationId": "finalizeUpload",
- "parameters": [
- {
- "name": "mediaId",
- "in": "path",
- "required": true,
- "description": "ID of the media entity to finalize",
- "schema": {
- "$ref": "#/components/schemas/MediaId"
- }
+ "summary": "Experimental: Is SSO environment",
+ "description": "Experimental: Returns a boolean which indicates the it is a SSO environment or not",
+ "operationId": "isSso",
+ "responses": {
+ "200": {
+ "description": "Experimental: Returns if it is a SSO environment or not"
}
+ }
+ }
+ },
+ "/_action/sso/invite-user": {
+ "post": {
+ "tags": [
+ "Experimental",
+ "Authorization & Authentication",
+ "SSO"
],
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "required": [
- "fileName",
- "extension",
- "mimeType",
- "path"
- ],
- "properties": {
- "fileName": {
- "type": "string",
- "description": "Name of the file without extension"
- },
- "extension": {
- "type": "string",
- "description": "File extension, e.g. `jpg`, `png`, `pdf`"
- },
- "mimeType": {
- "type": "string",
- "description": "MIME type of the file"
- },
- "path": {
- "type": "string",
- "description": "Storage path returned by the presign-upload endpoint"
- },
- "width": {
- "type": "integer",
- "description": "Image width in pixels (optional, for images only)"
- },
- "height": {
- "type": "integer",
- "description": "Image height in pixels (optional, for images only)"
- }
- }
- }
- }
- }
- },
+ "summary": "Experimental: Invite a new SSO user",
+ "description": "Experimental: Invite a new SSO user and sends a e-mail with the invite",
+ "operationId": "inviteUser",
"responses": {
"200": {
- "description": "Upload finalized successfully",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "required": [
- "mediaId"
- ],
- "properties": {
- "mediaId": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the finalized media entity"
- }
- }
- }
- }
- }
- },
- "400": {
- "description": "Bad request. The file extension is not supported, the storage path does not match, the file name is already taken, or the file could not be found on the remote storage.",
- "$ref": "#/components/responses/400"
- },
- "404": {
- "description": "The media entity with the given `mediaId` was not found.",
- "$ref": "#/components/responses/404"
- },
- "422": {
- "description": "Validation error. Required fields (`fileName`, `extension`, `mimeType`, `path`) must not be blank.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/failure"
- }
- }
- }
+ "description": "Experimental: Invite a new SSO user and sends a e-mail with the invite"
}
}
}
},
- "/_action/media/{mediaId}/external-thumbnails": {
- "post": {
+ "/_action/state-machine/{entityName}/{entityId}/state": {
+ "get": {
"tags": [
- "Asset Management"
+ "State Machine"
],
- "summary": "Add external thumbnails to media",
- "description": "Attaches external thumbnail URLs to an existing external media entity. The media must have an HTTP/HTTPS path (i.e. be an external media link).\n\nUsed for CDNs that pre-generated thumbnails alongside the main media file.\nNot to be confused with [remote thumbnails](https://developer.shopware.com/docs/guides/plugins/plugins/content/media/remote-thumbnail-generation.html#remote-thumbnail-generation), which are generated based on a pattern.\n\nThe thumbnail sized are matched against existing thumbnails sizes and a matching size will automatically be assigned. If there's not existing size, a **new thumbnail size will automatically be created** for each missing size.",
- "operationId": "addExternalThumbnails",
+ "summary": "Get available transitions for an entity",
+ "description": "Retrieves the available state transitions for the specified entity.",
+ "operationId": "getEntityState",
"parameters": [
{
- "name": "mediaId",
+ "name": "entityName",
"in": "path",
- "description": "ID of the external media entity the thumbnails will be attached to.",
+ "description": "Name of the entity.",
"required": true,
"schema": {
- "$ref": "#/components/schemas/MediaId"
- }
- }
- ],
- "requestBody": {
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "thumbnails": {
- "type": "array",
- "description": "List of external thumbnails to attach",
- "items": {
- "$ref": "#/components/schemas/ExternalThumbnail"
- }
- }
- }
- }
- }
- }
- },
- "responses": {
- "201": {
- "description": "Thumbnails attached successfully",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "mediaId": {
- "description": "ID of the media entity the thumbnails were attached to.",
- "$ref": "#/components/schemas/MediaId"
- },
- "thumbnailsCreated": {
- "type": "integer"
- }
- }
- }
- }
+ "type": "string"
}
},
- "400": {
- "description": "Media is not an external media entity or path is missing"
- },
- "404": {
- "description": "Media entity not found"
- }
- }
- },
- "delete": {
- "tags": [
- "Asset Management"
- ],
- "summary": "Delete all external thumbnails from media",
- "description": "Removes all externally stored thumbnail entries from the given media entity. Only works on external media (media with an HTTP/HTTPS path). Used to replace outdated thumbnails with new ones.",
- "operationId": "deleteExternalThumbnails",
- "parameters": [
{
- "name": "mediaId",
+ "name": "entityId",
"in": "path",
- "description": "ID of the external media entity the thumbnails will be deleted from..",
+ "description": "Identifier of the entity.",
"required": true,
"schema": {
- "$ref": "#/components/schemas/MediaId"
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ {
+ "name": "stateFieldName",
+ "in": "query",
+ "description": "This is the state column within the order delivery database table. There should be no need to change it from the default.",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "default": "stateId"
}
}
],
"responses": {
"200": {
- "description": "Thumbnails deleted successfully",
+ "description": "Available transitions for the current state.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
- "mediaId": {
- "description": "ID of the media entity the thumbnails were deleted from.",
- "$ref": "#/components/schemas/MediaId"
+ "transitions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the transition."
+ },
+ "technicalName": {
+ "type": "string",
+ "description": "The technical name of the transition."
+ },
+ "actionName": {
+ "type": "string",
+ "description": "The action name of the transition."
+ },
+ "fromStateName": {
+ "type": "string",
+ "description": "The technical name of the state the transition starts from."
+ },
+ "toStateName": {
+ "type": "string",
+ "description": "The technical name of the state the transition goes to."
+ },
+ "url": {
+ "type": "string",
+ "description": "The URL to trigger the transition."
+ }
+ },
+ "required": [
+ "name",
+ "technicalName",
+ "actionName",
+ "fromStateName",
+ "toStateName",
+ "url"
+ ]
+ }
}
- }
+ },
+ "required": [
+ "transitions"
+ ]
}
}
}
},
"400": {
- "description": "Media is not an external media entity or path is missing"
+ "description": "Unable to read the entity or entity field."
},
- "404": {
- "description": "Media entity not found"
+ "403": {
+ "description": "Forbidden. Missing privileges to access the entity."
}
}
}
},
- "/_action/media/{mediaId}/video-cover": {
+ "/_action/state-machine/{entityName}/{entityId}/state/{transition}": {
"post": {
"tags": [
- "Asset Management"
+ "State Machine"
],
- "summary": "Assign or remove a video cover image",
- "description": "Assigns an image as a cover for a video media entity, or removes the cover if `coverMediaId` is null.",
- "operationId": "assignVideoCover",
+ "summary": "Transition an entity to a new state",
+ "description": "Changes the entity state by applying the given transition.",
+ "operationId": "transitionEntityState",
"parameters": [
{
- "name": "mediaId",
+ "name": "entityName",
"in": "path",
+ "description": "Name of the entity.",
"required": true,
- "description": "ID of the video media entity",
"schema": {
- "$ref": "#/components/schemas/MediaId"
+ "type": "string"
+ }
+ },
+ {
+ "name": "entityId",
+ "in": "path",
+ "description": "Identifier of the entity.",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ }
+ },
+ {
+ "name": "transition",
+ "in": "path",
+ "description": "The `action_name` of the `state_machine_transition`.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "stateFieldName",
+ "in": "query",
+ "description": "This is the state column within the order delivery database table. There should be no need to change it from the default.",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "default": "stateId"
}
}
],
"requestBody": {
+ "description": "Optional internal comment for the state transition.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
- "coverMediaId": {
- "type": [
- "string",
- "null"
- ],
- "pattern": "^[0-9a-f]{32}$",
- "description": "ID of the image media entity to use as cover. Set to null to remove the cover."
+ "internalComment": {
+ "type": "string",
+ "description": "An optional internal comment that will be saved with the state transition."
}
}
}
@@ -84022,158 +83977,46 @@
}
},
"responses": {
- "204": {
- "description": "Video cover assigned or removed successfully"
+ "200": {
+ "description": "State transition applied successfully."
},
"400": {
- "description": "Invalid request"
+ "description": "Unable to read the entity or entity field, or invalid transition."
+ },
+ "403": {
+ "description": "Forbidden. Missing privileges to access the entity."
}
}
}
},
- "/_info/version": {
- "get": {
+ "/_action/sync": {
+ "post": {
"tags": [
- "System Info & Health Check"
- ],
- "summary": "Get the Shopware version",
- "description": "Get the version of the Shopware instance",
- "operationId": "infoShopwareVersion",
- "responses": {
- "200": {
- "description": "Returns the version of the Shopware instance.",
- "content": {
- "application/json": {
- "schema": {
- "properties": {
- "version": {
- "description": "The Shopware version.",
- "type": "string"
- }
- },
- "type": "object"
- }
- }
- }
- }
- }
- }
- },
- "/_action/index": {
- "post": {
- "tags": [
- "System Operations"
- ],
- "summary": "Run indexer",
- "description": "Runs all registered indexer in the shop asynchronously.",
- "operationId": "index",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "properties": {
- "skip": {
- "description": "Array of indexers/updaters to be skipped.",
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "type": "object"
- }
- }
- }
- },
- "responses": {
- "204": {
- "description": "Returns a no content response indicating that the indexing progress startet."
- }
- }
- }
- },
- "/_action/cache": {
- "delete": {
- "tags": [
- "System Operations"
- ],
- "summary": "Clear caches",
- "description": "The cache is immediately cleared synchronously for all used adapters.",
- "operationId": "clearCache",
- "responses": {
- "204": {
- "description": "Returns a no content response indicating that the cache has been cleared."
- }
- }
- }
- },
- "/_action/cache-delayed": {
- "delete": {
- "tags": [
- "System Operations"
+ "Bulk Operations"
],
- "summary": "Clear all invalidated caches",
- "description": "Directly triggers invalidation of all cache tags that were marked for invalidation.",
- "operationId": "clearCacheDelayed",
+ "summary": "Bulk edit entities",
+ "description": "Starts a sync process for the list of provided actions. This can be upserts and deletes on different entities to an asynchronous process in the background. You can control the behaviour with the `indexing-behavior` header.",
+ "operationId": "sync",
"parameters": [
{
- "name": "refreshOpenSearch",
- "in": "query",
- "required": false,
- "description": "This parameter indicates that in addition to invalidating the delayed caches, the opensearch indices will also be refreshed, which should lead to a clean state on the next read requests. When OpenSearch is not used this parameter will be ignored.",
+ "name": "fail-on-error",
+ "in": "header",
+ "description": "To continue upcoming actions on errors, set the `fail-on-error` header to `false`.",
"schema": {
"type": "boolean",
- "default": false
- }
- }
- ],
- "responses": {
- "204": {
- "description": "Returns a no content response indicating that the cache has been cleared."
- }
- }
- }
- },
- "/_action/index-products": {
- "post": {
- "tags": [
- "System Operations"
- ],
- "summary": "Send product indexing message",
- "description": "Dispatches a product indexing message to the message bus, with the provided ids",
- "operationId": "productIndexing",
- "responses": {
- "204": {
- "description": "Returns an empty response indicating that the message dispatched."
- }
- }
- }
- },
- "/_action/increment/{pool}": {
- "post": {
- "tags": [
- "Increment Storage"
- ],
- "summary": "Increment a value in the specified pool",
- "description": "Increments a value by key in the specified increment pool. This operation increments the counter for the given key and returns a success response.",
- "operationId": "incrementValue",
- "parameters": [
- {
- "name": "pool",
- "in": "path",
- "description": "The name of the increment pool (e.g., 'user_activity', 'message_queue').",
- "required": true,
- "schema": {
- "type": "string"
+ "default": true
}
},
{
- "name": "cluster",
- "in": "query",
- "description": "Optional cluster identifier for the increment operation.",
- "required": false,
+ "name": "indexing-behavior",
+ "in": "header",
+ "description": "Controls the indexing behavior.\n - `disable-indexing`: Data indexing is completely disabled",
"schema": {
- "type": "string"
+ "type": "string",
+ "enum": [
+ "use-queue-indexing",
+ "disable-indexing"
+ ]
}
}
],
@@ -84182,15 +84025,56 @@
"content": {
"application/json": {
"schema": {
- "type": "object",
- "required": [
- "key"
- ],
- "properties": {
- "key": {
- "type": "string",
- "description": "The key to increment in the pool."
- }
+ "type": "array",
+ "items": {
+ "required": [
+ "action",
+ "entity",
+ "payload"
+ ],
+ "properties": {
+ "action": {
+ "description": "The action indicates what should happen with the provided payload.\n * `upsert`: The Sync API does not differ between create and update operations,\n but always performs an upsert operation. During an upsert, the system checks whether the entity already exists in the\n system and updates it if an identifier has been passed, otherwise a new entity is created with this identifier.\n * `delete`: Deletes entities with the provided identifiers",
+ "type": "string",
+ "enum": [
+ "upsert",
+ "delete"
+ ]
+ },
+ "entity": {
+ "description": "The entity that should be processed with the payload.",
+ "type": "string",
+ "example": "product"
+ },
+ "payload": {
+ "description": "Contains a list of changesets for an entity. If the action type is `delete`,\n a list of identifiers can be provided.",
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "criteria": {
+ "description": "Only for delete operations: Instead of providing IDs in the payload, the filter by which should be deleted can be provided directly.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/SimpleFilter"
+ },
+ {
+ "$ref": "#/components/schemas/EqualsFilter"
+ },
+ {
+ "$ref": "#/components/schemas/MultiNotFilter"
+ },
+ {
+ "$ref": "#/components/schemas/RangeFilter"
+ }
+ ]
+ }
+ }
+ },
+ "type": "object"
}
}
}
@@ -84198,287 +84082,200 @@
},
"responses": {
"200": {
- "description": "Successfully incremented the value",
+ "description": "Returns a sync result containing information about the updated entities",
"content": {
"application/json": {
"schema": {
- "type": "object",
"properties": {
- "success": {
- "type": "boolean",
- "example": true
+ "data": {
+ "description": "Object with information about updated entities",
+ "type": "object"
+ },
+ "notFound": {
+ "description": "Object with information about not found entities",
+ "type": "object"
+ },
+ "deleted": {
+ "description": "Object with information about deleted entities",
+ "type": "object"
}
- }
+ },
+ "type": "object"
}
}
}
- },
- "400": {
- "description": "Bad request - key parameter missing or cluster parameter missing"
}
}
- },
+ }
+ },
+ "/_action/system-config": {
"get": {
"tags": [
- "Increment Storage"
+ "System Config"
],
- "summary": "List increment values from pool",
- "description": "Retrieves a list of increment values from the specified pool with pagination support.",
- "operationId": "getIncrementValues",
+ "summary": "Get configuration values",
+ "description": "Returns the configuration values for the given domain and optional sales channel.",
+ "operationId": "getConfigurationValues",
"parameters": [
{
- "name": "pool",
- "in": "path",
- "description": "The name of the increment pool to list values from.",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "cluster",
+ "name": "domain",
"in": "query",
- "description": "Cluster identifier for the increment operation.",
+ "description": "The configuration domain.",
"required": true,
"schema": {
"type": "string"
}
},
{
- "name": "limit",
+ "name": "salesChannelId",
"in": "query",
- "description": "Maximum number of items to return.",
- "required": false,
+ "description": "The sales channel ID to scope the configuration to.",
"schema": {
- "type": "integer",
- "default": 5,
- "minimum": 1
+ "type": "string"
}
},
{
- "name": "offset",
+ "name": "inherit",
"in": "query",
- "description": "Number of items to skip for pagination.",
- "required": false,
+ "description": "Whether to include inherited (global) values.",
"schema": {
- "type": "integer",
- "default": 0,
- "minimum": 0
+ "type": "boolean",
+ "default": false
}
}
],
"responses": {
"200": {
- "description": "List of increment values",
- "content": {
- "application/json": {
- "schema": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "key": {
- "type": "string",
- "description": "The increment key"
- },
- "count": {
- "type": "integer",
- "description": "The current count value"
- }
- }
- }
- }
- }
- }
- },
- "400": {
- "description": "Bad request - cluster parameter missing"
+ "description": "Returns the configuration values as a key-value object."
}
}
- }
- },
- "/_action/decrement/{pool}": {
+ },
"post": {
"tags": [
- "Increment Storage"
+ "System Config"
],
- "summary": "Decrement a value in the specified pool",
- "description": "Decrements a value by key in the specified increment pool. This operation decrements the counter for the given key and returns a success response.",
- "operationId": "decrementValue",
+ "summary": "Save configuration values",
+ "description": "Saves the given configuration key-value pairs for the given sales channel.",
+ "operationId": "saveConfiguration",
"parameters": [
{
- "name": "pool",
- "in": "path",
- "description": "The name of the increment pool.",
- "required": true,
+ "name": "salesChannelId",
+ "in": "query",
+ "description": "The sales channel ID to scope the configuration to.",
"schema": {
"type": "string"
}
},
{
- "name": "cluster",
+ "name": "silent",
"in": "query",
- "description": "Optional cluster identifier for the decrement operation.",
- "required": false,
+ "description": "If true, the HTTP cache will not be invalidated. Use this for internal configuration values that do not affect the storefront.",
"schema": {
- "type": "string"
+ "type": "boolean",
+ "default": false
}
}
],
"requestBody": {
+ "description": "Key-value pairs of configuration values to save.",
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
- "required": [
- "key"
- ],
- "properties": {
- "key": {
- "type": "string",
- "description": "The key to decrement in the pool."
- }
- }
+ "additionalProperties": true
}
}
}
},
"responses": {
- "200": {
- "description": "Successfully decremented the value",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "success": {
- "type": "boolean",
- "example": true
- }
- }
- }
- }
- }
- },
- "400": {
- "description": "Bad request - key parameter missing or cluster parameter missing"
+ "204": {
+ "description": "Configuration saved successfully."
}
}
}
},
- "/_action/reset-increment/{pool}": {
- "post": {
+ "/_action/system-config/check": {
+ "get": {
"tags": [
- "Increment Storage"
+ "System Config"
],
- "summary": "Reset increment values in pool",
- "description": "Resets increment values in the specified pool. Can reset all values or a specific key if provided.",
- "operationId": "resetIncrementValues",
+ "summary": "Check configuration",
+ "description": "Checks if a configuration domain exists.",
+ "operationId": "checkConfiguration",
"parameters": [
{
- "name": "pool",
- "in": "path",
- "description": "The name of the increment pool to reset.",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "cluster",
+ "name": "domain",
"in": "query",
- "description": "Cluster identifier for the reset operation.",
+ "description": "The configuration domain to check.",
"required": true,
"schema": {
"type": "string"
}
}
],
- "requestBody": {
- "required": false,
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "key": {
- "type": "string",
- "description": "Optional specific key to reset. If not provided, all values in the pool will be reset."
- }
- }
- }
- }
- }
- },
"responses": {
"200": {
- "description": "Successfully reset the increment values",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "success": {
- "type": "boolean",
- "example": true
- }
- }
- }
- }
- }
- },
- "400": {
- "description": "Bad request - cluster parameter missing"
+ "description": "Returns whether the configuration domain exists."
}
}
}
},
- "/_action/delete-increment/{pool}": {
- "delete": {
+ "/_action/system-config/schema": {
+ "get": {
"tags": [
- "Increment Storage"
+ "System Config"
],
- "summary": "Delete increment keys from pool",
- "description": "Deletes specific increment keys from the specified pool.",
- "operationId": "deleteIncrementKeys",
+ "summary": "Get configuration schema",
+ "description": "Returns the configuration schema for the given domain.",
+ "operationId": "getConfiguration",
"parameters": [
{
- "name": "pool",
- "in": "path",
- "description": "The name of the increment pool to delete keys from.",
+ "name": "domain",
+ "in": "query",
+ "description": "The configuration domain.",
"required": true,
"schema": {
"type": "string"
}
- },
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Returns the configuration schema."
+ }
+ }
+ }
+ },
+ "/_action/system-config/batch": {
+ "post": {
+ "tags": [
+ "System Config"
+ ],
+ "summary": "Batch save configuration values",
+ "description": "Saves configuration values for multiple sales channels at once. The request body is keyed by sales channel ID (use \"null\" for global scope).",
+ "operationId": "batchSaveConfiguration",
+ "parameters": [
{
- "name": "cluster",
+ "name": "silent",
"in": "query",
- "description": "Cluster identifier for the delete operation.",
- "required": true,
+ "description": "If true, the HTTP cache will not be invalidated. Use this for internal configuration values that do not affect the storefront.",
"schema": {
- "type": "string"
+ "type": "boolean",
+ "default": false
}
}
],
"requestBody": {
+ "description": "Object keyed by sales channel ID, each containing key-value pairs of configuration values.",
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
- "required": [
- "keys"
- ],
- "properties": {
- "keys": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "Array of keys to delete from the pool."
- }
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": true
}
}
}
@@ -84486,70 +84283,128 @@
},
"responses": {
"204": {
- "description": "Successfully deleted the increment keys"
- },
- "400": {
- "description": "Bad request - invalid keys parameter or cluster parameter missing"
+ "description": "Configuration saved successfully."
}
}
}
},
- "/_action/user/logout": {
+ "/oauth/token": {
"post": {
"tags": [
"Authorization & Authentication"
],
- "summary": "Logout the current user",
- "description": "Revokes all server-side refresh tokens for the currently authenticated administration user and returns a no content response.",
- "operationId": "userLogout",
+ "summary": "Fetch an access token",
+ "description": "Fetch a access token that can be used to perform authenticated requests. For more information take a look at the [Authentication documentation](https://shopware.stoplight.io/docs/admin-api/docs/concepts/authentication-authorisation.md).",
+ "operationId": "token",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/OAuthPasswordGrant"
+ },
+ {
+ "$ref": "#/components/schemas/OAuthRefreshTokenGrant"
+ },
+ {
+ "$ref": "#/components/schemas/OAuthClientCredentialsGrant"
+ }
+ ]
+ }
+ }
+ }
+ },
"responses": {
- "204": {
- "description": "Tokens have been revoked successfully."
- },
- "401": {
- "description": "Unauthorized - the access token is missing or invalid."
+ "200": {
+ "description": "Authorized successfully.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "required": [
+ "token_type",
+ "expires_in",
+ "access_token"
+ ],
+ "properties": {
+ "token_type": {
+ "description": "Type of the token.",
+ "type": "string"
+ },
+ "expires_in": {
+ "description": "Token lifetime in seconds.",
+ "type": "integer"
+ },
+ "access_token": {
+ "description": "The access token that can be used for subsequent requests",
+ "type": "string"
+ },
+ "refresh_token": {
+ "description": "The refresh token that can be used to refresh the access token. This field is not returned on grant type `refresh_token`.",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
},
- "403": {
- "description": "The authenticated source does not have a user ID associated."
+ "400": {
+ "$ref": "#/components/responses/400"
}
}
}
},
- "/_info/routes": {
+ "/_action/translation/list": {
"get": {
- "summary": "Get API routes",
- "operationId": "getRoutes",
"tags": [
- "System Info & Health Check"
+ "Translation Management"
],
+ "summary": "List configured translation locales",
+ "description": "Lists every locale configured for translation download, merging its local install state with the remotely available metadata.",
+ "operationId": "translationList",
"responses": {
"200": {
- "description": "Successful operation",
+ "description": "The configured locales with their merged local install state and remote metadata.",
"content": {
"application/json": {
"schema": {
"type": "object",
- "required": [
- "endpoints"
- ],
"properties": {
- "endpoints": {
+ "total": {
+ "description": "Number of configured locales.",
+ "type": "integer"
+ },
+ "items": {
"type": "array",
"items": {
"type": "object",
- "required": [
- "methods",
- "path"
- ],
"properties": {
- "methods": {
- "type": "array",
- "items": {
- "type": "string"
- }
+ "locale": {
+ "description": "The locale code, for example `de-DE`.",
+ "type": "string"
},
- "path": {
+ "name": {
+ "description": "The configured language name.",
"type": "string"
+ },
+ "lastUpdate": {
+ "description": "ISO-8601 timestamp of the last installation, or null if not installed.",
+ "type": "string",
+ "format": "date-time"
+ },
+ "progress": {
+ "description": "Translation completeness in percent, taken from the remote metadata. Null when the remote source is unreachable or does not offer the locale.",
+ "type": "integer"
+ },
+ "updateAvailable": {
+ "description": "Whether a newer translation than the installed one is available.",
+ "type": "boolean"
+ },
+ "isPseudoLanguage": {
+ "description": "Whether the locale is a pseudo-language used for translation testing.",
+ "type": "boolean"
}
}
}
@@ -84562,21 +84417,43 @@
}
}
},
- "/_info/flow-actions.json": {
+ "/_action/translation/meta": {
"get": {
"tags": [
- "System Info & Health Check"
+ "Translation Management"
],
- "summary": "Get actions for flow builder",
- "description": "Get a list of action for flow builder.",
- "operationId": "flow-actions",
+ "summary": "Get translation meta information",
+ "description": "Returns translation meta information that is independent of the configured locales: the built-in locales, the community translation and documentation URLs and the completeness threshold.",
+ "operationId": "translationMeta",
"responses": {
"200": {
- "description": "Returns a list of action for flow builder.",
+ "description": "The translation meta information.",
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/flowBuilderActionsResponse"
+ "type": "object",
+ "properties": {
+ "builtInLocales": {
+ "description": "Locale codes shipped with the platform and excluded from the community translation download.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "communityTranslationsUrl": {
+ "description": "URL of the community translation platform, or null if not configured.",
+ "type": "string",
+ "format": "uri"
+ },
+ "documentationUrlSnippetKey": {
+ "description": "Admin snippet key that resolves to the localized translation documentation URL, or null if not configured.",
+ "type": "string"
+ },
+ "completenessThreshold": {
+ "description": "Minimum translation completeness in percent considered sufficient.",
+ "type": "integer"
+ }
+ }
}
}
}
@@ -84584,84 +84461,280 @@
}
}
},
- "/_info/health-check": {
- "get": {
+ "/_action/translation/install": {
+ "post": {
"tags": [
- "System Info & Health Check"
+ "Translation Management"
],
- "summary": "Check that the Application is running",
- "operationId": "healthCheck",
+ "summary": "Install translations for locales",
+ "description": "Downloads and installs translations for the given locales, or for all configured locales when `all` is set. Created languages are activated unless `activate` is set to `false`.",
+ "operationId": "translationInstall",
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "locales": {
+ "description": "Locale codes to install, for example `[\"de-DE\", \"fr-FR\"]`. Required unless `all` is true.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "all": {
+ "description": "Install all configured locales instead of the `locales` list.",
+ "type": "boolean"
+ },
+ "activate": {
+ "description": "Whether created languages are activated. Defaults to true.",
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ }
+ },
"responses": {
"200": {
- "description": "Returns empty response"
- },
- "500": {
- "description": "Application is not working properly"
+ "description": "The locales that were updated and the ones skipped as already up to date.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "updated": {
+ "description": "Locale codes that were downloaded and installed.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "skipped": {
+ "description": "Locale codes that were already up to date.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "unavailable": {
+ "description": "Requested locale codes that have no translation available and were not installed.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
}
}
}
},
- "/_info/system-health-check": {
- "get": {
+ "/_action/translation/update": {
+ "post": {
"tags": [
- "System Info & Health Check"
- ],
- "summary": "Perform a detailed system health check",
- "operationId": "systemHealthCheck",
- "parameters": [
- {
- "name": "verbose",
- "in": "query",
- "required": false,
- "schema": {
- "type": "boolean",
- "default": false
- },
- "description": "Include detailed information in the response"
- }
+ "Translation Management"
],
+ "summary": "Update all installed translations",
+ "description": "Updates all installed translations.",
+ "operationId": "translationUpdate",
"responses": {
"200": {
- "description": "Returns the system health check results",
+ "description": "The locales that were updated and the ones skipped as already up to date.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
- "checks": {
+ "updated": {
+ "description": "Locale codes that were downloaded and installed.",
"type": "array",
"items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "healthy": {
- "type": "boolean"
- },
- "status": {
- "type": "string"
- },
- "message": {
- "type": "string"
- },
- "extra": {
- "type": "array",
- "items": {
- "type": "object",
- "additionalProperties": true
- }
- }
- }
+ "type": "string"
+ }
+ },
+ "skipped": {
+ "description": "Locale codes that were already up to date.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "unavailable": {
+ "description": "Requested locale codes that have no translation available and were not installed.",
+ "type": "array",
+ "items": {
+ "type": "string"
}
}
}
}
}
}
+ }
+ }
+ }
+ },
+ "/_action/translation/{locale}": {
+ "delete": {
+ "tags": [
+ "Translation Management"
+ ],
+ "summary": "Uninstall a translation",
+ "description": "Removes the downloaded translation files and the metadata entry for the given locale. The associated language, locale and snippet set records are left untouched and can be managed through their regular admin API endpoints.",
+ "operationId": "translationDelete",
+ "parameters": [
+ {
+ "name": "locale",
+ "in": "path",
+ "description": "The locale code to uninstall, for example `de-DE`.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "The translation files and metadata entry were removed."
+ }
+ }
+ }
+ },
+ "/_action/user/logout": {
+ "post": {
+ "tags": [
+ "Authorization & Authentication"
+ ],
+ "summary": "Logout the current user",
+ "description": "Revokes all server-side refresh tokens for the currently authenticated administration user and returns a no content response.",
+ "operationId": "userLogout",
+ "responses": {
+ "204": {
+ "description": "Tokens have been revoked successfully."
},
- "500": {
- "description": "Application is not working properly"
+ "401": {
+ "description": "Unauthorized - the access token is missing or invalid."
+ },
+ "403": {
+ "description": "The authenticated source does not have a user ID associated."
+ }
+ }
+ }
+ },
+ "/_action/validation/email": {
+ "post": {
+ "tags": [
+ "Email support validation"
+ ],
+ "summary": "Email support.",
+ "description": "Checks a given email string.",
+ "operationId": "supportsEmail",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "required": [
+ "email"
+ ],
+ "properties": {
+ "email": {
+ "description": "The email to be verified.",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
+ "responses": {
+ "204": {
+ "description": "Email is supported"
+ },
+ "400": {
+ "description": "Invalid request payload. The argument 'email' may be missing.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "errors": {
+ "description": "Contains the error message.",
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "example": {
+ "errors": [
+ {
+ "code": "0",
+ "status": "400",
+ "title": "Unprocessable Content",
+ "detail": "This value should not be blank."
+ }
+ ]
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Email address is not supported.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "errors": {
+ "description": "Contains the validation error.",
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "example": {
+ "errors": [
+ {
+ "code": "0",
+ "status": "422",
+ "title": "Unprocessable Content",
+ "detail": "This value is not a supported email address."
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/_info/version": {
+ "get": {
+ "tags": [
+ "System Info & Health Check"
+ ],
+ "summary": "Get the Shopware version",
+ "description": "Get the version of the Shopware instance",
+ "operationId": "infoShopwareVersion",
+ "responses": {
+ "200": {
+ "description": "Returns the version of the Shopware instance.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "properties": {
+ "version": {
+ "description": "The Shopware version.",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
}
}
}
@@ -98791,6 +98864,10 @@
"active": {
"type": "boolean"
},
+ "translationAutoUpdate": {
+ "description": "Whether the scheduled task keeps the community translations of this language up to date. Enabled by default and only applied to linked languages.",
+ "type": "boolean"
+ },
"customFields": {
"type": "object"
},
@@ -99279,6 +99356,10 @@
"active": {
"type": "boolean"
},
+ "translationAutoUpdate": {
+ "description": "Whether the scheduled task keeps the community translations of this language up to date. Enabled by default and only applied to linked languages.",
+ "type": "boolean"
+ },
"customFields": {
"type": "object",
"description": "Additional fields that offer a possibility to add own fields for the different program-areas."
@@ -121679,6 +121760,10 @@
"description": "This is used to toggle the language configurations, say between DE and DE-DE for instance.",
"type": "boolean"
},
+ "isExternalStorefront": {
+ "description": "Whether the domain points to an external (headless) storefront.",
+ "type": "boolean"
+ },
"customFields": {
"type": "object"
},
@@ -121925,6 +122010,10 @@
"description": "This is used to toggle the language configurations, say between DE and DE-DE for instance.",
"type": "boolean"
},
+ "isExternalStorefront": {
+ "description": "Whether the domain points to an external (headless) storefront.",
+ "type": "boolean"
+ },
"customFields": {
"type": "object",
"description": "Additional fields that offer a possibility to add own fields for the different program-areas."
@@ -123499,6 +123588,10 @@
"description": "Created SEO URL template can be made usable by setting `isValid` to true.",
"type": "boolean"
},
+ "isHeadless": {
+ "description": "Whether the template applies to headless (API type) sales channels. Derived from the route family.",
+ "type": "boolean"
+ },
"customFields": {
"type": "object"
},
@@ -123585,6 +123678,10 @@
"description": "Created SEO URL template can be made usable by setting `isValid` to true.",
"type": "boolean"
},
+ "isHeadless": {
+ "description": "Whether the template applies to headless (API type) sales channels. Derived from the route family.",
+ "type": "boolean"
+ },
"customFields": {
"type": "object",
"description": "Additional fields that offer a possibility to add own fields for the different program-areas."
@@ -129207,313 +129304,6 @@
},
"type": "object"
},
- "ConsentState": {
- "type": "object",
- "required": [
- "name",
- "scopeName",
- "identifier",
- "status",
- "actor",
- "updatedAt",
- "acceptedUntil"
- ],
- "properties": {
- "name": {
- "type": "string",
- "description": "The name of the consent"
- },
- "scopeName": {
- "type": "string",
- "description": "The scope of the consent that defines how the identifier is resolved"
- },
- "identifier": {
- "type": "string",
- "description": "The resolved identifier of the consent"
- },
- "status": {
- "type": "string",
- "enum": [
- "unset",
- "accepted",
- "revoked"
- ],
- "description": "The current status of the consent (requested, accepted, revoked)"
- },
- "actor": {
- "type": [
- "string",
- "null"
- ],
- "description": "The user name of the user who made the consent decision. null if never updated"
- },
- "updatedAt": {
- "type": [
- "string",
- "null"
- ],
- "format": "date-time",
- "description": "The timestamp of when the consent status was last updated. null if never updated"
- },
- "acceptedUntil": {
- "type": [
- "string",
- "null"
- ],
- "format": "date-time",
- "description": "The timestamp until when the consent is accepted. null if never accepted"
- },
- "acceptedRevision": {
- "type": [
- "string",
- "null"
- ],
- "description": "The accepted consent revision. null unless the consent is currently accepted for a revision-aware consent."
- },
- "latestRevision": {
- "type": [
- "string",
- "null"
- ],
- "description": "The current latest revision defined for the consent. null when the consent does not use revisions."
- }
- }
- },
- "SalesChannelFileConfiguration": {
- "type": "object",
- "required": [
- "id",
- "enabled",
- "templateOverrides"
- ],
- "properties": {
- "id": {
- "description": "Identifier of the sales_channel_file row.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "enabled": {
- "description": "Whether this file is served publicly for the sales channel.",
- "type": "boolean"
- },
- "templateOverrides": {
- "description": "Merchant-provided Twig overrides keyed by Twig namespace. The reserved `user_provided_content` key stores plain text for the dedicated append block when supported by the template chain.",
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
- }
- }
- },
- "SalesChannelFileDescriptor": {
- "type": "object",
- "required": [
- "fileFamily",
- "fileName",
- "contentType",
- "configuration"
- ],
- "properties": {
- "fileFamily": {
- "description": "File family below `Resources/views/files`.",
- "type": "string",
- "maxLength": 64
- },
- "fileName": {
- "description": "Public file path without a leading slash.",
- "type": "string",
- "examples": [
- "llms.txt",
- ".well-known/ucp.json"
- ]
- },
- "contentType": {
- "description": "Detected response content type for the public file.",
- "type": "string",
- "examples": [
- "text/plain; charset=utf-8"
- ]
- },
- "configuration": {
- "description": "Stored sales-channel configuration for this file, or null when it has not been configured yet.",
- "oneOf": [
- {
- "$ref": "#/components/schemas/SalesChannelFileConfiguration"
- },
- {
- "type": "null"
- }
- ]
- }
- }
- },
- "SalesChannelFileDetail": {
- "type": "object",
- "required": [
- "fileFamily",
- "fileName",
- "templatePath",
- "contentType",
- "templates",
- "supportsUserProvidedContent",
- "configuration"
- ],
- "properties": {
- "fileFamily": {
- "description": "File family below `Resources/views/files`.",
- "type": "string",
- "maxLength": 64
- },
- "fileName": {
- "description": "Public file path without a leading slash.",
- "type": "string",
- "examples": [
- "llms.txt",
- ".well-known/ucp.json"
- ]
- },
- "templatePath": {
- "description": "Relative Twig template path used for rendering.",
- "type": "string",
- "examples": [
- "files/agentic/llms.txt.twig"
- ]
- },
- "contentType": {
- "description": "Detected response content type for the public file.",
- "type": "string",
- "examples": [
- "text/plain; charset=utf-8"
- ]
- },
- "templates": {
- "description": "Contributing Twig templates in resolved inheritance order.",
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/SalesChannelFileTemplate"
- }
- },
- "supportsUserProvidedContent": {
- "description": "Whether the template chain exposes the `user_provided_content` block for simple appended merchant notes.",
- "type": "boolean"
- },
- "configuration": {
- "description": "Stored sales-channel configuration for this file, or null when it has not been configured yet.",
- "oneOf": [
- {
- "$ref": "#/components/schemas/SalesChannelFileConfiguration"
- },
- {
- "type": "null"
- }
- ]
- }
- }
- },
- "SalesChannelFileDetailResponse": {
- "type": "object",
- "required": [
- "data"
- ],
- "properties": {
- "data": {
- "$ref": "#/components/schemas/SalesChannelFileDetail"
- }
- }
- },
- "SalesChannelFileListResponse": {
- "type": "object",
- "required": [
- "data"
- ],
- "properties": {
- "data": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/SalesChannelFileDescriptor"
- }
- }
- }
- },
- "SalesChannelFilePreviewRequest": {
- "type": "object",
- "required": [
- "fileName"
- ],
- "properties": {
- "fileName": {
- "description": "Public file path without a leading slash.",
- "type": "string",
- "examples": [
- "llms.txt",
- ".well-known/ucp.json"
- ]
- },
- "templateOverrides": {
- "description": "Unsaved Twig overrides keyed by Twig namespace. The reserved `user_provided_content` key stores plain text for the dedicated append block when supported by the template chain.",
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
- }
- }
- },
- "SalesChannelFilePreviewResponse": {
- "type": "object",
- "required": [
- "fileName",
- "contentType",
- "content"
- ],
- "properties": {
- "fileName": {
- "description": "Public file path without a leading slash.",
- "type": "string"
- },
- "contentType": {
- "description": "Detected content type of the rendered file.",
- "type": "string"
- },
- "content": {
- "description": "Rendered file content.",
- "type": "string"
- }
- }
- },
- "SalesChannelFileTemplate": {
- "type": "object",
- "required": [
- "twigNamespace",
- "templateName",
- "templateContent",
- "role"
- ],
- "properties": {
- "twigNamespace": {
- "description": "Twig namespace that contributed the template, for example `Framework` or a plugin name.",
- "type": "string"
- },
- "templateName": {
- "description": "Resolved Twig template name.",
- "type": "string",
- "examples": [
- "@Framework/files/agentic/llms.txt.twig"
- ]
- },
- "templateContent": {
- "description": "Original source template content. Administration clients can use this as the default text when editing a template override.",
- "type": "string"
- },
- "role": {
- "description": "Whether this source provides the base template or extends another source in the resolved template chain.",
- "type": "string",
- "enum": [
- "base",
- "extension"
- ]
- }
- }
- },
"Criteria": {
"type": "object",
"description": "Criteria to query entities.",
@@ -130234,6 +130024,373 @@
"field"
]
},
+ "MeasurementUnits": {
+ "type": "object",
+ "description": "Configuration of the measurement system",
+ "properties": {
+ "system": {
+ "type": "string",
+ "enum": [
+ "metric",
+ "imperial"
+ ],
+ "default": "metric",
+ "description": "The measurement system used in the store. 'metric' for metric system, 'imperial' for imperial system."
+ },
+ "units": {
+ "type": "object",
+ "description": "Units used in the measurement system.",
+ "properties": {
+ "length": {
+ "type": "string",
+ "enum": [
+ "mm",
+ "cm",
+ "m",
+ "in",
+ "ft"
+ ],
+ "default": "mm",
+ "description": "Unit of length."
+ },
+ "weight": {
+ "type": "string",
+ "enum": [
+ "g",
+ "kg",
+ "oz",
+ "lb"
+ ],
+ "default": "kg",
+ "description": "Unit of weight."
+ }
+ }
+ }
+ }
+ },
+ "MediaId": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$",
+ "description": "Media entity ID"
+ },
+ "ExternalThumbnail": {
+ "type": "object",
+ "description": "An external thumbnail URL with its dimensions. Used when a CDN provides pre-generated thumbnails alongside the main media file.",
+ "required": [
+ "url",
+ "width",
+ "height"
+ ],
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "Absolute HTTP/HTTPS URL of the thumbnail",
+ "example": "https://cdn.example.com/image-200x200.jpg"
+ },
+ "width": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Width of the thumbnail in pixels",
+ "example": 200
+ },
+ "height": {
+ "type": "integer",
+ "exclusiveMinimum": 0,
+ "description": "Height of the thumbnail in pixels",
+ "example": 200
+ }
+ }
+ },
+ "OAuthScopes": {
+ "description": "OAuth scopes that should be requested.",
+ "type": "string",
+ "enum": [
+ "write",
+ "user-verified",
+ "admin",
+ "write user-verified",
+ "write admin",
+ "user-verified admin",
+ "write user-verified admin"
+ ]
+ },
+ "OAuthGrant": {
+ "type": "object",
+ "properties": {
+ "grant_type": {
+ "description": "OAuth grant type that should be requested. See [OAuth 2.0 grant](https://oauth2.thephpleague.com/authorization-server/which-grant/) for more information.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "grant_type"
+ ],
+ "discriminator": {
+ "propertyName": "grant_type",
+ "mapping": {
+ "client_credentials": "#/components/schemas/OAuthClientCredentialsGrant",
+ "password": "#/components/schemas/OAuthPasswordGrant",
+ "refresh_token": "#/components/schemas/OAuthRefreshTokenGrant"
+ }
+ }
+ },
+ "OAuthClientCredentialsGrant": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/OAuthGrant"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "client_id": {
+ "description": "OAuth client id.",
+ "type": "string"
+ },
+ "client_secret": {
+ "description": "Password of the client that should be authenticated.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "client_id",
+ "client_secret"
+ ]
+ }
+ ]
+ },
+ "OAuthPasswordGrant": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/OAuthGrant"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "client_id": {
+ "description": "OAuth client id.",
+ "type": "string",
+ "enum": [
+ "administration"
+ ]
+ },
+ "scope": {
+ "$ref": "#/components/schemas/OAuthScopes"
+ },
+ "username": {
+ "description": "Username of the user that should be authenticated.",
+ "type": "string"
+ },
+ "password": {
+ "description": "Password of the user that should be authenticated.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "client_id",
+ "scope",
+ "username",
+ "password"
+ ]
+ }
+ ]
+ },
+ "OAuthRefreshTokenGrant": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/OAuthGrant"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "client_id": {
+ "description": "OAuth client id.",
+ "type": "string",
+ "enum": [
+ "administration"
+ ]
+ },
+ "scope": {
+ "$ref": "#/components/schemas/OAuthScopes"
+ },
+ "refresh_token": {
+ "description": "The refresh token that should be used to refresh the access token.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "client_id",
+ "scope",
+ "refresh_token"
+ ]
+ }
+ ]
+ },
+ "Price": {
+ "type": "object",
+ "description": "Price object",
+ "properties": {
+ "currencyId": {
+ "description": "Unique identity of the associated currency.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ },
+ "gross": {
+ "description": "Gross price for the associated currency.",
+ "type": "number"
+ },
+ "net": {
+ "description": "Net price for the associated currency.",
+ "type": "number"
+ },
+ "linked": {
+ "description": "Whether gross and net prices are linked through the tax configuration.",
+ "type": "boolean"
+ },
+ "percentage": {
+ "description": "Discount percentage relative to the list price for the gross and net amounts. `null` when no list price is set.",
+ "type": [
+ "object",
+ "null"
+ ],
+ "properties": {
+ "gross": {
+ "description": "Discount percentage relative to the gross list price.",
+ "type": "number"
+ },
+ "net": {
+ "description": "Discount percentage relative to the net list price.",
+ "type": "number"
+ }
+ },
+ "required": [
+ "gross",
+ "net"
+ ]
+ },
+ "listPrice": {
+ "description": "Reference list price for displaying discounts.",
+ "type": "object",
+ "properties": {
+ "currencyId": {
+ "description": "Unique identity of the associated currency.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ },
+ "gross": {
+ "description": "Gross list price for the associated currency.",
+ "type": "number"
+ },
+ "net": {
+ "description": "Net list price for the associated currency.",
+ "type": "number"
+ },
+ "linked": {
+ "description": "Whether gross and net list prices are linked through the tax configuration.",
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "gross",
+ "net",
+ "linked"
+ ]
+ },
+ "regulationPrice": {
+ "description": "Reference price used for legal price disclosures.",
+ "type": "object",
+ "properties": {
+ "currencyId": {
+ "description": "Unique identity of the associated currency.",
+ "type": "string",
+ "pattern": "^[0-9a-f]{32}$"
+ },
+ "gross": {
+ "description": "Gross regulation price for the associated currency.",
+ "type": "number"
+ },
+ "net": {
+ "description": "Net regulation price for the associated currency.",
+ "type": "number"
+ },
+ "linked": {
+ "description": "Whether gross and net regulation prices are linked through the tax configuration.",
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "gross",
+ "net",
+ "linked"
+ ]
+ }
+ },
+ "required": [
+ "currencyId",
+ "gross",
+ "net",
+ "linked"
+ ]
+ },
+ "businessEventsResponse": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Unique name of the businessEventsResponse."
+ },
+ "class": {
+ "type": "string",
+ "description": "Class name of business event."
+ },
+ "data": {
+ "type": "object",
+ "description": "Internal field."
+ },
+ "aware": {
+ "type": "array",
+ "description": "Parameter that indicates the areas in which the business event is supported.",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extensions": {
+ "type": "array",
+ "description": "Internal field.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "flowBuilderActionsResponse": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of the flow action"
+ },
+ "requirements": {
+ "type": "array",
+ "description": "When requirement fit with aware from `events.json` actions will be shown",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extensions": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Extensions data of event"
+ }
+ }
+ }
+ },
"infoConfigResponse": {
"type": "object",
"properties": {
@@ -130466,372 +130623,312 @@
],
"additionalProperties": false
},
- "Price": {
+ "ConsentState": {
"type": "object",
- "description": "Price object",
+ "required": [
+ "name",
+ "scopeName",
+ "identifier",
+ "status",
+ "actor",
+ "updatedAt",
+ "acceptedUntil"
+ ],
"properties": {
- "currencyId": {
- "description": "Unique identity of the associated currency.",
+ "name": {
"type": "string",
- "pattern": "^[0-9a-f]{32}$"
+ "description": "The name of the consent"
},
- "gross": {
- "description": "Gross price for the associated currency.",
- "type": "number"
+ "scopeName": {
+ "type": "string",
+ "description": "The scope of the consent that defines how the identifier is resolved"
},
- "net": {
- "description": "Net price for the associated currency.",
- "type": "number"
+ "identifier": {
+ "type": "string",
+ "description": "The resolved identifier of the consent"
},
- "linked": {
- "description": "Whether gross and net prices are linked through the tax configuration.",
- "type": "boolean"
+ "status": {
+ "type": "string",
+ "enum": [
+ "unset",
+ "accepted",
+ "revoked"
+ ],
+ "description": "The current status of the consent (requested, accepted, revoked)"
},
- "percentage": {
- "description": "Discount percentage relative to the list price for the gross and net amounts. `null` when no list price is set.",
+ "actor": {
"type": [
- "object",
+ "string",
"null"
],
- "properties": {
- "gross": {
- "description": "Discount percentage relative to the gross list price.",
- "type": "number"
- },
- "net": {
- "description": "Discount percentage relative to the net list price.",
- "type": "number"
- }
- },
- "required": [
- "gross",
- "net"
- ]
+ "description": "The user name of the user who made the consent decision. null if never updated"
},
- "listPrice": {
- "description": "Reference list price for displaying discounts.",
- "type": "object",
- "properties": {
- "currencyId": {
- "description": "Unique identity of the associated currency.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "gross": {
- "description": "Gross list price for the associated currency.",
- "type": "number"
- },
- "net": {
- "description": "Net list price for the associated currency.",
- "type": "number"
- },
- "linked": {
- "description": "Whether gross and net list prices are linked through the tax configuration.",
- "type": "boolean"
- }
- },
- "required": [
- "gross",
- "net",
- "linked"
- ]
+ "updatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time",
+ "description": "The timestamp of when the consent status was last updated. null if never updated"
},
- "regulationPrice": {
- "description": "Reference price used for legal price disclosures.",
- "type": "object",
- "properties": {
- "currencyId": {
- "description": "Unique identity of the associated currency.",
- "type": "string",
- "pattern": "^[0-9a-f]{32}$"
- },
- "gross": {
- "description": "Gross regulation price for the associated currency.",
- "type": "number"
- },
- "net": {
- "description": "Net regulation price for the associated currency.",
- "type": "number"
- },
- "linked": {
- "description": "Whether gross and net regulation prices are linked through the tax configuration.",
- "type": "boolean"
- }
- },
- "required": [
- "gross",
- "net",
- "linked"
- ]
- }
- },
- "required": [
- "currencyId",
- "gross",
- "net",
- "linked"
- ]
- },
- "businessEventsResponse": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "description": "Unique name of the businessEventsResponse."
- },
- "class": {
- "type": "string",
- "description": "Class name of business event."
- },
- "data": {
- "type": "object",
- "description": "Internal field."
- },
- "aware": {
- "type": "array",
- "description": "Parameter that indicates the areas in which the business event is supported.",
- "items": {
- "type": "string"
- }
- },
- "extensions": {
- "type": "array",
- "description": "Internal field.",
- "items": {
- "type": "string"
- }
- }
+ "acceptedUntil": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time",
+ "description": "The timestamp until when the consent is accepted. null if never accepted"
+ },
+ "acceptedRevision": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "The accepted consent revision. null unless the consent is currently accepted for a revision-aware consent."
+ },
+ "latestRevision": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "The current latest revision defined for the consent. null when the consent does not use revisions."
}
}
},
- "MeasurementUnits": {
+ "SalesChannelFileConfiguration": {
"type": "object",
- "description": "Configuration of the measurement system",
+ "required": [
+ "id",
+ "enabled",
+ "templateOverrides"
+ ],
"properties": {
- "system": {
+ "id": {
+ "description": "Identifier of the sales_channel_file row.",
"type": "string",
- "enum": [
- "metric",
- "imperial"
- ],
- "default": "metric",
- "description": "The measurement system used in the store. 'metric' for metric system, 'imperial' for imperial system."
+ "pattern": "^[0-9a-f]{32}$"
},
- "units": {
+ "enabled": {
+ "description": "Whether this file is served publicly for the sales channel.",
+ "type": "boolean"
+ },
+ "templateOverrides": {
+ "description": "Merchant-provided Twig overrides keyed by Twig namespace. The reserved `user_provided_content` key stores plain text for the dedicated append block when supported by the template chain.",
"type": "object",
- "description": "Units used in the measurement system.",
- "properties": {
- "length": {
- "type": "string",
- "enum": [
- "mm",
- "cm",
- "m",
- "in",
- "ft"
- ],
- "default": "mm",
- "description": "Unit of length."
- },
- "weight": {
- "type": "string",
- "enum": [
- "g",
- "kg",
- "oz",
- "lb"
- ],
- "default": "kg",
- "description": "Unit of weight."
- }
+ "additionalProperties": {
+ "type": "string"
}
}
}
},
- "MediaId": {
- "type": "string",
- "pattern": "^[0-9a-f]{32}$",
- "description": "Media entity ID"
- },
- "ExternalThumbnail": {
+ "SalesChannelFileDescriptor": {
"type": "object",
- "description": "An external thumbnail URL with its dimensions. Used when a CDN provides pre-generated thumbnails alongside the main media file.",
"required": [
- "url",
- "width",
- "height"
+ "fileFamily",
+ "fileName",
+ "contentType",
+ "configuration"
],
"properties": {
- "url": {
+ "fileFamily": {
+ "description": "File family below `Resources/views/files`.",
"type": "string",
- "description": "Absolute HTTP/HTTPS URL of the thumbnail",
- "example": "https://cdn.example.com/image-200x200.jpg"
+ "maxLength": 64
},
- "width": {
- "type": "integer",
- "exclusiveMinimum": 0,
- "description": "Width of the thumbnail in pixels",
- "example": 200
+ "fileName": {
+ "description": "Public file path without a leading slash.",
+ "type": "string",
+ "examples": [
+ "llms.txt",
+ ".well-known/ucp.json"
+ ]
},
- "height": {
- "type": "integer",
- "exclusiveMinimum": 0,
- "description": "Height of the thumbnail in pixels",
- "example": 200
+ "contentType": {
+ "description": "Detected response content type for the public file.",
+ "type": "string",
+ "examples": [
+ "text/plain; charset=utf-8"
+ ]
+ },
+ "configuration": {
+ "description": "Stored sales-channel configuration for this file, or null when it has not been configured yet.",
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/SalesChannelFileConfiguration"
+ },
+ {
+ "type": "null"
+ }
+ ]
}
}
},
- "flowBuilderActionsResponse": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "description": "Name of the flow action"
- },
- "requirements": {
- "type": "array",
- "description": "When requirement fit with aware from `events.json` actions will be shown",
- "items": {
- "type": "string"
- }
- },
- "extensions": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "description": "Extensions data of event"
+ "SalesChannelFileDetail": {
+ "type": "object",
+ "required": [
+ "fileFamily",
+ "fileName",
+ "templatePath",
+ "contentType",
+ "templates",
+ "supportsUserProvidedContent",
+ "configuration"
+ ],
+ "properties": {
+ "fileFamily": {
+ "description": "File family below `Resources/views/files`.",
+ "type": "string",
+ "maxLength": 64
+ },
+ "fileName": {
+ "description": "Public file path without a leading slash.",
+ "type": "string",
+ "examples": [
+ "llms.txt",
+ ".well-known/ucp.json"
+ ]
+ },
+ "templatePath": {
+ "description": "Relative Twig template path used for rendering.",
+ "type": "string",
+ "examples": [
+ "files/agentic/llms.txt.twig"
+ ]
+ },
+ "contentType": {
+ "description": "Detected response content type for the public file.",
+ "type": "string",
+ "examples": [
+ "text/plain; charset=utf-8"
+ ]
+ },
+ "templates": {
+ "description": "Contributing Twig templates in resolved inheritance order.",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SalesChannelFileTemplate"
}
+ },
+ "supportsUserProvidedContent": {
+ "description": "Whether the template chain exposes the `user_provided_content` block for simple appended merchant notes.",
+ "type": "boolean"
+ },
+ "configuration": {
+ "description": "Stored sales-channel configuration for this file, or null when it has not been configured yet.",
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/SalesChannelFileConfiguration"
+ },
+ {
+ "type": "null"
+ }
+ ]
}
}
},
- "OAuthScopes": {
- "description": "OAuth scopes that should be requested.",
- "type": "string",
- "enum": [
- "write",
- "user-verified",
- "admin",
- "write user-verified",
- "write admin",
- "user-verified admin",
- "write user-verified admin"
- ]
- },
- "OAuthGrant": {
+ "SalesChannelFileDetailResponse": {
"type": "object",
+ "required": [
+ "data"
+ ],
"properties": {
- "grant_type": {
- "description": "OAuth grant type that should be requested. See [OAuth 2.0 grant](https://oauth2.thephpleague.com/authorization-server/which-grant/) for more information.",
- "type": "string"
+ "data": {
+ "$ref": "#/components/schemas/SalesChannelFileDetail"
}
- },
+ }
+ },
+ "SalesChannelFileListResponse": {
+ "type": "object",
"required": [
- "grant_type"
+ "data"
],
- "discriminator": {
- "propertyName": "grant_type",
- "mapping": {
- "client_credentials": "#/components/schemas/OAuthClientCredentialsGrant",
- "password": "#/components/schemas/OAuthPasswordGrant",
- "refresh_token": "#/components/schemas/OAuthRefreshTokenGrant"
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SalesChannelFileDescriptor"
+ }
}
}
},
- "OAuthClientCredentialsGrant": {
- "allOf": [
- {
- "$ref": "#/components/schemas/OAuthGrant"
+ "SalesChannelFilePreviewRequest": {
+ "type": "object",
+ "required": [
+ "fileName"
+ ],
+ "properties": {
+ "fileName": {
+ "description": "Public file path without a leading slash.",
+ "type": "string",
+ "examples": [
+ "llms.txt",
+ ".well-known/ucp.json"
+ ]
},
- {
+ "templateOverrides": {
+ "description": "Unsaved Twig overrides keyed by Twig namespace. The reserved `user_provided_content` key stores plain text for the dedicated append block when supported by the template chain.",
"type": "object",
- "properties": {
- "client_id": {
- "description": "OAuth client id.",
- "type": "string"
- },
- "client_secret": {
- "description": "Password of the client that should be authenticated.",
- "type": "string"
- }
- },
- "required": [
- "client_id",
- "client_secret"
- ]
+ "additionalProperties": {
+ "type": "string"
+ }
}
- ]
+ }
},
- "OAuthPasswordGrant": {
- "allOf": [
- {
- "$ref": "#/components/schemas/OAuthGrant"
+ "SalesChannelFilePreviewResponse": {
+ "type": "object",
+ "required": [
+ "fileName",
+ "contentType",
+ "content"
+ ],
+ "properties": {
+ "fileName": {
+ "description": "Public file path without a leading slash.",
+ "type": "string"
},
- {
- "type": "object",
- "properties": {
- "client_id": {
- "description": "OAuth client id.",
- "type": "string",
- "enum": [
- "administration"
- ]
- },
- "scope": {
- "$ref": "#/components/schemas/OAuthScopes"
- },
- "username": {
- "description": "Username of the user that should be authenticated.",
- "type": "string"
- },
- "password": {
- "description": "Password of the user that should be authenticated.",
- "type": "string"
- }
- },
- "required": [
- "client_id",
- "scope",
- "username",
- "password"
- ]
+ "contentType": {
+ "description": "Detected content type of the rendered file.",
+ "type": "string"
+ },
+ "content": {
+ "description": "Rendered file content.",
+ "type": "string"
}
- ]
+ }
},
- "OAuthRefreshTokenGrant": {
- "allOf": [
- {
- "$ref": "#/components/schemas/OAuthGrant"
+ "SalesChannelFileTemplate": {
+ "type": "object",
+ "required": [
+ "twigNamespace",
+ "templateName",
+ "templateContent",
+ "role"
+ ],
+ "properties": {
+ "twigNamespace": {
+ "description": "Twig namespace that contributed the template, for example `Framework` or a plugin name.",
+ "type": "string"
},
- {
- "type": "object",
- "properties": {
- "client_id": {
- "description": "OAuth client id.",
- "type": "string",
- "enum": [
- "administration"
- ]
- },
- "scope": {
- "$ref": "#/components/schemas/OAuthScopes"
- },
- "refresh_token": {
- "description": "The refresh token that should be used to refresh the access token.",
- "type": "string"
- }
- },
- "required": [
- "client_id",
- "scope",
- "refresh_token"
+ "templateName": {
+ "description": "Resolved Twig template name.",
+ "type": "string",
+ "examples": [
+ "@Framework/files/agentic/llms.txt.twig"
+ ]
+ },
+ "templateContent": {
+ "description": "Original source template content. Administration clients can use this as the default text when editing a template override.",
+ "type": "string"
+ },
+ "role": {
+ "description": "Whether this source provides the base template or extends another source in the resolved template chain.",
+ "type": "string",
+ "enum": [
+ "base",
+ "extension"
]
}
- ]
+ }
},
"Cart": {
"properties": {
diff --git a/adminapi.summary.json b/adminapi.summary.json
index ccb80ef..2d43b0b 100644
--- a/adminapi.summary.json
+++ b/adminapi.summary.json
@@ -73,6 +73,7 @@
"/_action/theme/{themeId}/structured-fields",
"/_action/translation/install",
"/_action/translation/list",
+ "/_action/translation/meta",
"/_action/translation/update",
"/_action/translation/{locale}",
"/_action/user/logout",