Reference: Tickets

Tickets, their panels and menus, and saved transcripts.

Good to know

Every request needs your key: Authorization: Bearer tfy_…. Replace YOUR_SERVER_ID with your Discord server id. Errors are explained in Requests, errors and limits.

GET /tickets

GET /guilds/{guildId}/tickets

The list, filterable by state, panel, opener and claimant.

Key permissiontickets.read (See tickets)

Query parameters

Added to the address after a ?, like ?limit=10&order=asc.

FieldTypeRequiredWhat it is
limitintegerNoHow many to answer with at most, 1 to 100.1 to 100 · default 25
cursorstringNoThe nextCursor of the page before, to get the next page. Absent: the first page.at most 64 characters
order"asc" | "desc"Nodesc for newest first, asc for oldest first.default "desc"
state"open" | "closed" | "deleted"NoOnly tickets in this state, such as open.
panelIdstringNoOnly tickets from this panel.at most 40 characters
openerDiscordUserIdstringNoOnly tickets this member opened.digits only
claimedBystringNoOnly tickets claimed by this person (a Technified user id).at most 40 characters
qstringNoWords in the reason or the opener’s name.at most 100 characters

No request body.

Example

curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"
Answer · 200
{
  "items": [
    {
      "id": "tkt_01M5TXYM1CHGR14TA8A0PR6YX4",
      "number": 12,
      "panelId": null,
      "channelId": null,
      "channelName": "ticket-12",
      "openerDiscordUserId": "17929789298638349990005",
      "reason": "I was scammed in game",
      "source": "panel",
      "submissionId": null,
      "state": "open",
      "claimedBy": null,
      "claimedAt": null,
      "participants": [],
      "closedBy": null,
      "closedAt": null,
      "closeReason": null,
      "lastActivityAt": "2026-10-26T01:42:11.756Z",
      "createdAt": "2026-10-26T01:42:11.756Z"
    }
  ],
  "nextCursor": null
}

POST /tickets

POST /guilds/{guildId}/tickets

Opens one.

Key permissionAny key of this server.
Retry safelySend an Idempotency-Key header; a retry with the same one is not done twice.

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
panelIdstringNoThe panel whose settings the ticket opens with.at most 40 characters
discordUserIdstringNoThe member the ticket is for (Discord user id). Absent: the caller.digits only
reasonstring or nullNoWhat it is about. Staff see it first.at most 1000 characters · default null
source"panel" | "menu" | "submission" | "command" | "api"NoWhere it came from, for the record. Leave it out.default "api"
submissionIdstringNoThe submission the ticket continues, if any.at most 40 characters

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'

GET /tickets/{ticketId}

GET /guilds/{guildId}/tickets/{ticketId}

One ticket.

Key permissiontickets.read (See tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).

No request body.

Example

curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

DELETE /tickets/{ticketId}

DELETE /guilds/{guildId}/tickets/{ticketId}

Saves a transcript, then deletes the channel. Refused with transcript_failed when the transcript cannot be saved.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).

No request body.

Example

curl -X DELETE "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

POST /tickets/{ticketId}/claim

POST /guilds/{guildId}/tickets/{ticketId}/claim

Takes responsibility for it. ?takeOver=true takes it from whoever had it. The Claim button in the channel becomes "Claimed by …".

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).

Query parameters

Added to the address after a ?, like ?limit=10&order=asc.

FieldTypeRequiredWhat it is
takeOver"true" | "false"Notrue to take a ticket somebody else claimed. Otherwise that is refused.default "false"

No request body.

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID/claim" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

DELETE /tickets/{ticketId}/claim

DELETE /guilds/{guildId}/tickets/{ticketId}/claim

Hands it back. The button says Claim again.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).

No request body.

Example

curl -X DELETE "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID/claim" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

POST /tickets/{ticketId}/close

POST /guilds/{guildId}/tickets/{ticketId}/close

Closes it, saving a transcript unless told not to. A transcript that fails is reported in transcriptError, and what Discord refused in discord; neither undoes the close.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
reasonstring or nullNoWhy it was closed. Kept with the ticket and posted in the channel.at most 1000 characters · default null
saveTranscriptbooleanNoSave a transcript now. Absent: whatever the ticket’s panel says.

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID/close" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

POST /tickets/{ticketId}/participants

POST /guilds/{guildId}/tickets/{ticketId}/participants

Lets somebody into the ticket.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
discordUserIdstringYesThe Discord user id of the person to add.digits only

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID/participants" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"discordUserId":"123456789012345678"}'

DELETE /tickets/{ticketId}/participants/{discordUserId}

DELETE /guilds/{guildId}/tickets/{ticketId}/participants/{discordUserId}

Takes somebody out. The opener can never be removed.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).
discordUserIdstringYesA Discord user id (digits).

No request body.

Example

curl -X DELETE "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID/participants/DISCORDUSERID" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

POST /tickets/{ticketId}/reopen

POST /guilds/{guildId}/tickets/{ticketId}/reopen

Opens it again.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).

No request body.

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID/reopen" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

POST /tickets/{ticketId}/transcript

POST /guilds/{guildId}/tickets/{ticketId}/transcript

Saves a transcript now.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
ticketIdstringYesA ticket’s id (tkt_…).

No request body.

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/TICKETID/transcript" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

GET /tickets/menus

GET /guilds/{guildId}/tickets/menus

Key permissiontickets.read (See tickets)

No request body.

Example

curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/menus" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

POST /tickets/menus

POST /guilds/{guildId}/tickets/menus

Key permissiontickets.write (Handle tickets)

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
namestringYes1 to 60 characters
titlestringYes1 to 120 characters
descriptionstring or nullNoat most 2000 characters · default null
placeholderstringNo1 to 100 characters · default "Choose a topic"
panelIdsarray of stringYes1 to 25 items

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/menus" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"…","title":"…","panelIds":["…"]}'

PATCH /tickets/menus/{menuId}

PATCH /guilds/{guildId}/tickets/menus/{menuId}

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
menuIdstringYesA ticket menu’s id (mnu_…).

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
namestringNo1 to 60 characters
titlestringNo1 to 120 characters
descriptionstring or nullNoat most 2000 characters · default null
placeholderstringNo1 to 100 characters · default "Choose a topic"
panelIdsarray of stringNo1 to 25 items

Example

curl -X PATCH "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/menus/MENUID" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

DELETE /tickets/menus/{menuId}

DELETE /guilds/{guildId}/tickets/menus/{menuId}

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
menuIdstringYesA ticket menu’s id (mnu_…).

No request body.

Example

curl -X DELETE "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/menus/MENUID" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

POST /tickets/menus/{menuId}/publish

POST /guilds/{guildId}/tickets/menus/{menuId}/publish

Posts the menu into a channel. A copy posted before is taken down.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
menuIdstringYesA ticket menu’s id (mnu_…).

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
channelIdstringYesThe Discord channel id to post it in.digits only

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/menus/MENUID/publish" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channelId":"123456789012345678"}'

GET /tickets/panels

GET /guilds/{guildId}/tickets/panels

Key permissiontickets.read (See tickets)

No request body.

Example

curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/panels" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

POST /tickets/panels

POST /guilds/{guildId}/tickets/panels

Key permissiontickets.write (Handle tickets)

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
namestringYes1 to 60 characters
titlestringYes1 to 120 characters
descriptionstring or nullNoat most 2000 characters · default null
buttonLabelstringNo1 to 60 characters · default "Open a ticket"
buttonStyle"primary" | "secondary" | "success" | "danger"Nodefault "primary"
buttonEmojistring or nullNoat most 64 characters · default null
categoryIdstring or nullNodigits only · default null
namingPatternstringNo1 to 60 characters · default "ticket-{number}"
welcomeMessagestring or nullNoat most 2000 characters · default null
reasonRequiredbooleanNodefault false
maxOpenPerMemberintegerNo1 to 25 · default 1
autoCloseAfterHoursinteger or nullNo1 to 720 · default null
deleteClosedAfterHoursinteger or nullNo1 to 720 · default 24
saveTranscriptOnClosebooleanNodefault true
staffRoleIdsarray of stringNoat most 25 items · default []
messageobject, one of the shapes below or nullNodefault null

message takes one of these shapes:

kind: "embed"

FieldTypeRequiredWhat it is
kind"embed"Yes
contentstring or nullNoat most 2000 characters · default null
embedobject or nullNodefault null
embed.authorstring or nullNoat most 256 characters · default null
embed.titlestring or nullNoat most 256 characters · default null
embed.titleUrlstring or nullNoat most 500 characters · default null
embed.descriptionstring or nullNoat most 4000 characters · default null
embed.colourstring or nullNodefault null
embed.fieldsarray of objectsNoat most 25 items · default []
embed.fields[].namestringYes1 to 256 characters
embed.fields[].valuestringYes1 to 1024 characters
embed.fields[].inlinebooleanNodefault false
embed.imageUrlstring or nullNoat most 500 characters · default null
embed.thumbnailUrlstring or nullNoat most 500 characters · default null
embed.footerstring or nullNoat most 2048 characters · default null

kind: "components"

FieldTypeRequiredWhat it is
kind"components"Yes
componentsobjectYes
components.boxedbooleanNo
components.accentColourstring or nullNodefault null
components.spoilerbooleanNodefault false
components.blocksarray of object, one of the shapes belowYesat most 30 items

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/panels" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"…","title":"…"}'

PATCH /tickets/panels/{panelId}

PATCH /guilds/{guildId}/tickets/panels/{panelId}

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
panelIdstringYesA ticket panel’s id (pnl_…).

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
namestringNo1 to 60 characters
titlestringNo1 to 120 characters
descriptionstring or nullNoat most 2000 characters · default null
buttonLabelstringNo1 to 60 characters · default "Open a ticket"
buttonStyle"primary" | "secondary" | "success" | "danger"Nodefault "primary"
buttonEmojistring or nullNoat most 64 characters · default null
categoryIdstring or nullNodigits only · default null
namingPatternstringNo1 to 60 characters · default "ticket-{number}"
welcomeMessagestring or nullNoat most 2000 characters · default null
reasonRequiredbooleanNodefault false
maxOpenPerMemberintegerNo1 to 25 · default 1
autoCloseAfterHoursinteger or nullNo1 to 720 · default null
deleteClosedAfterHoursinteger or nullNo1 to 720 · default 24
saveTranscriptOnClosebooleanNodefault true
staffRoleIdsarray of stringNoat most 25 items · default []
messageobject, one of the shapes below or nullNodefault null

message takes one of these shapes:

kind: "embed"

FieldTypeRequiredWhat it is
kind"embed"Yes
contentstring or nullNoat most 2000 characters · default null
embedobject or nullNodefault null
embed.authorstring or nullNoat most 256 characters · default null
embed.titlestring or nullNoat most 256 characters · default null
embed.titleUrlstring or nullNoat most 500 characters · default null
embed.descriptionstring or nullNoat most 4000 characters · default null
embed.colourstring or nullNodefault null
embed.fieldsarray of objectsNoat most 25 items · default []
embed.fields[].namestringYes1 to 256 characters
embed.fields[].valuestringYes1 to 1024 characters
embed.fields[].inlinebooleanNodefault false
embed.imageUrlstring or nullNoat most 500 characters · default null
embed.thumbnailUrlstring or nullNoat most 500 characters · default null
embed.footerstring or nullNoat most 2048 characters · default null

kind: "components"

FieldTypeRequiredWhat it is
kind"components"Yes
componentsobjectYes
components.boxedbooleanNo
components.accentColourstring or nullNodefault null
components.spoilerbooleanNodefault false
components.blocksarray of object, one of the shapes belowYesat most 30 items

Example

curl -X PATCH "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/panels/PANELID" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

DELETE /tickets/panels/{panelId}

DELETE /guilds/{guildId}/tickets/panels/{panelId}

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
panelIdstringYesA ticket panel’s id (pnl_…).

No request body.

Example

curl -X DELETE "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/panels/PANELID" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

POST /tickets/panels/{panelId}/publish

POST /guilds/{guildId}/tickets/panels/{panelId}/publish

Posts the panel into a channel.

Key permissiontickets.write (Handle tickets)

In the address

FieldTypeRequiredWhat it is
panelIdstringYesA ticket panel’s id (pnl_…).

Request body

JSON, sent with Content-Type: application/json.

FieldTypeRequiredWhat it is
channelIdstringYesThe Discord channel id to post it in.digits only

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/panels/PANELID/publish" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channelId":"123456789012345678"}'

GET /tickets/transcripts

GET /guilds/{guildId}/tickets/transcripts

Saved transcripts, newest first, with a cursor.

Key permissiontickets.read (See tickets)

Query parameters

Added to the address after a ?, like ?limit=10&order=asc.

FieldTypeRequiredWhat it is
limitintegerNoHow many to answer with at most, 1 to 100.1 to 100 · default 25
cursorstringNoThe nextCursor of the page before.at most 40 characters

No request body.

Example

curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/transcripts" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

GET /tickets/transcripts/{transcriptId}

GET /guilds/{guildId}/tickets/transcripts/{transcriptId}

One transcript, as a self contained HTML page.

Key permissiontickets.read (See tickets)

In the address

FieldTypeRequiredWhat it is
transcriptIdstringYesA transcript’s id (trs_…).

No request body.

Example

curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/tickets/transcripts/TRANSCRIPTID" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"

Still stuck? Get help from the Technified team.