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.pdf200 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.