API reference navigation
Discount Codes
AdminDiscount Codes groups 5 operations on the admin tier.
Admin tier. Requires an RBAC-gated vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.
/api/{version}/admin/discount_codes
One cursored page of discount codes, newest first. Follow the Link: rel="next" header for the next page; a page_info that was not issued for this exact query string is rejected with 422.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Query parameters
| Name | Type | Description |
|---|---|---|
| limit optional | integer (int32) |
Responses
- 200DiscountCodeListResponseOK
- 422ApiErrorResponseUnprocessable Content
curl -X GET \
'https://<your-shop-domain>/api/2026-04-01/admin/discount_codes' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'{
"discount_codes": [
{
"id": "00000000-0000-0000-0000-000000000000",
"code": "string",
"type": "string",
"value": 1,
"is_active": true,
"is_used": true,
"is_infinite": true,
"using_date": "2026-04-01T12:00:00Z",
"currency_id": "00000000-0000-0000-0000-000000000000",
"expiry_date": "2026-04-01T12:00:00Z",
"min_value": 1,
"is_check_all_products_for_category": true,
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-01T12:00:00Z"
}
]
}/api/{version}/admin/discount_codes
Creates a discount code and returns it as stored. A missing body and a rejected field both surface as 422.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Request body
application/json, text/json, application/*+json · optional
CreateDiscountCodeRequestBody for POST /api/{version}/admin/discount_codes. code is required; type defaults to value.
codestringnullabletypestringnullablevaluenumber (double)is_activebooleanis_infinitebooleancurrency_idstring (uuid)nullableexpiry_datestring (date-time)nullablemin_valuenumber (double)is_check_all_products_for_categoryboolean
Responses
- 201DiscountCodeResponseCreated
- 422ApiErrorResponseUnprocessable Content
curl -X POST \
'https://<your-shop-domain>/api/2026-04-01/admin/discount_codes' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>' \
-H 'Content-Type: application/json' \
-d '{
"code": "string",
"type": "string",
"value": 1,
"is_active": true,
"is_infinite": true,
"currency_id": "00000000-0000-0000-0000-000000000000",
"expiry_date": "2026-04-01T12:00:00Z",
"min_value": 1,
"is_check_all_products_for_category": true
}'{
"discount_code": {
"id": "00000000-0000-0000-0000-000000000000",
"code": "string",
"type": "string",
"value": 1,
"is_active": true,
"is_used": true,
"is_infinite": true,
"using_date": "2026-04-01T12:00:00Z",
"currency_id": "00000000-0000-0000-0000-000000000000",
"expiry_date": "2026-04-01T12:00:00Z",
"min_value": 1,
"is_check_all_products_for_category": true,
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-01T12:00:00Z"
}
}/api/{version}/admin/discount_codes/{id}
One discount code.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Path parameters
| Name | Type | Description |
|---|---|---|
| id required | string (uuid) |
Responses
- 200DiscountCodeResponseOK
- 404ApiErrorResponseNot Found
curl -X GET \
'https://<your-shop-domain>/api/2026-04-01/admin/discount_codes/<id>' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'{
"discount_code": {
"id": "00000000-0000-0000-0000-000000000000",
"code": "string",
"type": "string",
"value": 1,
"is_active": true,
"is_used": true,
"is_infinite": true,
"using_date": "2026-04-01T12:00:00Z",
"currency_id": "00000000-0000-0000-0000-000000000000",
"expiry_date": "2026-04-01T12:00:00Z",
"min_value": 1,
"is_check_all_products_for_category": true,
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-01T12:00:00Z"
}
}/api/{version}/admin/discount_codes/{id}
Applies the supplied fields and returns the discount code as stored.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Path parameters
| Name | Type | Description |
|---|---|---|
| id required | string (uuid) |
Request body
application/json, text/json, application/*+json · optional
UpdateDiscountCodeRequestBody for PUT /api/{version}/admin/discount_codes/{id}. Every field is optional; only the
supplied ones are applied. code and type are immutable after creation and are ignored.
valuenumber (double)nullableis_activebooleannullableis_infinitebooleannullablecurrency_idstring (uuid)nullableexpiry_datestring (date-time)nullablemin_valuenumber (double)nullableis_check_all_products_for_categorybooleannullable
Responses
- 200DiscountCodeResponseOK
- 404ApiErrorResponseNot Found
- 422ApiErrorResponseUnprocessable Content
curl -X PUT \
'https://<your-shop-domain>/api/2026-04-01/admin/discount_codes/<id>' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>' \
-H 'Content-Type: application/json' \
-d '{
"value": 1,
"is_active": true,
"is_infinite": true,
"currency_id": "00000000-0000-0000-0000-000000000000",
"expiry_date": "2026-04-01T12:00:00Z",
"min_value": 1,
"is_check_all_products_for_category": true
}'{
"discount_code": {
"id": "00000000-0000-0000-0000-000000000000",
"code": "string",
"type": "string",
"value": 1,
"is_active": true,
"is_used": true,
"is_infinite": true,
"using_date": "2026-04-01T12:00:00Z",
"currency_id": "00000000-0000-0000-0000-000000000000",
"expiry_date": "2026-04-01T12:00:00Z",
"min_value": 1,
"is_check_all_products_for_category": true,
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-01T12:00:00Z"
}
}/api/{version}/admin/discount_codes/{id}
Deletes the discount code. Returns 204 with no body; deleting an already-deleted code is a 404, not a no-op success.
vnstat_ access token, sent as Authorization: Bearer … or X-Vinosoft-Access-Token.Path parameters
| Name | Type | Description |
|---|---|---|
| id required | string (uuid) |
Responses
- 204No Content
- 404ApiErrorResponseNot Found
curl -X DELETE \
'https://<your-shop-domain>/api/2026-04-01/admin/discount_codes/<id>' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer vnstat_<token>'Schemas
ApiErrorResponse
The error envelope every non-2xx response from this API uses. Documentation shape: actions build it as an anonymous object, so this type exists to give the OpenAPI document a schema to point at.
errorsstringnullableHuman-readable description of what went wrong, e.g.
Not Found,Invalid page_info.codestringnullableMachine-readable error code. Only a few endpoints (checkout) emit one; omitted everywhere else.
CreateDiscountCodeRequest
Body for POST /api/{version}/admin/discount_codes. code is required; type defaults to value.
codestringnullabletypestringnullablevaluenumber (double)is_activebooleanis_infinitebooleancurrency_idstring (uuid)nullableexpiry_datestring (date-time)nullablemin_valuenumber (double)is_check_all_products_for_categoryboolean
DiscountCodeDto
Admin representation of a discount code (the discount_codes resource, backed by the existing
coupon domain — api-design.md §17.4). Serialized snake_case via explicit [JsonPropertyName]
attributes, because the host's global JSON policy is camelCase.
idstring (uuid)codestringnullabletypestringnullableDiscount type:
value(fixed amount) orpercent.valuenumber (double)The discount amount — an absolute amount when
type=value, a percentage whentype=percent.is_activebooleanis_usedbooleanTrue once the code has been redeemed (irrelevant while Cloudwawi.Shop.Api.V2026_04_01.DiscountCodeDto.IsInfinite).
is_infinitebooleanWhen true the code may be redeemed without limit; otherwise it is single-use.
using_datestring (date-time)nullablecurrency_idstring (uuid)nullableCurrency the fixed Cloudwawi.Shop.Api.V2026_04_01.DiscountCodeDto.Value is denominated in;
nullfor percent codes or the tenant default.expiry_datestring (date-time)nullablemin_valuenumber (double)Minimum cart subtotal required before the code applies (
0= no minimum).is_check_all_products_for_categorybooleancreated_atstring (date-time)updated_atstring (date-time)nullable
DiscountCodeListResponse
Envelope returned by GET /admin/discount_codes.
One page of discount codes. Paging is cursored: when more exist, the response carries a Link header
of the form <https://…?limit=50&page_info=…>; rel="next". Follow that URL verbatim — the
cursor embeds a fingerprint of the query that produced the page, and a request whose query string no
longer matches is rejected with 422. There is no total count and no last page link.
The page of discount codes, newest first, expired and inactive ones included — this read applies no validity filter. Always present; an empty array when the tenant has none.
DiscountCodeResponse
Envelope returned by GET /admin/discount_codes/{id}, POST /admin/discount_codes (201) and
PUT /admin/discount_codes/{id}.
discount_codeDiscountCodeDto
UpdateDiscountCodeRequest
Body for PUT /api/{version}/admin/discount_codes/{id}. Every field is optional; only the
supplied ones are applied. code and type are immutable after creation and are ignored.
valuenumber (double)nullableis_activebooleannullableis_infinitebooleannullablecurrency_idstring (uuid)nullableexpiry_datestring (date-time)nullablemin_valuenumber (double)nullableis_check_all_products_for_categorybooleannullable
