Quickstart

Sign up, get a test key, read the catalog and make a first booking.

Base URL: https://api.shyni.io (production); staging is https://api.shyni.dev. Every path starts with /api/v1. A test key acts on a sandbox business, so nothing touches real customers.

1. Sign up and get a test key

Sign up at dashboard.shyni.io/signup with your e-mail, Google or GitHub. You give the name of your organization and an industry. The portal preselects Automotive; pick General. The examples below use the General sandbox, a dog grooming salon. If you keep Automotive, two things differ, and the note under step 5 lists them.

A sandbox business already exists when you arrive. It is named after your organization, with "Sandbox" at the end, and holds sample services, a worker and a few orders. The Overview shows a test key once; Shyni keeps only a hash, so a lost key has to be revoked and replaced in API keys. The first key carries the scopes catalog:read, orders:read and orders:write. See Keys and auth and Sandbox.

export SHYNI_KEY="shyni_sk_test_..."

2. Pick the business

An organization key acts on one business per request, named in the Shyni-Business header. Open the sandbox in the portal under Businesses and copy its ID, or list the businesses with a key that carries businesses:read (create one in API keys):

curl https://api.shyni.io/api/v1/businesses \
  -H "Authorization: Bearer $SHYNI_KEY"

The answer is {"data": [{"id": "...", "name": "...", "sandbox": true, ...}], "meta": {...}}. Take the id of your sandbox. See List businesses.

export SHYNI_BUSINESS="<the id of the sandbox>"

A request to a business endpoint without the header is 400 BUSINESS_REQUIRED. An id that does not exist, belongs to another organization or has the wrong mode is 404 BUSINESS_NOT_FOUND.

3. Read the catalog

curl https://api.shyni.io/api/v1/services \
  -H "Authorization: Bearer $SHYNI_KEY" \
  -H "Shyni-Business: $SHYNI_BUSINESS"

The answer is {"data": {"categories": [...], "services": [...], "packages": [...]}}. Take a service id from services, and a code from that service's variants (here a dog size: SMALL, MEDIUM or LARGE). The General sandbox sells Bath and brush, Full groom, De-shedding treatment and the add-on Nail trim; Bath and brush takes 60 minutes. The ids and times below are samples, use your own. See List services.

A 401 INVALID_API_KEY means the key is missing, mistyped or revoked.

Request bodies are strict: a field the endpoint does not define is 400 UNKNOWN_FIELD. See Errors.

4. Pick a start time

Ask for the bookable starts of one day. serviceIds is comma-separated.

curl "https://api.shyni.io/api/v1/availability/starts?date=2026-11-03&serviceIds=3b7e9c52-81d4-4f6a-a0c3-2d9e5b8f1a47&variant=MEDIUM" \
  -H "Authorization: Bearer $SHYNI_KEY" \
  -H "Shyni-Business: $SHYNI_BUSINESS"
{ "data": [{ "start": "2026-11-03T08:00:00Z", "end": "2026-11-03T09:00:00Z" }] }

This call needs catalog:read. See List start times.

5. Create an order

Send start and end of one entry as scheduledStart and scheduledEnd. A pair that does not match the services' real duration is refused with 400 INVALID_INPUT. variant is required: a code from the service's variants. Every write needs an Idempotency-Key header; see Idempotency.

curl -X POST https://api.shyni.io/api/v1/orders \
  -H "Authorization: Bearer $SHYNI_KEY" \
  -H "Shyni-Business: $SHYNI_BUSINESS" \
  -H "Idempotency-Key: quickstart-booking-1" \
  -H "Content-Type: application/json" \
  -d '{
    "serviceIds": ["3b7e9c52-81d4-4f6a-a0c3-2d9e5b8f1a47"],
    "scheduledStart": "2026-11-03T08:00:00Z",
    "scheduledEnd": "2026-11-03T09:00:00Z",
    "customer": { "name": "Jane Doe", "email": "jane.doe@example.com", "phone": "+1 202 555 0104" },
    "variant": "MEDIUM",
    "subject": { "attributes": { "name": "Biscuit" } }
  }'

201 Created returns the order. The sample services carry no deposit rule, so the order is created with depositRequired false:

{
  "id": "68aa1b98-3c1e-4f0a-9d2b-5e7f1a2b3c4d",
  "publicId": "84609120",
  "state": "CREATED",
  "depositState": "NOT_REQUIRED",
  "currency": "CZK",
  "totalPrice": 120000,
  "depositRequired": false,
  "depositAmount": 0,
  "scheduledStart": "2026-11-03T08:00:00Z",
  "scheduledEnd": "2026-11-03T09:00:00Z",
  "pickupAt": "2026-11-03T09:00:00Z",
  "serviceLines": [{ "name": "Bath and brush", "price": 120000, "durationMinutes": 60 }],
  "externalRef": null,
  "orderUrl": "https://app.shyni.cz/order/84609120?token=...",
  "sourceChannel": "API",
  "sourceLabel": null,
  "attribution": { "utmSource": null, "utmMedium": null, "utmCampaign": null, "utmTerm": null, "utmContent": null, "referrer": null, "gclid": null, "gbraid": null, "wbraid": null, "fbclid": null },
  "metadata": {},
  "billing": null
}

Mails of a sandbox go to the organization's technical e-mail with [TEST] in the subject, never to the customer.

A service with a deposit rule creates the order awaiting the deposit: depositRequired is true and the order carries a paymentUrl and holdUntil. holdUntil is the moment the unpaid deposit releases the slot (30 minutes after creation with card payment through paymentUrl, 3 hours with bank transfer); see Booking on your site. Money is in minor units of currency. orderUrl is the customer's page for the order and carries its access token, so give it to the customer only. See Create an order for every field.

1200.00 CZK is the 1000.00 base price of Bath and brush times 1.2 for a MEDIUM dog. The dog grooming salon requires the dog's name in subject.attributes; a missing one is 400 INVALID_SUBJECT. See Subject types and variants.

If you signed up with Automotive, the sandbox is an auto detailing: use its services (for example Hand wash), its vehicle-size variant codes from step 3, and send no dog subject (a car's plate, make and model are optional).

If the window was taken in the meantime you get 409 SLOT_UNAVAILABLE and nothing is created: ask for the starts again.

Next

On this page