Orders

Set the real end of an order

PUT
/api/v1/orders/{id}/end

The studio states how long the job really takes: the start stays, the end becomes the given instant (it may fall outside opening hours). It never refuses a collision - orders in the same place that the new end ran into come back in collisions. Allowed on CREATED, CONFIRMED and IN_PROGRESS orders; nothing is sent to the customer (use notify-time-change). Requires the orders:manage scope and an Idempotency-Key header.

Authorization

ApiKeyAuth orders:manage
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: orders:manage

Path Parameters

id*string

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
scheduledEnd*string

The real end of the work (ISO-8601 instant), after the order's start.

Formatdate-time

Response Body

The order with its new end, and the collisions the new end caused.

application/json
  1. response
order?
collisions?array<>

Other orders in the same place that the new end ran into; empty when none (a shorter end reports nothing).

Example Request
curl -X PUT 'https://api.shyni.io/api/v1/orders/string/end' \  -H 'Authorization: Bearer shyni_sk_test_YOUR_KEY' \  -H 'Idempotency-Key: 7f3c9a52-1d4e-4b86-a0c7-5e2b9d8f6a13' \  -H 'Content-Type: application/json' \  -d '{  "scheduledEnd": "2019-08-24T14:15:22Z"}'

Response 200

The order with its new end, and the collisions the new end caused.

{  "order": {    "id": "string",    "publicId": "string",    "state": "CREATED",    "kind": "ORDER",    "depositState": "PENDING",    "currency": "string",    "depositAmount": 0,    "depositPaidAt": "2019-08-24T14:15:22Z",    "scheduledStart": "2019-08-24T14:15:22Z",    "scheduledEnd": "2019-08-24T14:15:22Z",    "pickupAt": "2019-08-24T14:15:22Z",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z",    "externalRef": "string",    "readyAt": "2019-08-24T14:15:22Z",    "customer": {      "id": "string",      "name": "string",      "email": "user@example.com",      "phone": "string",      "externalRef": "string"    },    "variant": "string",    "subject": {      "id": "string",      "type": "string",      "attributes": {        "property1": "string",        "property2": "string"      },      "summary": "string",      "externalRef": "string"    },    "serviceLines": [      {        "id": "string",        "name": "string",        "price": 0,        "durationMinutes": 0,        "packageHead": true,        "custom": true,        "serviceId": "string",        "packageId": "string",        "optionAnswers": [          {            "questionId": "string",            "optionId": "string"          }        ]      }    ],    "totalPrice": 0,    "paidTotal": 0,    "balanceDue": 0,    "payments": [      {        "id": "string",        "amount": 0,        "method": "string",        "recordedAt": "2019-08-24T14:15:22Z",        "reference": "string"      }    ],    "appliedDiscountCode": {      "code": "string",      "type": "string",      "discount": 0    },    "note": "string",    "cancellationReason": "string",    "sourceChannel": "STOREFRONT",    "sourceLabel": "string",    "utmSource": "string",    "utmMedium": "string",    "utmCampaign": "string",    "referrerDomain": "string",    "attribution": {      "utmSource": "string",      "utmMedium": "string",      "utmCampaign": "string",      "utmTerm": "string",      "utmContent": "string",      "referrer": "string",      "gclid": "string",      "gbraid": "string",      "wbraid": "string",      "fbclid": "string"    },    "metadata": {      "property1": "string",      "property2": "string"    },    "billing": {      "company": "string",      "ico": "string",      "dic": "string",      "address": "string"    },    "cancelledBy": "STUDIO",    "assignedWorkerId": "string",    "acceptedTermsVersion": 0,    "waivedDayAdjustment": 0,    "pendingReschedule": {      "id": "string",      "requestedStart": "2019-08-24T14:15:22Z",      "requestedEnd": "2019-08-24T14:15:22Z",      "createdAt": "2019-08-24T14:15:22Z"    },    "rejectedReschedule": {      "id": "string",      "requestedStart": "2019-08-24T14:15:22Z",      "requestedEnd": "2019-08-24T14:15:22Z",      "reason": "string",      "rejectedAt": "2019-08-24T14:15:22Z"    },    "inspection": {      "reply": "COME",      "text": "string",      "repliedAt": "2019-08-24T14:15:22Z"    }  },  "collisions": [    {      "orderId": "string",      "publicId": "string",      "scheduledStart": "2019-08-24T14:15:22Z",      "scheduledEnd": "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 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."}