API-Referenz-Navigation
Themes
AdminThemes groups 9 operations on the admin tier.
Admin tier. Requires an RBAC-gated vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.
/api/{version}/admin/themes
Every theme of the tenant, unpaged. Exactly one carries role: "main".
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Antworten
- 200ThemeListResponseOK
curl -X GET \
'https://<your-shop-domain>/api/2026-04-01/admin/themes' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'{
"themes": [
{
"id": "00000000-0000-0000-0000-000000000000",
"name": "string",
"role": "string",
"theme_key": "string",
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-01T12:00:00Z"
}
]
}/api/{version}/admin/themes/{id}
One theme record (no assets).
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Pfad-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| id erforderlich | string (uuid) |
Antworten
- 200ThemeResponseOK
- 404ApiErrorResponseNot Found
curl -X GET \
'https://<your-shop-domain>/api/2026-04-01/admin/themes/<id>' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'{
"theme": {
"id": "00000000-0000-0000-0000-000000000000",
"name": "string",
"role": "string",
"theme_key": "string",
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-01T12:00:00Z"
}
}/api/{version}/admin/themes/{id}
Renames the theme and/or publishes it. role: "main" publishes (deactivating whichever theme held the role); role: "unpublished" is accepted but is a no-op, since the API never leaves a tenant without an active theme. A missing body or an unrecognized role is a 422.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Pfad-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| id erforderlich | string (uuid) |
Request-Body
application/json, text/json, application/*+json · optional
UpdateThemeRequestBody for PUT /api/{version}/admin/themes/{id}. Both fields are optional; only the supplied ones
are applied. Setting role to main publishes the theme (activating it and deactivating any
other). unpublished is accepted but is a no-op — the API never leaves a tenant with no active
theme (that would 503 the storefront).
namestringnullablerolestringnullable
Antworten
- 200ThemeResponseOK
- 404ApiErrorResponseNot Found
- 422ApiErrorResponseUnprocessable Content
curl -X PUT \
'https://<your-shop-domain>/api/2026-04-01/admin/themes/<id>' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"role": "string"
}'{
"theme": {
"id": "00000000-0000-0000-0000-000000000000",
"name": "string",
"role": "string",
"theme_key": "string",
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-01T12:00:00Z"
}
}/api/{version}/admin/themes/{id}/assets
The theme's text assets (Liquid, localization JSON, config). One route, two bodies: with ?key= the response carries asset (the file with its value), without it the response carries assets (every key plus metadata, no content). A key that escapes the theme root is a 422, not a 404.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Pfad-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| id erforderlich | string (uuid) |
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| key optional | string |
Antworten
- 200ThemeAssetsResponseOK
- 404ApiErrorResponseNot Found
- 422ApiErrorResponseUnprocessable Content
curl -X GET \
'https://<your-shop-domain>/api/2026-04-01/admin/themes/<id>/assets' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'{
"asset": {
"key": "string",
"value": "string",
"size": 1,
"content_type": "string"
},
"assets": [
{
"key": "string",
"size": 1,
"content_type": "string",
"updated_at": "2026-04-01T12:00:00Z"
}
]
}/api/{version}/admin/themes/{id}/assets
Upserts one text asset from the JSON key/value body: creates it when absent, replaces it when present. A missing key or one that escapes the theme root is a 422.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Pfad-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| id erforderlich | string (uuid) |
Request-Body
application/json, text/json, application/*+json · optional
PutThemeAssetRequestBody for PUT /api/{version}/admin/themes/{id}/assets. key is the asset path relative to the
theme root (e.g. templates/product.liquid); value is its text content. Upserts: creates the
asset when absent, replaces it when present.
keystringnullablevaluestringnullable
Antworten
- 200ThemeAssetResponseOK
- 404ApiErrorResponseNot Found
- 422ApiErrorResponseUnprocessable Content
curl -X PUT \
'https://<your-shop-domain>/api/2026-04-01/admin/themes/<id>/assets' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>' \
-H 'Content-Type: application/json' \
-d '{
"key": "string",
"value": "string"
}'{
"asset": {
"key": "string",
"value": "string",
"size": 1,
"content_type": "string"
}
}/api/{version}/admin/themes/{id}/assets
Deletes one text asset. Returns 204 with no body; a missing or escaping key is a 422 and an unknown asset a 404.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Pfad-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| id erforderlich | string (uuid) |
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| key optional | string |
Antworten
- 204No Content
- 404ApiErrorResponseNot Found
- 422ApiErrorResponseUnprocessable Content
curl -X DELETE \
'https://<your-shop-domain>/api/2026-04-01/admin/themes/<id>/assets' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'/api/{version}/admin/themes/{id}/assets/data
The theme's binary media. One route, two media types: the keyless form returns the JSON assets list documented below, while ?key= streams that asset's raw bytes with the asset's own Content-Type and no JSON envelope at all. Branch on the response's content type. A key that escapes the theme root is a 422.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Pfad-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| id erforderlich | string (uuid) |
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| key optional | string |
Antworten
- 200ThemeDataAssetListResponseOK
- 404ApiErrorResponseNot Found
- 422ApiErrorResponseUnprocessable Content
curl -X GET \
'https://<your-shop-domain>/api/2026-04-01/admin/themes/<id>/assets/data' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'{
"assets": [
{
"key": "string",
"size": 1,
"content_type": "string",
"updated_at": "2026-04-01T12:00:00Z",
"url": "string"
}
]
}/api/{version}/admin/themes/{id}/assets/data
Upserts one binary asset from the raw request body (no JSON envelope); the request's Content-Type is stored as the asset's. A body over 20 MB is a 413; a missing or escaping key is a 422. The upload is served by the storefront as soon as this returns.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Pfad-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| id erforderlich | string (uuid) |
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| key optional | string |
Antworten
- 200ThemeDataAssetResponseOK
- 404ApiErrorResponseNot Found
- 413ApiErrorResponseContent Too Large
- 422ApiErrorResponseUnprocessable Content
curl -X PUT \
'https://<your-shop-domain>/api/2026-04-01/admin/themes/<id>/assets/data' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'{
"asset": {
"key": "string",
"size": 1,
"content_type": "string",
"updated_at": "2026-04-01T12:00:00Z",
"url": "string"
}
}/api/{version}/admin/themes/{id}/assets/data
Deletes one binary asset. Returns 204 with no body; a missing or escaping key is a 422 and an unknown asset a 404.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Pfad-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| id erforderlich | string (uuid) |
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
| key optional | string |
Antworten
- 204No Content
- 404ApiErrorResponseNot Found
- 422ApiErrorResponseUnprocessable Content
curl -X DELETE \
'https://<your-shop-domain>/api/2026-04-01/admin/themes/<id>/assets/data' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'Schemas
ApiErrorResponse
The error envelope every non-2xx response from this API uses. Documentation shape: actions build it as an anonymous object, so this type exists to give the OpenAPI document a schema to point at.
errorsstringnullableHuman-readable description of what went wrong, e.g.
Not Found,Invalid page_info.codestringnullableMachine-readable error code. Only a few endpoints (checkout) emit one; omitted everywhere else.
PutThemeAssetRequest
Body for PUT /api/{version}/admin/themes/{id}/assets. key is the asset path relative to the
theme root (e.g. templates/product.liquid); value is its text content. Upserts: creates the
asset when absent, replaces it when present.
keystringnullablevaluestringnullable
ThemeAssetContentDto
An asset with its full text content (single read + upsert response).
keystringnullablevaluestringnullablesizeinteger (int64)content_typestringnullable
ThemeAssetDto
An asset list row: the key plus lightweight metadata, no content.
keystringnullablesizeinteger (int64)nullablecontent_typestringnullableupdated_atstring (date-time)nullable
ThemeAssetResponse
Envelope returned by PUT /admin/themes/{id}/assets. Always a single asset — the upsert addresses
one key.
assetThemeAssetContentDto
ThemeAssetsResponse
Envelope returned by GET /admin/themes/{id}/assets, whose body depends on the request:
?key= returns the single asset under asset, and the keyless form returns the whole key list
under assets. Exactly one of the two members is present on any given response — the other is
omitted entirely, never sent as null.
assetThemeAssetContentDtoEvery text asset in the theme — key plus metadata, no content. Present only for the keyless form; read a single key to get its
value.
ThemeDataAssetDto
A binary theme-media asset (the themes/{id}/assets/data surface): key + metadata + the served URL.
The bytes themselves stream over the wire, not through this JSON. url is the same address the
storefront's asset_url resolves to, so it is directly usable.
keystringnullablesizeinteger (int64)nullablecontent_typestringnullableupdated_atstring (date-time)nullableurlstringnullable
ThemeDataAssetListResponse
Envelope returned by the keyless GET /admin/themes/{id}/assets/data. The ?key= form of that
same route does not return this — it streams the asset's raw bytes with the asset's own content
type, so a client must branch on the response's Content-Type, not assume JSON.
Every binary asset in the theme — key, metadata and the served
url, never the bytes. Always present; an empty array when the theme carries no media.
ThemeDataAssetResponse
Envelope returned by PUT /admin/themes/{id}/assets/data.
assetThemeDataAssetDto
ThemeDto
Admin representation of a theme (the themes resource, backed by the existing ShopTheme
domain). Serialized snake_case via explicit [JsonPropertyName] attributes, because the host's
global JSON policy is camelCase. role follows Shopify: main for the single active theme,
else unpublished.
idstring (uuid)namestringnullablerolestringnullablePublication role:
main(the active theme) orunpublished.theme_keystringnullableThe library theme this was created from (e.g.
vineyard);nullfor custom themes.created_atstring (date-time)updated_atstring (date-time)nullable
ThemeListResponse
Envelope returned by GET /admin/themes. Unpaged: a tenant has a handful of themes, so every one is
returned in a single response — there is no Link header and no page_info here.
Every theme of the tenant. Always present, and never empty in practice: a tenant always keeps at least the active one, so exactly one row carries
role: "main".
UpdateThemeRequest
Body for PUT /api/{version}/admin/themes/{id}. Both fields are optional; only the supplied ones
are applied. Setting role to main publishes the theme (activating it and deactivating any
other). unpublished is accepted but is a no-op — the API never leaves a tenant with no active
theme (that would 503 the storefront).
namestringnullablerolestringnullable
