Swarmtix Help Center
Tool Reference

swarmtix_discounts_create

Creates a private discount code on an event, taking either an amount or a percentage off

swarmtix_discounts_create

Creates a discount on an event and returns it. By default it is a code: it reduces the price only for a buyer who types it at checkout, and it is not advertised on the event page. With kind set to "public" it has a name instead of a code and is advertised on the event page once the event is published.

When you would reach for it

  • A partner or sponsor code for a specific audience.
  • An early-bird code with an end date and a redemption limit.
  • A speaker or staff code taking a fixed amount off one ticket tier.

Scope

discounts:write

This has a scope of its own rather than sharing events:write, because a discount is the one thing in this catalog that changes what a buyer pays. An organizer who wants an assistant to set an event up should not have to hand it the ability to price that event down as well.

Creating a code takes no money and gives none away on its own — it is redeemed at checkout, by a buyer, against tickets that are on sale. But it is the closest this catalog gets to the money, so it is the place the arguments are checked hardest.

Calling this twice with the same code creates two offers that both answer to it. It is not idempotent. Switch the spare off with swarmtix_discounts_delete. Check swarmtix_discounts_list before retrying a call that timed out.

Parameters

NameTypeRequiredDefaultDescription
eventstringYes—The event's id (a GUID) or its URL slug.
endsAtstringYes—When the offer stops being accepted, in ISO 8601 form, read as UTC when no offset is given.
codestringFor "code"—The code a buyer types at checkout. Letters, digits, dots, dashes and underscores, up to 100 characters. Not allowed for "public".
namestringFor "public"—The name shown on the event page. Up to 150 characters. Not allowed for "code".
kindstringNo"code""code" or "public".
amountOffnumberNo—How much to take off each ticket, in the event's currency. Give this or percentOff, not both.
percentOffnumberNo—What percentage to take off each ticket, from 1 to 100. Give this or amountOff, not both.
startsAtstringNonowWhen the offer starts being accepted, in ISO 8601 form.
ticketTypestringNoevery typeThe id of the one ticket type this applies to, from swarmtix_ticket_types_list.
usesLimitintegerNono limitHow many times in total the code may be redeemed. 1 to 1,000,000.

Exactly one of amountOff and percentOff is required. They are stored in one place with a flag saying which kind the offer is, so a request carrying both would silently keep one and throw the other away — it is refused instead.

endsAt is required and must be after the start. There is no "runs until sales end" option here: the setting that means that reads the furthest-future date across the whole system rather than this event's, so this tool always writes an explicit end date.

A coded offer is named after its code. A public offer has a name and no code.

Times are UTC in, event time stored

startsAt and endsAt are read as UTC and then converted to the event's local time, using the event's timezone, before they are stored. Set the timezone with swarmtix_events_update first. An event with no timezone is read as UTC.

Discounts created before this was fixed stored the UTC time as if it were local, so their windows are off by the event's UTC offset. Check them with swarmtix_discounts_list and correct them with swarmtix_discounts_update.

What the code may contain

Letters, digits, dots, dashes and underscores. That is narrower than what the product itself accepts, on purpose: a code that passes this check cannot then be rejected further down with a message this layer is not allowed to repeat, leaving you a generic failure for something you could have fixed.

Example call

{
  "name": "swarmtix_discounts_create",
  "arguments": {
    "event": "spring-summit-2027",
    "code": "PARTNER20",
    "percentOff": 20,
    "endsAt": "2027-09-30T23:59:00Z",
    "usesLimit": 50
  }
}

What comes back

The offer as stored:

{
  "id": "a15c9e02-3b7d-4c61-8f95-6d24e0a7b3c8",
  "eventId": "3b6f81ce-04a2-4d97-b5e8-7c10924af3d6",
  "kind": "code",
  "name": "PARTNER20",
  "code": "PARTNER20",
  "amountOff": 0,
  "percentageOff": 20,
  "appliesToAllTicketTypes": true,
  "unlimited": false,
  "usesLimit": 50,
  "startDate": "2027-01-14T11:06:22",
  "endDate": "2027-09-30T23:59:00",
  "active": true
}
FieldWhat it is
idThe new offer's id
eventIdThe event it was created on
kind"code", "public" or "accessCode"
nameThe offer's name: the code for a coded offer
codeThe code a buyer types
amountOffThe fixed reduction. 0 when the offer is a percentage.
percentageOffThe percentage reduction. 0 when the offer is a fixed amount.
appliesToAllTicketTypesWhether it covers every ticket type on the event
ticketTypeIdThe single ticket type it covers, when it is scoped to one
unlimitedWhether it has no redemption limit
usesLimitThe limit, when there is one
startDate, endDateThe window it is accepted between, in the event's local time
activeWhether the offer is live

What happens when you call it

  1. The event is resolved through the edit gate.
  2. code is validated against the character rule above, and endsAt and startsAt are parsed as UTC when they carry no offset.
  3. Exactly one of amountOff and percentOff is required, and the value is rounded to two decimals.
  4. ticketType, if given, is checked against this event. Nothing downstream does that: the offer is written with whatever id it is handed, so an id from another organisation's event would be stored against yours and two events would share a discount row neither organiser could account for.
  5. The offer is created as a coded discount (redeemed by typing the code) or, with kind "public", a public one. Access codes have their own tool, swarmtix_access_codes_create.
  6. The stored row is read back, checked for belonging to this event, and returned.

Troubleshooting

"amountOff is not valid: neither amountOff nor percentOff was given. Expected one of them, saying how much the code takes off."

One of the two is required.

"amountOff is not valid: both amountOff and percentOff were given. Expected only one of them, because an offer takes off an amount or a percentage but not both."

Send one. Sending both would have quietly kept one and dropped the other.

"amountOff is not valid: it was 0. Expected an amount greater than 0, or percentOff instead."

Zero is not "no discount" here — it is the flag that says the offer is a percentage, and the percentage would be zero too. Use a real amount, or percentOff.

"percentOff is not valid: it was 150. Expected an amount from 0 to 100."

Percentages run from 1 to 100.

"percentOff is not valid: it was 0.5. Expected a percentage from 1 to 100."

Fractions below 1% are not accepted.

"endsAt is not valid: "soon" is not a date and time. Expected a date and time in ISO 8601 form."

Use an ISO 8601 instant — 2027-09-30T23:59:00Z.

"endsAt is not valid: it is not after startsAt. Expected a date and time after the offer starts."

The window has no duration. When startsAt is omitted the offer starts immediately, so endsAt must be in the future.

"code is not valid: it contains " ". Expected a code of letters, digits, dots, dashes or underscores."

The code has a space or another disallowed character. Letters, digits, ., - and _ only.

"ticketType is not valid: there is no ticket type with that id on this event. Expected the id of a ticket type on this event, or nothing to cover all of them."

The ticket type id does not name an active type on that event. List them with swarmtix_ticket_types_list, or omit the argument to cover every type.

"usesLimit is not valid: it was 0. Expected a whole number from 1 to 1000000."

Omit usesLimit for an unlimited code rather than sending zero.

"Event not found, or this connection does not have access to it."

The event does not exist, it belongs to another organisation, or this organizer may read it but not edit it.

"This connection is not authorized for discounts:write. Reconnect and grant it to use this tool."

Reconnect and approve discounts:write. It is a separate permission from events:write on purpose.

The code does not work at checkout

Check it with swarmtix_discounts_check_code — it reports which of the four reasons applies in a sentence.

Two offers now share the same code

Expected after a retry. Switch one off with swarmtix_discounts_delete.

Use cases

  • Partner codes with a limit and an expiry
  • Speaker comps — a fixed amount off one ticket tier
  • Early-bird pricing without creating a second ticket type
  • A public offer shown on the event page, such as "Student price"
  • Campaign codes created and then verified in two calls

On this page