> For the complete documentation index, see [llms.txt](https://eventx-hq.gitbook.io/knowledge-base/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://eventx-hq.gitbook.io/knowledge-base/api-v2/promo-codes.md).

# Promo Codes

Promo code CRUD — discount for ticket classes, org/event scoped, write needs confirm via MCP

## List promo codes

> List promo codes for an event — paginated, filterable by codeName substring and isActive. Requires organizer\_api\_token read, org or event scoped. Excludes soft-deleted rows.

```json
{"openapi":"3.1.0","info":{"title":"EventX Public API v2","version":"v2"},"tags":[{"name":"promo codes","description":"Promo code CRUD — discount for ticket classes, org/event scoped, write needs confirm via MCP"}],"servers":[{"url":"https://api.eventx.io","description":"EventX Public API server"}],"security":[{"organizerApiToken":[]}],"components":{"securitySchemes":{"organizerApiToken":{"type":"http","scheme":"bearer","description":"Organizer API token — Authorization: Bearer evtx_live_… (Org/Event scoped, read/write)."}}},"paths":{"/v2/events/{eventId}/promo-codes":{"get":{"tags":["promo codes"],"summary":"List promo codes","description":"List promo codes for an event — paginated, filterable by codeName substring and isActive. Requires organizer_api_token read, org or event scoped. Excludes soft-deleted rows.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"eventId","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"default":0},"required":false,"name":"offset","in":"query"},{"schema":{"type":"string","description":"Filter by codeName substring (case-insensitive)"},"required":false,"name":"q","in":"query"},{"schema":{"type":["boolean","null"]},"required":false,"name":"isActive","in":"query"}],"responses":{"200":{"description":"Paginated promo codes","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Promo code ID, UUID"},"eventId":{"type":["string","null"],"format":"uuid","description":"Event ID"},"codeName":{"type":["string","null"],"description":"Human-readable code name, unique per event"},"remarks":{"type":["string","null"],"description":"Internal remarks"},"discountType":{"type":["string","null"],"description":"subtractByPercentage | subtractByFixedAmount | chargeByFixedAmount"},"discount":{"type":["string","null"],"description":"Fixed amount string, for subtractByFixedAmount/chargeByFixedAmount"},"discountRate":{"type":["string","null"],"description":"Percentage string 0-100, for subtractByPercentage"},"quota":{"type":["number","null"],"description":"Max redemptions, null = unlimited"},"isActive":{"type":["boolean","null"],"description":"Whether code is currently active"},"isAppliedToAllTicketClasses":{"type":["boolean","null"],"description":"If true, applies to all ticket classes; otherwise ticketClassIds lists scope"},"ticketClassIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Ticket class IDs this code applies to (empty when isAppliedToAllTicketClasses=true)"},"startDate":{"type":["string","null"],"description":"Start time ISO"},"endDate":{"type":["string","null"],"description":"End time ISO, null = no expiry"},"timezone":{"type":["string","null"],"description":"IANA timezone for start/end display"},"createdAt":{"type":["string","null"]},"updatedAt":{"type":["string","null"]}},"required":["id","eventId","codeName","remarks","discountType","discount","discountRate","quota","isActive","isAppliedToAllTicketClasses","ticketClassIds","startDate","endDate","timezone","createdAt","updatedAt"],"description":"Promo code row — scoped by organizer_api_token (Org or Event, not user). Discount affects ticket pricing; PATCH is human-confirmed via MCP."}},"total":{"type":"number"},"limit":{"type":"number"},"offset":{"type":"number"}},"required":["data","total","limit","offset"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"404":{"description":"Event not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}}}}}}}
```

## Create promo code

> Create promo code — event-create allowed for event-scoped token (token.eventId must match). Validates discount range, price, and ticketClass ownership. Requires write.

```json
{"openapi":"3.1.0","info":{"title":"EventX Public API v2","version":"v2"},"tags":[{"name":"promo codes","description":"Promo code CRUD — discount for ticket classes, org/event scoped, write needs confirm via MCP"}],"servers":[{"url":"https://api.eventx.io","description":"EventX Public API server"}],"security":[{"organizerApiToken":[]}],"components":{"securitySchemes":{"organizerApiToken":{"type":"http","scheme":"bearer","description":"Organizer API token — Authorization: Bearer evtx_live_… (Org/Event scoped, read/write)."}}},"paths":{"/v2/events/{eventId}/promo-codes":{"post":{"tags":["promo codes"],"summary":"Create promo code","description":"Create promo code — event-create allowed for event-scoped token (token.eventId must match). Validates discount range, price, and ticketClass ownership. Requires write.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"eventId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"codeName":{"type":"string","minLength":1,"maxLength":100,"description":"Unique per event, required"},"remarks":{"type":["string","null"],"maxLength":500},"discountType":{"type":"string","enum":["subtractByPercentage","subtractByFixedAmount","chargeByFixedAmount"],"description":"Discount type, required"},"discount":{"type":["string","null"],"description":"Fixed amount string; required for subtractByFixedAmount/chargeByFixedAmount"},"discountRate":{"type":["string","null"],"description":"Percentage 0-100 string; for subtractByPercentage"},"quota":{"type":["integer","null"],"minimum":1,"description":"Max redemptions; null = unlimited"},"isActive":{"type":"boolean","description":"Active flag, defaults to true"},"isAppliedToAllTicketClasses":{"type":"boolean","description":"If true, ticketClassIds is ignored"},"ticketClassIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Ticket class IDs when isAppliedToAllTicketClasses=false"},"startDate":{"type":"string","description":"ISO start, required"},"endDate":{"type":["string","null"],"description":"ISO end, null = no expiry"},"timezone":{"type":"string","minLength":1,"description":"IANA timezone, required"}},"required":["codeName","discountType","isAppliedToAllTicketClasses","startDate","timezone"],"description":"Create promo code — requires organizer_api_token write, org or event scoped (event-create allowed). Validates discount range and ticket class scope."}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Promo code ID, UUID"},"eventId":{"type":["string","null"],"format":"uuid","description":"Event ID"},"codeName":{"type":["string","null"],"description":"Human-readable code name, unique per event"},"remarks":{"type":["string","null"],"description":"Internal remarks"},"discountType":{"type":["string","null"],"description":"subtractByPercentage | subtractByFixedAmount | chargeByFixedAmount"},"discount":{"type":["string","null"],"description":"Fixed amount string, for subtractByFixedAmount/chargeByFixedAmount"},"discountRate":{"type":["string","null"],"description":"Percentage string 0-100, for subtractByPercentage"},"quota":{"type":["number","null"],"description":"Max redemptions, null = unlimited"},"isActive":{"type":["boolean","null"],"description":"Whether code is currently active"},"isAppliedToAllTicketClasses":{"type":["boolean","null"],"description":"If true, applies to all ticket classes; otherwise ticketClassIds lists scope"},"ticketClassIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Ticket class IDs this code applies to (empty when isAppliedToAllTicketClasses=true)"},"startDate":{"type":["string","null"],"description":"Start time ISO"},"endDate":{"type":["string","null"],"description":"End time ISO, null = no expiry"},"timezone":{"type":["string","null"],"description":"IANA timezone for start/end display"},"createdAt":{"type":["string","null"]},"updatedAt":{"type":["string","null"]}},"required":["id","eventId","codeName","remarks","discountType","discount","discountRate","quota","isActive","isAppliedToAllTicketClasses","ticketClassIds","startDate","endDate","timezone","createdAt","updatedAt"],"description":"Promo code row — scoped by organizer_api_token (Org or Event, not user). Discount affects ticket pricing; PATCH is human-confirmed via MCP."}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"404":{"description":"Event or ticket class not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}}}}}}}
```

## Get promo code

> Get single promo code by ID, scoped to event. Requires read.

```json
{"openapi":"3.1.0","info":{"title":"EventX Public API v2","version":"v2"},"tags":[{"name":"promo codes","description":"Promo code CRUD — discount for ticket classes, org/event scoped, write needs confirm via MCP"}],"servers":[{"url":"https://api.eventx.io","description":"EventX Public API server"}],"security":[{"organizerApiToken":[]}],"components":{"securitySchemes":{"organizerApiToken":{"type":"http","scheme":"bearer","description":"Organizer API token — Authorization: Bearer evtx_live_… (Org/Event scoped, read/write)."}}},"paths":{"/v2/events/{eventId}/promo-codes/{promoCodeId}":{"get":{"tags":["promo codes"],"summary":"Get promo code","description":"Get single promo code by ID, scoped to event. Requires read.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"eventId","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"promoCodeId","in":"path"}],"responses":{"200":{"description":"Promo code","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Promo code ID, UUID"},"eventId":{"type":["string","null"],"format":"uuid","description":"Event ID"},"codeName":{"type":["string","null"],"description":"Human-readable code name, unique per event"},"remarks":{"type":["string","null"],"description":"Internal remarks"},"discountType":{"type":["string","null"],"description":"subtractByPercentage | subtractByFixedAmount | chargeByFixedAmount"},"discount":{"type":["string","null"],"description":"Fixed amount string, for subtractByFixedAmount/chargeByFixedAmount"},"discountRate":{"type":["string","null"],"description":"Percentage string 0-100, for subtractByPercentage"},"quota":{"type":["number","null"],"description":"Max redemptions, null = unlimited"},"isActive":{"type":["boolean","null"],"description":"Whether code is currently active"},"isAppliedToAllTicketClasses":{"type":["boolean","null"],"description":"If true, applies to all ticket classes; otherwise ticketClassIds lists scope"},"ticketClassIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Ticket class IDs this code applies to (empty when isAppliedToAllTicketClasses=true)"},"startDate":{"type":["string","null"],"description":"Start time ISO"},"endDate":{"type":["string","null"],"description":"End time ISO, null = no expiry"},"timezone":{"type":["string","null"],"description":"IANA timezone for start/end display"},"createdAt":{"type":["string","null"]},"updatedAt":{"type":["string","null"]}},"required":["id","eventId","codeName","remarks","discountType","discount","discountRate","quota","isActive","isAppliedToAllTicketClasses","ticketClassIds","startDate","endDate","timezone","createdAt","updatedAt"],"description":"Promo code row — scoped by organizer_api_token (Org or Event, not user). Discount affects ticket pricing; PATCH is human-confirmed via MCP."}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}}}}}}}
```

## Delete promo code

> Soft delete — sets deletedAt, keeps assignment rows. Requires write.

```json
{"openapi":"3.1.0","info":{"title":"EventX Public API v2","version":"v2"},"tags":[{"name":"promo codes","description":"Promo code CRUD — discount for ticket classes, org/event scoped, write needs confirm via MCP"}],"servers":[{"url":"https://api.eventx.io","description":"EventX Public API server"}],"security":[{"organizerApiToken":[]}],"components":{"securitySchemes":{"organizerApiToken":{"type":"http","scheme":"bearer","description":"Organizer API token — Authorization: Bearer evtx_live_… (Org/Event scoped, read/write)."}}},"paths":{"/v2/events/{eventId}/promo-codes/{promoCodeId}":{"delete":{"tags":["promo codes"],"summary":"Delete promo code","description":"Soft delete — sets deletedAt, keeps assignment rows. Requires write.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"eventId","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"promoCodeId","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}}}}}}}
```

## Patch promo code

> Partial update — at least one field. codeName rename checks duplicate per event. Validates discount/price/ticket scope. Requires write and human confirmation when via MCP (confirm:true). Best-effort duplicate race.

```json
{"openapi":"3.1.0","info":{"title":"EventX Public API v2","version":"v2"},"tags":[{"name":"promo codes","description":"Promo code CRUD — discount for ticket classes, org/event scoped, write needs confirm via MCP"}],"servers":[{"url":"https://api.eventx.io","description":"EventX Public API server"}],"security":[{"organizerApiToken":[]}],"components":{"securitySchemes":{"organizerApiToken":{"type":"http","scheme":"bearer","description":"Organizer API token — Authorization: Bearer evtx_live_… (Org/Event scoped, read/write)."}}},"paths":{"/v2/events/{eventId}/promo-codes/{promoCodeId}":{"patch":{"tags":["promo codes"],"summary":"Patch promo code","description":"Partial update — at least one field. codeName rename checks duplicate per event. Validates discount/price/ticket scope. Requires write and human confirmation when via MCP (confirm:true). Best-effort duplicate race.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"eventId","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"promoCodeId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"codeName":{"type":"string","minLength":1,"maxLength":100},"remarks":{"type":["string","null"],"maxLength":500},"discountType":{"type":"string","enum":["subtractByPercentage","subtractByFixedAmount","chargeByFixedAmount"]},"discount":{"type":["string","null"]},"discountRate":{"type":["string","null"]},"quota":{"type":["integer","null"],"minimum":1},"isActive":{"type":"boolean"},"isAppliedToAllTicketClasses":{"type":"boolean"},"ticketClassIds":{"type":"array","items":{"type":"string","format":"uuid"}},"startDate":{"type":"string"},"endDate":{"type":["string","null"]},"timezone":{"type":"string"}},"description":"Partial update — at least one field required. codeName rename checks duplicate. Requires human confirmation via MCP confirm:true."}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Promo code ID, UUID"},"eventId":{"type":["string","null"],"format":"uuid","description":"Event ID"},"codeName":{"type":["string","null"],"description":"Human-readable code name, unique per event"},"remarks":{"type":["string","null"],"description":"Internal remarks"},"discountType":{"type":["string","null"],"description":"subtractByPercentage | subtractByFixedAmount | chargeByFixedAmount"},"discount":{"type":["string","null"],"description":"Fixed amount string, for subtractByFixedAmount/chargeByFixedAmount"},"discountRate":{"type":["string","null"],"description":"Percentage string 0-100, for subtractByPercentage"},"quota":{"type":["number","null"],"description":"Max redemptions, null = unlimited"},"isActive":{"type":["boolean","null"],"description":"Whether code is currently active"},"isAppliedToAllTicketClasses":{"type":["boolean","null"],"description":"If true, applies to all ticket classes; otherwise ticketClassIds lists scope"},"ticketClassIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Ticket class IDs this code applies to (empty when isAppliedToAllTicketClasses=true)"},"startDate":{"type":["string","null"],"description":"Start time ISO"},"endDate":{"type":["string","null"],"description":"End time ISO, null = no expiry"},"timezone":{"type":["string","null"],"description":"IANA timezone for start/end display"},"createdAt":{"type":["string","null"]},"updatedAt":{"type":["string","null"]}},"required":["id","eventId","codeName","remarks","discountType","discount","discountRate","quota","isActive","isAppliedToAllTicketClasses","ticketClassIds","startDate","endDate","timezone","createdAt","updatedAt"],"description":"Promo code row — scoped by organizer_api_token (Org or Event, not user). Discount affects ticket pricing; PATCH is human-confirmed via MCP."}}}},"400":{"description":"Validation","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"},"meta":{}},"required":["code","message","status"]}}}}}}}}}
```
