> For the complete documentation index, see [llms.txt](https://apidocs.akinon.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://apidocs.akinon.com/commerce-openapis/admin/bulk-voucher-codes/create-a-bulk-voucher-code.md).

# Create a bulk voucher code

Manually adds a single voucher code to a basket offer, optionally assigning it to a user.

The code is **always created in `active` status**; a `status` value sent in the request is ignored.

Business rules:

* The code value must be unique across all bulk voucher codes (`promotion_100_2`).
* A user can hold at most one code per basket offer; assigning a second code to the same user for the same offer is rejected (`promotion_100_6`).

```json
{"openapi":"3.1.0","info":{"title":"Admin API","version":"1.0.0"},"tags":[{"name":"Bulk Voucher Codes","description":"Administrative endpoints for **bulk voucher codes** — the individually generated, single-use codes that belong to a basket offer of type `bulk_voucher_code`. Typical integrations include distributing campaign codes to customers and redeeming or managing codes from external systems such as in-store checkout (POS) applications. The parent campaigns themselves are managed with the **Basket Offers** endpoints (`/basket_offers/`).\n\n## Core Capabilities\n\n**1. Code Listing & Filtering**\n* Retrieve a paginated list of voucher codes, newest first.\n* Filter by the parent basket offer, code value, status, and assigned user — the filters behind the code list of the management panel (e.g. `?basket_offer=35763&status=active&limit=20&page=1`).\n\n**2. Code Lifecycle Management**\n* Add a single code manually and optionally assign it to a user.\n* Activate or deactivate a code by updating its `status` (used codes are immutable).\n\n**3. Bulk Code Generation**\n* Generate any number of random codes for a campaign from a prefix, alphabet, and length; generation runs asynchronously in the background.\n\n## Code Statuses\n\nA voucher code shares the status vocabulary of basket offers.\n\n| Value | Description |\n|-------|-------------|\n| `active` | The code can be redeemed. Newly created and generated codes always start in this status. |\n| `passive` | The code is disabled and cannot be redeemed. |\n| `used` | The code has been redeemed. A used code can no longer be updated. |\n| `revoked` | The code has been withdrawn. |\n\n## Dynamic Settings & Environment Variables\n\nNo dynamic settings (`dj_dynamic_settings`) are read by these endpoints: listing, creation, update, bulk generation, and the import/export flows are not influenced by any management-panel setting. Note that whether a code is *redeemable on the storefront* is governed by the parent basket offer (its status, dates, conditions) and by the promotion-application settings documented in the **Basket Offers** section — not by these administrative endpoints.\n\n**Environment variables:** No environment variables affect these endpoints."}],"servers":[{"description":"Omnitron Remote Proxy (external access — recommended)","url":"https://{omnitron_url}/api/remote/{channel_id}","variables":{"omnitron_url":{"default":"sandbox.akinon.com","description":"Omnitron server URL (e.g., {omnitron.akinon.com})"},"channel_id":{"default":"1","description":"The channel identifier the remote request is routed through"}}},{"description":"Commerce API Server (internal / direct access only)","url":"https://{commerce_url}/api/v1","variables":{"commerce_url":{"default":"sandbox.akinon.com","description":"Internal commerce server URL, reachable only from within the Omnitron network"}}}],"security":[{"tokenAuth":[]}],"components":{"securitySchemes":{"tokenAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"Token credential sent in the Authorization header, in the form: `Token <your-token>`. Requires a staff (admin) account."}},"schemas":{"BulkVoucherCodeRequest":{"type":"object","description":"The payload accepted when creating or updating a bulk voucher code.","required":["code","basket_offer","status"],"properties":{"code":{"type":"string","maxLength":32,"description":"The voucher code value. Must be unique across all bulk voucher codes."},"basket_offer":{"type":"integer","description":"Identifier of the parent basket offer."},"status":{"allOf":[{"$ref":"#/components/schemas/VoucherCodeStatus"}],"description":"The code status. On **create** this value is ignored — new codes are always created as `active`. On **update** it activates (`active`) or deactivates (`passive`) the code."},"user":{"type":["integer","null"],"description":"Identifier of the user the code is assigned to, when any. A user can hold at most one code per basket offer."}}},"VoucherCodeStatus":{"type":"string","description":"The lifecycle status of a voucher code.\n* `active` — the code can be redeemed; new codes always start here\n* `passive` — the code is disabled\n* `used` — the code has been redeemed and can no longer be updated\n* `revoked` — the code has been withdrawn","enum":["active","passive","used","revoked"]},"BulkVoucherCode":{"type":"object","description":"A bulk voucher code as returned by the API.","properties":{"pk":{"type":"integer","description":"Unique voucher code identifier."},"code":{"type":"string","description":"The voucher code value."},"basket_offer":{"type":"integer","description":"Identifier of the parent basket offer."},"status":{"$ref":"#/components/schemas/VoucherCodeStatus"},"user":{"type":["integer","null"],"description":"Identifier of the user the code is assigned to, when any."},"user_email":{"type":["string","null"],"description":"Email address of the assigned user, when any."}}},"ValidationError":{"type":"object","description":"Returned when the request contains invalid or missing data. Errors are grouped by the field they apply to: each key is the name of a field from the request and its value is a list of one or more messages describing what is wrong with that field. Messages that do not belong to any single field are grouped under `non_field_errors`.","properties":{"non_field_errors":{"type":"array","description":"Error messages that apply to the request as a whole rather than to a specific field.","items":{"type":"string"}}},"additionalProperties":{"type":"array","description":"The list of error messages for the field named by the key.","items":{"type":"string"}}},"BulkVoucherCodeBusinessError":{"type":"object","description":"Returned when a request is valid in form but violates a business rule of the promotion engine. The message describes the rule that was violated, and a stable code identifies it.\n\nCodes raised by these endpoints:\n* `promotion_100_2` — a voucher code with the same value already exists.\n* `promotion_100_5` — a used voucher code cannot be updated.\n* `promotion_100_6` — the user already holds a voucher code for this basket offer.","properties":{"non_field_errors":{"type":"string","description":"A human-readable message describing the business rule that was violated."},"error_code":{"type":"string","description":"A stable code identifying the specific business rule violation."}},"additionalProperties":true},"Error":{"type":"object","description":"An error response.","properties":{"detail":{"type":"string","description":"A human-readable description of the error."}},"additionalProperties":true}},"responses":{"BulkVoucherCodeValidationOrBusinessError":{"description":"The request contains invalid or missing data, or violates a business rule — for example a code that already exists (`promotion_100_2`), an attempt to update a used code (`promotion_100_5`), or a user who already holds a code for the offer (`promotion_100_6`).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ValidationError"},{"$ref":"#/components/schemas/BulkVoucherCodeBusinessError"}]}}}},"Unauthorized":{"description":"Authentication credentials were not provided or are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The authenticated user does not have administrator privileges.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/bulk_voucher_codes/":{"post":{"tags":["Bulk Voucher Codes"],"operationId":"createBulkVoucherCode","summary":"Create a bulk voucher code","description":"Manually adds a single voucher code to a basket offer, optionally assigning it to a user.\n\nThe code is **always created in `active` status**; a `status` value sent in the request is ignored.\n\nBusiness rules:\n* The code value must be unique across all bulk voucher codes (`promotion_100_2`).\n* A user can hold at most one code per basket offer; assigning a second code to the same user for the same offer is rejected (`promotion_100_6`).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkVoucherCodeRequest"}}}},"responses":{"201":{"description":"The created voucher code.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkVoucherCode"}}}},"400":{"$ref":"#/components/responses/BulkVoucherCodeValidationOrBusinessError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://apidocs.akinon.com/commerce-openapis/admin/bulk-voucher-codes/create-a-bulk-voucher-code.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
