Edit a pending booking link in place
Changes a PENDING link without issuing a new one: the id, token and url stay the same, so a link the
customer already has keeps working. A field left out stays as it is; null clears a nullable one
(scheduledStart: null turns the link into an open term and releases the hold). A changed term is held
again; if the new slot is taken the answer is 409 and the link keeps its old hold. Every real change
raises revision; a customer who opened the page before the edit is asked to look at the new offer before
completing it. With notifyCustomer (default true) the customer is mailed the edited offer when something
they see changed and the link has an e-mail address (429 when the link was mailed too often in the last
hour). A completed, cancelled or expired link is 409 CONFLICT. agreedPrice, depositOverride and
customLines need the PRO plan. Requires the orders:manage scope and an Idempotency-Key header.
ApiKeyAuth orders:manageAuthorizationBearer <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: orders:manage
id*stringIdempotency-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 is optional. A field left out stays as it is; null clears a nullable one. Lists replace the whole list.
serviceIds?array<string>Service and/or package ids from GET /api/v1/services; replaces the list.
scheduledStart?|The held start. null = open term: nothing is held and the customer picks the start.
date-timecustomer?subject?The owner's guess of what the customer brings, a prefill for the customer's page. Checked as subject of POST /orders (400 INVALID_SUBJECT).
variant?|Code of the variant (detailing - the vehicle size), a prefill.
adminNote?|For the studio only, at most 500 characters.
customerMessage?|Shown to the customer on the link's page, at most 500 characters.
validity?|Left out, the expiry stays (an edit never extends it; it is only capped at a new, earlier start). Sent, the link stays open that long from now.
"HOURS_24""HOURS_48""DAYS_7"nullagreedPrice?|PRO. The price agreed for the whole job, minor units of the studio currency; null returns to the price list.
int64depositOverride?|PRO. The deposit for this job, minor units; 0 = none; null returns to the studio default.
int64optionAnswers?array<>customLines?array<>PRO. Lines the owner types in outside the price list; replaces the list.
waiveDayAdjustment?booleanThe order made from this link does not pay the day-policy surcharge.
skipDeposit?booleanThe order made from this link requires no deposit.
notifyCustomer?booleanMail the customer the edited offer (same link) when something they see changed and the link has an e-mail.
trueThe edited link, with its new revision.
application/json- response
A booking link as the studio sees it. url is the customer's page for the link and carries its token:
hand it only to the customer. Money is minor units of currency.
id?stringstatus?string"PENDING""COMPLETED""EXPIRED""CANCELLED"url?stringcurrency?stringserviceIds?array<string>serviceNames?array<string>Names against the published catalog, in the order of serviceIds.
optionAnswers?array<>scheduledStart?|Null = open term.
date-timescheduledEnd?|date-timepickupAt?|date-timecustomer?adminNote?string|nullcustomerMessage?string|nullvariant?string|nullsubject?|The owner's prefill of what the customer brings; null when none was given.
agreedPrice?|int64depositOverride?|int64customLines?array<>waiveDayAdjustment?booleanThe order made from this link does not pay the day-policy surcharge.
falseskipDeposit?booleanThe order made from this link requires no deposit.
falseinspectionOrderId?string|nullexpiresAt?stringdate-timecreatedAt?stringdate-timefirstOpenedAt?|date-timeopenCount?integerdelivery?|nullcompletedOrderId?|The order the customer made out of the link.
completedAt?|date-timecancelledAt?|date-timerevision?integerRaised by every real edit (PATCH /booking-links/{id}); the customer's completion is refused when the page they saw is older.
curl -X PATCH 'https://api.shyni.io/api/v1/booking-links/string' \ -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 edited link, with its new revision.
{ "id": "string", "status": "PENDING", "url": "string", "currency": "string", "serviceIds": [ "string" ], "serviceNames": [ "string" ], "optionAnswers": [ { "questionId": "string", "optionId": "string" } ], "scheduledStart": "2019-08-24T14:15:22Z", "scheduledEnd": "2019-08-24T14:15:22Z", "pickupAt": "2019-08-24T14:15:22Z", "customer": { "name": "string", "email": "string", "phone": "string" }, "adminNote": "string", "customerMessage": "string", "variant": "string", "subject": { "type": "string", "attributes": { "property1": "string", "property2": "string" } }, "agreedPrice": 0, "depositOverride": 0, "customLines": [ { "name": "string", "price": 0, "durationMinutes": 0 } ], "waiveDayAdjustment": false, "skipDeposit": false, "inspectionOrderId": "string", "expiresAt": "2019-08-24T14:15:22Z", "createdAt": "2019-08-24T14:15:22Z", "firstOpenedAt": "2019-08-24T14:15:22Z", "openCount": 0, "delivery": { "channel": "EMAIL", "at": "2019-08-24T14:15:22Z", "to": "string" }, "completedOrderId": "string", "completedAt": "2019-08-24T14:15:22Z", "cancelledAt": "2019-08-24T14:15:22Z", "revision": 0}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 404
The resource does not exist, or belongs to a different studio.
{ "code": "NOT_FOUND", "message": "Order not found."}Response 409
The request is well-formed but the studio's current state forbids it.
{ "code": "CONFLICT", "message": "The voucher cannot be deactivated because it is not active."}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."}