BizKitHub
DocsAPI ReferenceVoucher/api/v1/voucher/analyze
getVoucherPublic API v1

/api/v1/voucher/analyze

Public mirror of /bff/voucher/analyze. Returns a lightweight snapshot of a voucher: whether it exists in the organisation and, if it does, its computed status (active / inactive / expired / not-yet-valid / limit-reached). Does NOT throw when the voucher is missing — the exists=false branch carries rejectionReason="code_not_found". When redeemContext is supplied, the response additionally carries the rejection reason this voucher would hit for that context. When identityId is supplied and resolves to a known contact, the engine also evaluates the "single use per customer" check. Read-only — never increments usedCount or writes an audit log.

VouchergetApiV1VoucherAnalyze

Parameters

5 query

Query parameters

· 5
apiKeystringRequired

Your BizKitHub API key (passed as GET parameter).

Key format: A 32-character string matching: ^(PROD|DEV_|ROOT)[A-Za-z0-9]{28}$
Prefixes: PROD (production key), DEV_ (individual developer), ROOT (system key with no limits). Learn more

ExamplePRODPGrFxpGEtrOZfuWhnoJohUYBXuOE
codestringRequired

Voucher code to analyze. Server trims + uppercases.

ExampleSUMMER2024
redeemContextstringOptional

Optional redemption context. "order" = voucher is being added to a reservation/order; "voucher_page" = voucher is being redeemed on the dedicated voucher-redeem page. When present, the response includes rejectionReason/rejectionMessage reflecting what the order engine would answer today.

Exampleorder
identityIdstringOptional

Logged user identity (from your frontend cookies). Learn more

ExampleZ9CPkS2o3UV163VQn5OUv0T8BQi8Fvdg
customerRealIpstringOptional

User IP address used for GEO/IP intelligence.

Accepted formats:

  • IPv4 dot-decimal, e.g. 1.1.1.1 (4 octets, 0–255, no leading zeros).
  • IPv6 as defined by RFC 4291 — full 2001:0db8:0000:0000:0000:0000:0000:0001, zero-compressed 2001:db8::1, IPv4-mapped ::ffff:1.2.3.4, or scoped literals. Both upper- and lower-case hex are accepted.

Server-side canonicalization (ipNormalize in core/src/lib/network/ipNormalize.ts):

  • Valid IPv4 is passed through verbatim.
  • Valid IPv6 is lowercased (RFC 5952 §4.3).
  • IPv4-mapped IPv6 ::ffff:X.X.X.X is unwrapped to plain IPv4 (RFC 4291 §2.5.5.2) so 1.2.3.4 and ::ffff:1.2.3.4 share one brj__geo_ip row.
  • Loopback aliases (::1, 0.0.0.0, localhost, empty string) collapse to 127.0.0.1.
  • Junk values that fail both IPv4 and IPv6 validation are silently rejected and replaced with 127.0.0.1 (loopback).

On the wire: every response returns the canonicalized form — clients can safely rely on lowercase IPv6 and the plain-IPv4 unwrap when de-duping or joining. Server-originated writers (activity log, session log, ban list) resolve the visitor IP via resolveClientIp / resolveClientIpOrNull — always native IPv6 on Vercel Edge (there is no auto-mapping to ::ffff:X.X.X.X).

Enrichment: the system resolves reverse DNS, geolocation, ASN, mobile/proxy/hosting/Tor flags via our VikiTron GEO/IP resolver for both address families. Learn more

Example1.1.1.1

Response schema

1 status code documented

200SuccessVoucher analysis result.
object | object

Voucher analysis result.

One of 2:
Variant 1

Voucher not found.

exists"false"Required

Voucher with this code does not exist.

rejectionReason"code_not_found"Required

Always "code_not_found" for the exists=false branch.

rejectionMessagestringRequired

Human-readable reason, pre-formatted for the frontend.

Variant 2

Voucher exists — snapshot with computed status.

exists"true"Required
codestringRequired

Voucher code (canonical, uppercase).

type"fixed" | "percentage" | "free-credit" | "free-product"Required

Discount type.

valuestringRequired

Discount value.

activebooleanRequired

Database active flag (does NOT consider expiration/limit).

effectivelyActivebooleanRequired

True if voucher is currently usable (active + within validity + below limit).

isValidbooleanRequired

Alias of effectivelyActive — convenient flag for UI consumers.

status"active" | "inactive" | "expired" | "not-yet-valid" | "limit-reached"Required

Computed status enum.

usedCountnumberRequired

Number of times voucher has been used.

usageLimitnumber | nullRequired

Maximum number of uses, or null if unlimited.

One of 2:
Variant 1
number
Variant 2
null
remainingUsagenumber | nullRequired

Remaining uses, or null if unlimited.

One of 2:
Variant 1
number
Variant 2
null
validFromDate | string | string | number | nullRequired

Validity start date.

One of 2:
Variant 1
Date | string | string | number
One of 4:
Variant 1
Date
Variant 2
stringdate-time
Variant 3
stringdate
Variant 4
number
Variant 2
null
validToDate | string | string | number | nullRequired

Validity end date.

One of 2:
Variant 1
Date | string | string | number
One of 4:
Variant 1
Date
Variant 2
stringdate-time
Variant 3
stringdate
Variant 4
number
Variant 2
null
daysUntilExpirationnumber | nullRequired

Days remaining until expiration, or null if no expiration or already expired.

One of 2:
Variant 1
number
Variant 2
null
lastUsedDateDate | string | string | number | nullRequired

Last usage date.

One of 2:
Variant 1
Date | string | string | number
One of 4:
Variant 1
Date
Variant 2
stringdate-time
Variant 3
stringdate
Variant 4
number
Variant 2
null
notestringRequired

Internal note (full content).

isOrderSingletonbooleanRequired

If true, voucher cannot be combined with other vouchers inside a single order.

singleUsePerCustomerbooleanRequired

If true, every customer may redeem this voucher on at most one order.

redeemableAtOrderbooleanRequired

If true, voucher may be redeemed on the reservation / order form.

redeemableAtVoucherPagebooleanRequired

If true, voucher may be redeemed on the dedicated "redeem voucher" page (typically used for free-credit vouchers).

rejectionReason"code_not_found" | "inactive" | "not_yet_valid" | "expired" | "usage_limit_reached" | "already_used_by_customer" | "wrong_redemption_context" | nullRequired

Rejection reason the order engine would answer for this voucher in the supplied redeemContext. Null when the voucher would be accepted or when redeemContext was not supplied.

One of 8:
Variant 1
"code_not_found"
Variant 2
"inactive"
Variant 3
"not_yet_valid"
Variant 4
"expired"
Variant 5
"usage_limit_reached"
Variant 6
"already_used_by_customer"
Variant 7
"wrong_redemption_context"
Variant 8
null
rejectionMessagestring | nullRequired

Human-readable rejection message. Null when accepted or no context passed.

One of 2:
Variant 1
string
Variant 2
null
acceptedForContext"order" | "voucher_page" | nullRequired

When the engine accepted the voucher this echoes the requested redeemContext; otherwise null.

One of 3:
Variant 1
"order"
Variant 2
"voucher_page"
Variant 3
null

Response example

application/json
{
  "exists": false,
  "rejectionReason": "code_not_found",
  "rejectionMessage": "example_rejectionMessage"
}

Request example

GET /api/v1/voucher/analyze

get
curl -X GET "https://api.bizkithub.com/api/v1/voucher/analyze?apiKey=PRODPGrFxpGEtrOZfuWhnoJohUYBXuOE&code=SUMMER2024&redeemContext=order&identityId=Z9CPkS2o3UV163VQn5OUv0T8BQi8Fvdg&customerRealIp=1.1.1.1" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY"

Need an API key?

All BizKitHub public API endpoints require authentication via API key.

Get API Key