Update the studio settings
Changes the listed fields; an omitted or null field stays as it is. Same rules as the admin settings
screen: the basic info, deposit amounts and footer texts are written to the studio's draft and go live with
the next publish, the cancellation / confirmation windows and the confirmation mode are effective at once.
employeeCount above 0 needs the MAX plan (0 turns the pool off on every plan). Switching a deposit on
needs a payment path (422 DEPOSIT_WITHOUT_PAYMENT_PATH). A wrong type or value is 400 with field.
Not part of the request, and refused as 400 UNKNOWN_FIELD when sent: bank account, currency, allowed domains, reference consent,
team, billing, API keys and the payment gateway - those change in the admin only. The rich-text
description is not editable here either. Audited with the API key as the actor (deposit amounts, rounding
mode). The answer is the whole studio as the draft now holds it. Requires the settings:write scope and an
Idempotency-Key header.
ApiKeyAuth settings:writeAuthorizationBearer <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: settings:write
Idempotency-Key*stringCaller-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.
length <= 64application/json- body
Every field optional; omitted or null = unchanged. A blank string clears an optional text. contactEmail is not writable through the API - it receives invoices and legal notices, so a request carrying it is refused with 403 (FORBIDDEN); the studio owner changes it in the admin.
name?stringlength <= 255phone?stringaddress?stringemailSignOff?stringClosing line of customer e-mails, shown above the studio name, address and phone. One line of plain text (no line breaks, no < or >); a blank string clears it.
length <= 120timezone?stringobor?string"DETAILING""PPF""KERAMIKA""MYCKA""TUNING""CALOUNENI"tagline?stringlength <= 160servicesHeading?stringlength <= 80beforeAfterSubtitle?stringlength <= 120gallerySubtitle?stringlength <= 120packagesSubtitle?stringlength <= 120publicEmail?stringico?stringlegalName?stringlegalAddress?stringsocialLinks?array<>Replaces the list; an empty list removes all links.
items <= 4vatPayer?booleanpriceRoundingMode?string"NONE""PSYCHOLOGICAL"depositAmountMode?string"FIXED""PERCENT"depositAmount?integerint640 <= valuedepositPercent?integer1 <= value <= 100depositMinAmount?integerint640 <= valueknownCarDepositWaived?booleanemployeeCount?integer0 turns the pool off; above 0 needs the MAX plan.
0 <= value <= 99turnoverMinutes?integer0 <= value <= 480inspectionMinutes?integer1 <= value <= 240cancellationCutoffHours?integer0 <= value <= 168confirmWithinHours?integer1 <= value <= 168confirmMode?string"MANUAL""AUTO"The studio settings.
application/json- response
The studio's basic info and operational settings as the draft holds them. Draft-staged: name, phone,
address, texts, footer, VAT, rounding, deposit amounts, employee pool, buffers - live after the next publish
(hasUnpublishedChanges). Effective at once: contact e-mail, timezone, obor, booking pause, deposit
collection mode, reminders, review mail, Google review link, employee rights, confirmation mode and the
cancellation / confirmation windows.
id*stringslug*stringname*stringcontactEmail*stringphone?string|nulladdress?string|nullemailSignOff?|The studio's own closing line of customer e-mails (e.g. "Těším se, Franta"), shown above the studio name, address and phone. Plain text, one line. Null = none. Draft-staged. Not part of the public profile.
length <= 120timezone*stringobor?|"DETAILING""PPF""KERAMIKA""MYCKA""TUNING""CALOUNENI"nullcurrency*stringISO 4217 code of every amount of the studio. Read-only here.
tagline?string|nullservicesHeading?string|nullbeforeAfterSubtitle?string|nullgallerySubtitle?string|nullpackagesSubtitle?string|nullpublicEmail?string|nullico?string|nulllegalName?string|nulllegalAddress?string|nullsocialLinks*array<>vatPayer*booleanpriceRoundingMode*string"NONE""PSYCHOLOGICAL"depositAmountMode*string"FIXED""PERCENT"depositAmount*integerMinor units of currency.
int64depositPercent*integerdepositMinAmount*integerMinor units of currency.
int64knownCarDepositWaived*booleanemployeeCount?|Employee pool; null = the constraint is off.
turnoverMinutes*integerinspectionMinutes*integercancellationCutoffHours*integerconfirmWithinHours*integerconfirmMode*string"MANUAL""AUTO"bookingPaused*booleanbookingPausedAt?|ISO-8601 instant.
bookingPauseNote?string|nulldepositCollectionMode*string"MANUAL""ONLINE""BOTH"returnRemindersEnabled*booleanreviewRequestEmailEnabled*booleangoogleReviewUrl?string|nullemployeesConfirmAndHandOver*booleanhasUnpublishedChanges*booleanterms?The studio's current terms and conditions. The whole terms object is absent when the studio has none
(nothing to show, nothing to send back). Show the customer a link to url, then send version as
acceptedTermsVersion in POST /orders.
curl -X PATCH 'https://api.shyni.io/api/v1/studio' \ -H 'Authorization: Bearer shyni_sk_test_YOUR_KEY' \ -H 'Idempotency-Key: 7f3c9a52-1d4e-4b86-a0c7-5e2b9d8f6a13' \ -H 'Content-Type: application/json' \ -d '{}'Response 200
The studio settings.
{ "id": "string", "slug": "string", "name": "string", "contactEmail": "string", "phone": "string", "address": "string", "emailSignOff": "string", "timezone": "string", "obor": "DETAILING", "currency": "string", "tagline": "string", "servicesHeading": "string", "beforeAfterSubtitle": "string", "gallerySubtitle": "string", "packagesSubtitle": "string", "publicEmail": "string", "ico": "string", "legalName": "string", "legalAddress": "string", "socialLinks": [ { "network": "INSTAGRAM", "url": "string" } ], "vatPayer": true, "priceRoundingMode": "NONE", "depositAmountMode": "FIXED", "depositAmount": 0, "depositPercent": 0, "depositMinAmount": 0, "knownCarDepositWaived": true, "employeeCount": 0, "turnoverMinutes": 0, "inspectionMinutes": 0, "cancellationCutoffHours": 0, "confirmWithinHours": 0, "confirmMode": "MANUAL", "bookingPaused": true, "bookingPausedAt": "string", "bookingPauseNote": "string", "depositCollectionMode": "MANUAL", "returnRemindersEnabled": true, "reviewRequestEmailEnabled": true, "googleReviewUrl": "string", "employeesConfirmAndHandOver": true, "hasUnpublishedChanges": true, "terms": { "url": "http://example.com", "version": 0, "publishedAt": "2019-08-24T14:15:22Z" }}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."}