Gift vouchers

Issue an already-paid voucher, retry safely, read, refund, resend and download it.

Your own shop sold a voucher and took the money. This API records it as an active Shyni voucher the buyer can spend on the business's booking page.

You need a secret key with vouchers:write (and vouchers:read for reads), and a studio must be on the Pro subscription. Below it, all six voucher endpoints answer 403 PLAN_REQUIRED. Never commit a real key.

BASE_URL="https://api.shyni.io"
API_KEY="shyni_sk_REPLACE_ME"

1. Issue

POST /api/v1/gift-vouchers needs an Idempotency-Key (any token, 64 characters at most). paidAt says when the money moved on your side; Shyni never re-checks it. externalRef is your own id for the voucher, unique per studio: the same one under a different Idempotency-Key gives 409 CONFLICT.

value is in minor units of the studio's currency (hellers for CZK), from 10000 to 10000000, so 150000 is 1,500 CZK.

curl -sS -X POST "$BASE_URL/api/v1/gift-vouchers" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-9f2c-voucher" \
  -d '{
    "value": 150000,
    "buyer": { "name": "Jana Novakova", "email": "jana@example.cz" },
    "motif": "CLASSIC",
    "dedication": "Enjoy!",
    "paidAt": "2026-09-08T10:00:00Z",
    "externalRef": "order_9f2c",
    "notifyBuyer": true
  }'
{
  "id": "c4e81f37-92ab-4d65-8f10-a3b7d9e2c640",
  "code": "MU-8H3KQ",
  "value": 150000,
  "remaining": 150000,
  "currency": "CZK",
  "state": "ACTIVE",
  "issuedVia": "API",
  "paidAt": "2026-09-08T10:00:00Z",
  "validUntil": "2027-09-08",
  "buyer": { "name": "Jana Novakova", "email": "jana@example.cz" },
  "motif": "CLASSIC",
  "dedication": "Enjoy!",
  "externalRef": "order_9f2c",
  "redeemedOrderId": null,
  "redemptions": [],
  "notification": "SENT",
  "createdAt": "2026-09-08T10:00:05Z"
}

code is the bearer code printed on the voucher. Give it to the buyer, do not log it, and use it (never id) in every later call.

notifyBuyer: true mails the buyer in this same request, and notification reports SENT, FAILED or RATE_LIMITED. With false nothing goes out; call resend (step 5) when you are ready. validUntil defaults to paidAt plus 12 months unless you set it.

Limits on issuing: each key may issue at most a daily total (default 20,000 CZK per studio calendar day, in the studio's own time zone: Europe/Prague for Czech studios). Above it you get 422 API_KEY_DAILY_VOUCHER_CAP_EXCEEDED. A voucher worth at least the key's alert threshold (default 5,000 CZK) also mails the studio owner at once.

2. Retry safely

Send the same request again, same key and same body, after a dropped connection. Shyni replays the stored 201 instead of issuing a second voucher, and a retried notifyBuyer: true never mails the buyer twice.

Change anything in the body under the same key and you get 422 IDEMPOTENCY_KEY_MISMATCH. Use a new key for a different request. See Idempotency.

3. Read it back

Needs vouchers:read, no body and no Idempotency-Key.

curl -sS "$BASE_URL/api/v1/gift-vouchers/MU-8H3KQ" \
  -H "Authorization: Bearer $API_KEY"

notification is null on every read, because Shyni does not store a delivery state. After orders draw from the voucher, remaining drops and redemptions lists every draw that still counts, oldest first:

"redemptions": [
  { "orderId": "68aa1b98-3c1e-4f0a-9d2b-5e7f1a2b3c4d", "amount": 50000, "redeemedAt": "2026-09-20T14:00:00Z" },
  { "orderId": "9d3b2c10-5e4f-4a6b-8c7d-1e2f3a4b5c6d", "amount": 40000, "redeemedAt": "2026-10-02T09:30:00Z" }
]

See Get a gift voucher and List gift vouchers.

4. Refund

Use a fresh Idempotency-Key. Reusing step 1's key is a different request and answers 422 IDEMPOTENCY_KEY_MISMATCH.

curl -sS -X POST "$BASE_URL/api/v1/gift-vouchers/MU-8H3KQ/refund" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: order-9f2c-voucher-refund"

state comes back REFUNDED. Only a voucher with issuedVia: "API" can be refunded here. A voucher bought on the storefront (ONLINE) is refunded from the admin, and a MANUAL one never passed through Shyni. Those, and a voucher already redeemed or refunded, answer 409 CONFLICT; the message says which. See Refund a gift voucher.

5. Resend the delivery mail

Same scope, and an Idempotency-Key header.

curl -sS -X POST "$BASE_URL/api/v1/gift-vouchers/MU-8H3KQ/resend" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: order-9f2c-voucher-resend-1"

notification in the 200 is SENT or FAILED. If the mail budget is hit, the answer is 429 RATE_LIMITED and nothing was sent: back off and retry. See Resend a gift voucher.

6. Download the PDF

curl -sS "$BASE_URL/api/v1/gift-vouchers/MU-8H3KQ/pdf" \
  -H "Authorization: Bearer $API_KEY" \
  -o voucher-MU-8H3KQ.pdf

200 with application/pdf and a Content-Disposition filename naming the code. 503 PDF_UNAVAILABLE means the render failed right now: retry. The voucher itself is fine. See Download a gift voucher PDF.

Errors

Every non-2xx answer is {"code": "CONFLICT", "message": "..."}. Branch on code; see Errors.

On this page