> 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/bulk-voucher-code-import-and-export/import-voucher-codes-from-excel-csv.md).

# Import voucher codes from Excel/CSV

Starts an **asynchronous** import of voucher codes for a basket offer from an uploaded Excel/CSV file and returns a `cache_key` that is polled on **`GET /bulk_voucher_codes/excel_import_status/`** until the result is ready.

The file must contain **exactly** the column headers `voucher_code` and `user_email`, in that order. Each row creates the code (in `active` status) or, when the code already exists for the offer, assigns it to the user with the given email. Rows with problems — duplicate codes or emails within the file, unknown users, codes already assigned, or users already holding a code for the offer — are skipped and reported per row in the import result.

The target basket offer must be of type `bulk_voucher_code`.

```json
{"openapi":"3.1.0","info":{"title":"Admin API","version":"1.0.0"},"tags":[{"name":"Bulk Voucher Code Import & Export","description":"Asynchronous spreadsheet import and export of voucher codes.\n\nImport codes (optionally pre-assigned to users by email) from an Excel/CSV file, and export the codes of a campaign to an Excel file. Both operations are asynchronous: the initial request returns a `cache_key` that is polled on a companion status endpoint until the result is ready."}],"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":{"BulkVoucherCodeSheetImportRequest":{"type":"object","description":"The payload of a spreadsheet import request.","required":["basket_offer","file"],"properties":{"basket_offer":{"type":"integer","description":"Identifier of the target basket offer. The offer must be of type `bulk_voucher_code`."},"file":{"type":"string","contentEncoding":"base64","description":"Base64-encoded Excel or CSV file with exactly the column headers `voucher_code` and `user_email`."}}},"ExcelImportStatus":{"type":"object","description":"The status envelope of an asynchronous Excel/CSV import.","properties":{"cache_key":{"type":"string","format":"uuid","description":"The job key used to poll the import status."},"is_ready":{"type":"boolean","description":"Whether the import has finished."},"result":{"type":["object","null"],"description":"The import result, present once `is_ready` is `true`.","properties":{"assigned_count":{"type":"integer","description":"The number of codes created or assigned successfully."},"errors":{"type":"array","description":"One entry for every skipped row.","items":{"type":"object","properties":{"voucher_code":{"type":"string","description":"The code value of the skipped row."},"user_email":{"type":"string","description":"The email of the skipped row."},"error":{"type":"string","description":"Why the row was skipped."}}}},"summary":{"type":"object","description":"Aggregate counts of the import.","properties":{"total_rows":{"type":"integer","description":"The total number of rows in the file."},"successful":{"type":"integer","description":"The number of rows processed successfully."},"failed":{"type":"integer","description":"The number of rows skipped with an error."}}}}},"error_message":{"type":["string","null"],"description":"A human-readable error message when the import failed or was not found."}}},"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"}}},"Error":{"type":"object","description":"An error response.","properties":{"detail":{"type":"string","description":"A human-readable description of the error."}},"additionalProperties":true}},"responses":{"ValidationError":{"description":"The request contains invalid or missing data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"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/excel_import/":{"post":{"tags":["Bulk Voucher Code Import & Export"],"operationId":"importBulkVoucherCodes","summary":"Import voucher codes from Excel/CSV","description":"Starts an **asynchronous** import of voucher codes for a basket offer from an uploaded Excel/CSV file and returns a `cache_key` that is polled on **`GET /bulk_voucher_codes/excel_import_status/`** until the result is ready.\n\nThe file must contain **exactly** the column headers `voucher_code` and `user_email`, in that order. Each row creates the code (in `active` status) or, when the code already exists for the offer, assigns it to the user with the given email. Rows with problems — duplicate codes or emails within the file, unknown users, codes already assigned, or users already holding a code for the offer — are skipped and reported per row in the import result.\n\nThe target basket offer must be of type `bulk_voucher_code`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkVoucherCodeSheetImportRequest"}}}},"responses":{"202":{"description":"The import job was queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExcelImportStatus"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"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/bulk-voucher-code-import-and-export/import-voucher-codes-from-excel-csv.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.
