Reference: Applications
Application and appeal forms, what people sent, and deciding it.
Good to know
Authorization: Bearer tfy_…. Replace YOUR_SERVER_ID with your Discord server id. Errors are explained in Requests, errors and limits.GET /forms
GET /guilds/{guildId}/forms
| Key permission | forms.read (See applications and appeals) |
Query parameters
Added to the address after a ?, like ?limit=10&order=asc.
| Field | Type | Required | What it is |
|---|---|---|---|
kind | "application" | "appeal" | No | Only applications, or only appeals. |
state | "draft" | "open" | "paused" | "archived" | No | Only forms in this state. |
No request body.
Example
curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/forms" \
-H "Authorization: Bearer $TECHNIFIED_KEY"{
"items": [
{
"id": "frm_01M5TXYKPJRX6P75ZMRW5SFGW4",
"kind": "application",
"title": "Moderator application",
"description": null,
"state": "open",
"version": 1,
"submitAccess": "anyone",
"oneOpenSubmission": true,
"publishOnPublicPage": false,
"appealPunishmentType": null,
"requirePunishment": true,
"scope": "guild",
"createdAt": "2026-10-26T01:42:11.410Z"
}
]
}POST /forms
POST /guilds/{guildId}/forms
| Key permission | forms.write (Decide applications and edit forms) |
Request body
JSON, sent with Content-Type: application/json.
kind: "application"
| Field | Type | Required | What it is |
|---|---|---|---|
title | string | Yes | 1 to 120 characters |
description | string or null | No | at most 2000 characters · default null |
questions | array of objects | Yes | 1 to 100 items |
questions[].id | string | Yes | 1 to 40 characters |
questions[].type | "short_text" | "long_text" | "number" | "single_choice" | "multiple_choice" | "date" | "yes_no" | "file" | "section" | Yes | |
questions[].label | string | Yes | 1 to 200 characters |
questions[].description | string | No | at most 500 characters |
questions[].required | boolean | No | default false |
questions[].options | array of string | No | at most 25 items |
questions[].minLength | integer | No | 0 to 4000 |
questions[].maxLength | integer | No | 1 to 4000 |
questions[].min | number | No | |
questions[].max | number | No | |
questions[].showIf | object | No | |
questions[].showIf.questionId | string | Yes | 1 to 40 characters |
questions[].showIf.equals | object, one of the shapes below | Yes | |
questions[].logic | object | No | |
questions[].logic.match | "all" | "any" | No | default "all" |
questions[].logic.conditions | array of objects | Yes | 1 to 10 items |
questions[].logic.conditions[].questionId | string | Yes | 1 to 40 characters |
questions[].logic.conditions[].is | "equals" | "not_equals" | "includes" | "not_includes" | "at_least" | "at_most" | "contains" | "not_contains" | "answered" | "empty" | Yes | |
questions[].logic.conditions[].value | object, one of the shapes below | No | |
questions[].stop | object | No | |
questions[].stop.is | "equals" | "not_equals" | "includes" | "not_includes" | "at_least" | "at_most" | "contains" | "not_contains" | "answered" | "empty" | Yes | |
questions[].stop.value | object, one of the shapes below | No | |
questions[].stop.message | string | Yes | 1 to 500 characters |
submitAccess | "anyone" | "link" | "verified" | No | default "anyone" |
oneOpenSubmission | boolean | No | default true |
publishOnPublicPage | boolean | No | default false |
kind | "application" | Yes |
kind: "appeal"
| Field | Type | Required | What it is |
|---|---|---|---|
title | string | Yes | 1 to 120 characters |
description | string or null | No | at most 2000 characters · default null |
questions | array of objects | Yes | 1 to 100 items |
questions[].id | string | Yes | 1 to 40 characters |
questions[].type | "short_text" | "long_text" | "number" | "single_choice" | "multiple_choice" | "date" | "yes_no" | "file" | "section" | Yes | |
questions[].label | string | Yes | 1 to 200 characters |
questions[].description | string | No | at most 500 characters |
questions[].required | boolean | No | default false |
questions[].options | array of string | No | at most 25 items |
questions[].minLength | integer | No | 0 to 4000 |
questions[].maxLength | integer | No | 1 to 4000 |
questions[].min | number | No | |
questions[].max | number | No | |
questions[].showIf | object | No | |
questions[].showIf.questionId | string | Yes | 1 to 40 characters |
questions[].showIf.equals | object, one of the shapes below | Yes | |
questions[].logic | object | No | |
questions[].logic.match | "all" | "any" | No | default "all" |
questions[].logic.conditions | array of objects | Yes | 1 to 10 items |
questions[].logic.conditions[].questionId | string | Yes | 1 to 40 characters |
questions[].logic.conditions[].is | "equals" | "not_equals" | "includes" | "not_includes" | "at_least" | "at_most" | "contains" | "not_contains" | "answered" | "empty" | Yes | |
questions[].logic.conditions[].value | object, one of the shapes below | No | |
questions[].stop | object | No | |
questions[].stop.is | "equals" | "not_equals" | "includes" | "not_includes" | "at_least" | "at_most" | "contains" | "not_contains" | "answered" | "empty" | Yes | |
questions[].stop.value | object, one of the shapes below | No | |
questions[].stop.message | string | Yes | 1 to 500 characters |
submitAccess | "anyone" | "link" | "verified" | No | default "anyone" |
oneOpenSubmission | boolean | No | default true |
publishOnPublicPage | boolean | No | default false |
kind | "appeal" | Yes | |
appealPunishmentType | "ban" | "mute" | "warning" | "kick" | "serverban" | Yes | |
requirePunishment | boolean | No | default true |
Example
curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/forms" \
-H "Authorization: Bearer $TECHNIFIED_KEY" \
-H "Content-Type: application/json" \
-d '{"kind":"application","title":"Moderator application","questions":[{"id":"why","type":"long_text","label":"Why do you want to moderate?","required":true},{"id":"age","type":"number","label":"How old are you?","required":true,"min":13}]}'{
"id": "frm_01M5TXYKPJRX6P75ZMRW5SFGW4",
"kind": "application",
"title": "Moderator application",
"description": null,
"state": "draft",
"version": 1,
"submitAccess": "anyone",
"oneOpenSubmission": true,
"publishOnPublicPage": false,
"appealPunishmentType": null,
"requirePunishment": true,
"scope": "guild",
"questions": [
{
"id": "why",
"type": "long_text",
"label": "Why do you want to moderate?",
"required": true
},
{
"id": "age",
"type": "number",
"label": "How old are you?",
"required": true,
"min": 13
}
],
"createdAt": "2026-10-26T01:42:11.410Z"
}GET /forms/{formId}
GET /guilds/{guildId}/forms/{formId}
The form to fill in. This is the one a member loads.
| Key permission | Any key of this server. |
In the address
| Field | Type | Required | What it is |
|---|---|---|---|
formId | string | Yes | A form’s id (frm_…). |
No request body.
Example
curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/forms/FORMID" \
-H "Authorization: Bearer $TECHNIFIED_KEY"PATCH /forms/{formId}
PATCH /guilds/{guildId}/forms/{formId}
Edits a form. Writes a new version rather than changing the old one. An appeal form also takes appealPunishmentType and requirePunishment (422 on an application).
| Key permission | forms.write (Decide applications and edit forms) |
In the address
| Field | Type | Required | What it is |
|---|---|---|---|
formId | string | Yes | A form’s id (frm_…). |
Request body
JSON, sent with Content-Type: application/json.
| Field | Type | Required | What it is |
|---|---|---|---|
title | string | No | 1 to 120 characters |
description | string or null | No | at most 2000 characters |
questions | array of objects | No | 1 to 100 items |
questions[].id | string | Yes | 1 to 40 characters |
questions[].type | "short_text" | "long_text" | "number" | "single_choice" | "multiple_choice" | "date" | "yes_no" | "file" | "section" | Yes | |
questions[].label | string | Yes | 1 to 200 characters |
questions[].description | string | No | at most 500 characters |
questions[].required | boolean | No | default false |
questions[].options | array of string | No | at most 25 items |
questions[].minLength | integer | No | 0 to 4000 |
questions[].maxLength | integer | No | 1 to 4000 |
questions[].min | number | No | |
questions[].max | number | No | |
questions[].showIf | object | No | |
questions[].showIf.questionId | string | Yes | 1 to 40 characters |
questions[].showIf.equals | object, one of the shapes below | Yes | |
questions[].logic | object | No | |
questions[].logic.match | "all" | "any" | No | default "all" |
questions[].logic.conditions | array of objects | Yes | 1 to 10 items |
questions[].logic.conditions[].questionId | string | Yes | 1 to 40 characters |
questions[].logic.conditions[].is | "equals" | "not_equals" | "includes" | "not_includes" | "at_least" | "at_most" | "contains" | "not_contains" | "answered" | "empty" | Yes | |
questions[].logic.conditions[].value | object, one of the shapes below | No | |
questions[].stop | object | No | |
questions[].stop.is | "equals" | "not_equals" | "includes" | "not_includes" | "at_least" | "at_most" | "contains" | "not_contains" | "answered" | "empty" | Yes | |
questions[].stop.value | object, one of the shapes below | No | |
questions[].stop.message | string | Yes | 1 to 500 characters |
submitAccess | "anyone" | "link" | "verified" | No | |
oneOpenSubmission | boolean | No | |
publishOnPublicPage | boolean | No | |
state | "draft" | "open" | "paused" | "archived" | No | |
appealPunishmentType | "ban" | "mute" | "warning" | "kick" | "serverban" | No | |
requirePunishment | boolean | No |
Example
curl -X PATCH "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/forms/FORMID" \
-H "Authorization: Bearer $TECHNIFIED_KEY" \
-H "Content-Type: application/json" \
-d '{}'GET /submissions
GET /guilds/{guildId}/submissions
The queue.
| Key permission | forms.read (See applications and appeals) |
Query parameters
Added to the address after a ?, like ?limit=10&order=asc.
| Field | Type | Required | What it is |
|---|---|---|---|
limit | integer | No | How many to answer with at most, 1 to 100.1 to 100 · default 25 |
cursor | string | No | The nextCursor of the page before, to get the next page. Absent: the first page.at most 64 characters |
order | "asc" | "desc" | No | desc for newest first, asc for oldest first.default "desc" |
formId | string | No | Only submissions to this form.at most 40 characters |
state | "submitted" | "approved" | "declined" | "withdrawn" | No | Only submissions in this state, such as submitted (waiting). |
discordUserId | string | No | Only what this member sent.at most 32 characters |
punishmentId | string | No | Only the appeals against this punishment.at most 40 characters |
kind | "application" | "appeal" | No | Only applications, or only appeals. |
No request body.
Example
curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/submissions" \
-H "Authorization: Bearer $TECHNIFIED_KEY"{
"items": [
{
"id": "sub_01M5TXYKWGTNCFFEXH6CZ433YB",
"formId": "frm_01M5TXYKPJRX6P75ZMRW5SFGW4",
"formVersion": 1,
"guildId": "gld_01M5TXYJPNJZ19BDXJCNTD8WDW",
"discordUserId": "17929789298638349990005",
"state": "submitted",
"answers": {
"why": "I know the rules and I am online every day.",
"age": 17
},
"punishmentId": null,
"decidedBy": null,
"decidedAt": null,
"decisionNote": null,
"notified": false,
"createdAt": "2026-10-26T01:42:11.600Z"
}
],
"nextCursor": null
}GET /submissions/{submissionId}
GET /guilds/{guildId}/submissions/{submissionId}
One submission, with the version of the form it answered, and openTicket ({ id, number } or null): the ticket still open about it.
| Key permission | forms.read (See applications and appeals) |
In the address
| Field | Type | Required | What it is |
|---|---|---|---|
submissionId | string | Yes | A submission’s id (sub_…). |
No request body.
Example
curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/submissions/SUBMISSIONID" \
-H "Authorization: Bearer $TECHNIFIED_KEY"{
"id": "sub_01M5TXYKWGTNCFFEXH6CZ433YB",
"formId": "frm_01M5TXYKPJRX6P75ZMRW5SFGW4",
"formVersion": 1,
"guildId": "gld_01M5TXYJPNJZ19BDXJCNTD8WDW",
"discordUserId": "17929789298638349990005",
"state": "submitted",
"answers": {
"why": "I know the rules and I am online every day.",
"age": 17
},
"punishmentId": null,
"decidedBy": null,
"decidedAt": null,
"decisionNote": null,
"notified": false,
"createdAt": "2026-10-26T01:42:11.600Z",
"questions": [
{
"id": "why",
"type": "long_text",
"label": "Why do you want to moderate?",
"required": true
},
{
"id": "age",
"type": "number",
"label": "How old are you?",
"required": true,
"min": 13
}
],
"openTicket": null
}GET /submissions/{submissionId}/comments
GET /guilds/{guildId}/submissions/{submissionId}/comments
| Key permission | forms.read (See applications and appeals) |
In the address
| Field | Type | Required | What it is |
|---|---|---|---|
submissionId | string | Yes | A submission’s id (sub_…). |
No request body.
Example
curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/submissions/SUBMISSIONID/comments" \
-H "Authorization: Bearer $TECHNIFIED_KEY"POST /submissions/{submissionId}/comments
POST /guilds/{guildId}/submissions/{submissionId}/comments
| Key permission | forms.write (Decide applications and edit forms) |
In the address
| Field | Type | Required | What it is |
|---|---|---|---|
submissionId | string | Yes | A submission’s id (sub_…). |
Request body
JSON, sent with Content-Type: application/json.
| Field | Type | Required | What it is |
|---|---|---|---|
body | string | Yes | The note. Only staff see it, never the person.1 to 2000 characters |
Example
curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/submissions/SUBMISSIONID/comments" \
-H "Authorization: Bearer $TECHNIFIED_KEY" \
-H "Content-Type: application/json" \
-d '{"body":"…"}'POST /submissions/{submissionId}/decide
POST /guilds/{guildId}/submissions/{submissionId}/decide
Approves or declines, and can lift the punishment an appeal is about.
| Key permission | forms.write (Decide applications and edit forms) |
In the address
| Field | Type | Required | What it is |
|---|---|---|---|
submissionId | string | Yes | A submission’s id (sub_…). |
Request body
JSON, sent with Content-Type: application/json.
| Field | Type | Required | What it is |
|---|---|---|---|
decision | "approved" | "declined" | Yes | approved or declined. Final. |
note | string or null | No | A word to the person, sent in the direct message with the decision.at most 2000 characters · default null |
liftPunishment | boolean | No | Appeals only: true lifts the punishment the appeal is about, in the same step.default false |
Example
curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/submissions/SUBMISSIONID/decide" \
-H "Authorization: Bearer $TECHNIFIED_KEY" \
-H "Content-Type: application/json" \
-d '{"decision":"approved","note":"Welcome to the team!"}'{
"id": "sub_01M5TXYKWGTNCFFEXH6CZ433YB",
"formId": "frm_01M5TXYKPJRX6P75ZMRW5SFGW4",
"formVersion": 1,
"guildId": "gld_01M5TXYJPNJZ19BDXJCNTD8WDW",
"discordUserId": "17929789298638349990005",
"state": "approved",
"answers": {
"why": "I know the rules and I am online every day.",
"age": 17
},
"punishmentId": null,
"decidedBy": "key_01M5TXYJPZQGNT2KXZG3ZBA672",
"decidedAt": "2026-10-26T01:42:11.722Z",
"decisionNote": "Welcome to the team!",
"notified": false,
"createdAt": "2026-10-26T01:42:11.600Z",
"punishmentLifted": false
}POST /submissions/{submissionId}/ticket
POST /guilds/{guildId}/submissions/{submissionId}/ticket
Continues a submission as a ticket. 409 ticket_open while one is still open about it.
| Key permission | forms.write (Decide applications and edit forms), tickets.write (Handle tickets) |
In the address
| Field | Type | Required | What it is |
|---|---|---|---|
submissionId | string | Yes | A submission’s id (sub_…). |
Request body
JSON, sent with Content-Type: application/json.
| Field | Type | Required | What it is |
|---|---|---|---|
panelId | string | No | at most 40 characters |
Example
curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/submissions/SUBMISSIONID/ticket" \
-H "Authorization: Bearer $TECHNIFIED_KEY" \
-H "Content-Type: application/json" \
-d '{}'GET /submissions/uploads/{uploadId}
GET /guilds/{guildId}/submissions/uploads/{uploadId}
A file somebody attached.
| Key permission | forms.read (See applications and appeals) |
In the address
| Field | Type | Required | What it is |
|---|---|---|---|
uploadId | string | Yes | A file uploaded with a form (upl_…), from the submission’s answers. |
No request body.
Example
curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/submissions/uploads/UPLOADID" \
-H "Authorization: Bearer $TECHNIFIED_KEY"Still stuck? Get help from the Technified team.