Storefront

Set the look of the page

PUT
/api/v1/storefront/theme

Replaces the whole look: the accent colour (accentMode SWATCH with an accentSwatch, CUSTOM with an accentHue, or ADVANCED with hue, lightness and chroma), corner radius, neutral tint, font and whether the "Powered by" line is hidden. Custom colours, other neutrals and fonts and a hidden "Powered by" line are part of the plans an API key already has. Draft: the live page changes with POST /storefront/publish. Requires the storefront:write scope and an Idempotency-Key header.

Authorization

ApiKeyAuth storefront:write
headerAuthorizationBearer <shyni_sk_live_*>

An API key, issued once and never retrievable again: an organization key in the developer portal, or a studio key in the studio's admin (Moje studio → API). Send as Authorization: Bearer shyni_sk_live_....

Scope: storefront:write

Header Parameters

Idempotency-Key*string

Caller-chosen idempotency token for this write. A retry under the SAME key with the SAME body replays the first response; the SAME key with a DIFFERENT body is 422 IDEMPOTENCY_KEY_MISMATCH. See Idempotency above.

Lengthlength <= 64

Request Body

application/json
  1. body
accentMode*string
Value in"SWATCH""CUSTOM""ADVANCED"
accentSwatch?string|null
accentHue?|
Range0 <= value <= 359
accentLightness?|
Range0.45 <= value <= 0.85
accentChroma?|
Range0 <= value <= 0.22
radius*string
Value in"SHARP""SOFT""PILL"
neutral*string
Value in"COOL""WARM""NEUTRAL"
font*string
Value in"SANS""SERIF""HUMANIST"
hidePoweredBy*boolean

Response Body

The page draft.

application/json
  1. response

The content of the studio page as the draft holds it - what the /storefront write endpoints change. It is live only after POST /storefront/publish (GET /publish-state says whether something is waiting). The photo ids are read-only here.

description*|null
faq*array<>
whyUs*array<>
brands*array<>
customSections*array<>
layout*array<>
theme*
heroImageId*string|null
aboutImageId*string|null
logoImageId*string|null
galleryImageIds*array<string>
beforeAfter*array<>
Example Request
curl -X PUT 'https://api.shyni.io/api/v1/storefront/theme' \  -H 'Authorization: Bearer shyni_sk_test_YOUR_KEY' \  -H 'Idempotency-Key: 7f3c9a52-1d4e-4b86-a0c7-5e2b9d8f6a13' \  -H 'Content-Type: application/json' \  -d '{  "accentMode": "SWATCH",  "radius": "SHARP",  "neutral": "COOL",  "font": "SANS",  "hidePoweredBy": true}'

Response 200

The page draft.

{  "description": {    "plain": "string",    "html": "string",    "json": {      "v": 0,      "doc": {}    }  },  "faq": [    {      "question": "string",      "answer": {        "plain": "string",        "html": "string",        "json": {          "v": 0,          "doc": {}        }      }    }  ],  "whyUs": [    {      "icon": "string",      "title": "string",      "body": "string"    }  ],  "brands": [    {      "imageId": "string",      "name": "string"    }  ],  "customSections": [    {      "id": "string",      "heading": "string",      "body": {        "plain": "string",        "html": "string",        "json": {          "v": 0,          "doc": {}        }      },      "imageId": "string"    }  ],  "layout": [    {      "id": "string",      "type": "string",      "enabled": true    }  ],  "theme": {    "accentMode": "string",    "accentSwatch": "string",    "accentHue": 0,    "accentLightness": 0,    "accentChroma": 0,    "radius": "string",    "neutral": "string",    "font": "string",    "hidePoweredBy": true  },  "heroImageId": "string",  "aboutImageId": "string",  "logoImageId": "string",  "galleryImageIds": [    "string"  ],  "beforeAfter": [    {      "beforeImageId": "string",      "afterImageId": "string",      "label": "string",      "serviceId": "string"    }  ]}

Response 400

A parameter, header or request body is missing, malformed, or out of range. A request body property the endpoint does not define answers UNKNOWN_FIELD instead, with field naming it.

{  "code": "INVALID_INPUT",  "message": "Parameter perPage must be between 1 and 100."}

Response 401

Missing, malformed, unknown, or revoked API key (INVALID_API_KEY).

{  "code": "INVALID_API_KEY",  "message": "Missing or invalid API key."}

Response 403

The key is valid but the request is refused. Branch on code: INSUFFICIENT_SCOPE (the key lacks the permission this endpoint requires), PLAN_REQUIRED (the studio is not on a plan that includes API keys, Pro and above), ORIGIN_NOT_ALLOWED, SECRET_KEY_IN_BROWSER, or DEMO_STUDIO on a write to the demo studio. See Authentication and Scopes above.

{  "code": "INSUFFICIENT_SCOPE",  "message": "This API key does not have the permission this endpoint requires."}

Response 422

The same Idempotency-Key was already used for a request with a different body, use a new key (see Idempotency above).

{  "code": "IDEMPOTENCY_KEY_MISMATCH",  "message": "This Idempotency-Key was already used for a different request. Use a new key."}

Response 429

Burst rate limit exceeded.

{  "code": "RATE_LIMITED",  "message": "Too many requests. Retry after the time given in the Retry-After header."}