Reference: Staff

Your staff team: roles, hours, leave, quotas, notes, strikes and performance.

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 /staff

GET /guilds/{guildId}/staff

Who the staff are.

Key permissionstaff.read (See staff)

No request body.

Example

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

GET /staff/activity

GET /guilds/{guildId}/staff/activity

Hours worked, by member and period.

Key permissionstaff.read (See staff)

Query parameters

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

FieldTypeRequiredWhat it is
daysintegerNoHow many days back to count, 1 to 365.1 to 365 · default 30
discordUserIdstringNoOnly this staff member (Discord user id).digits only
limitintegerNoHow many people to answer with at most, 1 to 100.1 to 100 · default 25
includeInactive"true" | "false"Nofalse to leave out staff with no hours in the period.default "true"

No request body.

Example

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

GET /staff/activity/leaderboard

GET /guilds/{guildId}/staff/activity/leaderboard

The same, ranked.

Key permissionstaff.read (See staff)

Query parameters

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

FieldTypeRequiredWhat it is
daysintegerNoHow many days back to count, 1 to 365.1 to 365 · default 30
discordUserIdstringNoOnly this staff member (Discord user id).digits only
limitintegerNoHow many people to answer with at most, 1 to 100.1 to 100 · default 25
includeInactive"true" | "false"Nofalse to leave out staff with no hours in the period.default "true"

No request body.

Example

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

POST /staff/activity/sessions/manual

POST /guilds/{guildId}/staff/activity/sessions/manual

Time worked away from a game, entered by hand and attributed to whoever entered it.

Key permissionstaff.write (Write notes and strikes)

Request body

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

FieldTypeRequiredWhat it is
discordUserIdstringYesThe staff member who worked (Discord user id).digits only
startedAtstringYesWhen the work started (ISO 8601).ISO 8601 date and time
endedAtstringYesWhen it ended (ISO 8601).ISO 8601 date and time
universeIdstringNoThe game it counts for, if any (Roblox universe id).1 to 32 characters · digits only

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/activity/sessions/manual" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"discordUserId":"123456789012345678","startedAt":"2026-11-01T18:00:00.000Z","endedAt":"2026-11-01T18:00:00.000Z"}'

POST /staff/leave/{leaveId}/decide

POST /guilds/{guildId}/staff/leave/{leaveId}/decide

Approves or declines.

Key permissionstaff.manage (Manage staff roles, leave and quotas)

In the address

FieldTypeRequiredWhat it is
leaveIdstringYesA leave request’s id (lve_…).

Request body

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

FieldTypeRequiredWhat it is
decision"approved" | "declined"Yesapproved or declined.
notestring or nullNoA word to the staff member, sent with the answer.at most 1000 characters · default null

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/leave/LEAVEID/decide" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"decision":"approved"}'

GET /staff/members/{discordUserId}

GET /guilds/{guildId}/staff/members/{discordUserId}

One staff member: their roles, records, hours and quota.

Key permissionstaff.read (See staff)

In the address

FieldTypeRequiredWhat it is
discordUserIdstringYesA Discord user id (digits).

No request body.

Example

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

GET /staff/members/{discordUserId}/summary

GET /guilds/{guildId}/staff/members/{discordUserId}/summary

Only whether somebody is staff, and their roles and rank. member is null for somebody who is not. Reads one member, for a badge.

Key permissionstaff.read (See staff)

In the address

FieldTypeRequiredWhat it is
discordUserIdstringYesA Discord user id (digits).

No request body.

Example

curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/members/DISCORDUSERID/summary" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"
Answer · 200
{
  "member": {
    "discordUserId": "17929789298638349990004",
    "userId": "usr_01M5TXYJQQ1CB83Q7KH3V40MR7",
    "nickname": null,
    "isAdministrator": false,
    "rank": 200,
    "roles": [
      {
        "id": "str_01M5TXYJQJSKT8MH128K65JPTZ",
        "name": "Moderator",
        "rank": 200
      }
    ]
  }
}

GET /staff/performance

GET /guilds/{guildId}/staff/performance

The score, with the counts beside it.

Key permissionstaff.read (See staff)

Query parameters

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

FieldTypeRequiredWhat it is
daysintegerNo1 to 365 · default 30
discordUserIdstringNodigits only
limitintegerNo1 to 100 · default 25
includeInactive"true" | "false"Nodefault "true"

No request body.

Example

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

GET /staff/performance/weights

GET /guilds/{guildId}/staff/performance/weights

Key permissionstaff.read (See staff)

No request body.

Example

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

PUT /staff/performance/weights

PUT /guilds/{guildId}/staff/performance/weights

Key permissionstaff.manage (Manage staff roles, leave and quotas)

Request body

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

FieldTypeRequiredWhat it is
perTicketnumberYes-100 to 100
perModerationActionnumberYes-100 to 100
perHourActivenumberYes-100 to 100
perApplicationReviewednumberYes-100 to 100
perStrikenumberYes-100 to 100

Example

curl -X PUT "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/performance/weights" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"perTicket":-100,"perModerationAction":-100,"perHourActive":-100,"perApplicationReviewed":-100,"perStrike":-100}'

GET /staff/quotas

GET /guilds/{guildId}/staff/quotas

Key permissionstaff.read (See staff)

No request body.

Example

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

POST /staff/quotas

POST /guilds/{guildId}/staff/quotas

Key permissionstaff.manage (Manage staff roles, leave and quotas)

Request body

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

FieldTypeRequiredWhat it is
namestringYes1 to 60 characters
requiredHoursnumberYes0.016666666666666666 to 1000
periodDaysintegerYes1 to 90
staffRoleIdsarray of stringNoat most 25 items · default []
universeIdsarray of string or nullNoat most 25 items · default null
onMissed"strike" | "notify" | "review"Nodefault "notify"
strikeSeverity"low" | "medium" | "high"Nodefault "low"
enabledbooleanNodefault true

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/quotas" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"…","requiredHours":0.016666666666666666,"periodDays":1}'

PATCH /staff/quotas/{quotaId}

PATCH /guilds/{guildId}/staff/quotas/{quotaId}

Key permissionstaff.manage (Manage staff roles, leave and quotas)

In the address

FieldTypeRequiredWhat it is
quotaIdstringYesA quota’s id (qta_…).

Request body

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

FieldTypeRequiredWhat it is
namestringNo1 to 60 characters
requiredHoursnumberNo0.016666666666666666 to 1000
periodDaysintegerNo1 to 90
staffRoleIdsarray of stringNoat most 25 items · default []
universeIdsarray of string or nullNoat most 25 items · default null
onMissed"strike" | "notify" | "review"Nodefault "notify"
strikeSeverity"low" | "medium" | "high"Nodefault "low"
enabledbooleanNodefault true

Example

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

DELETE /staff/quotas/{quotaId}

DELETE /guilds/{guildId}/staff/quotas/{quotaId}

Key permissionstaff.manage (Manage staff roles, leave and quotas)

In the address

FieldTypeRequiredWhat it is
quotaIdstringYesA quota’s id (qta_…).

No request body.

Example

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

GET /staff/quotas/progress

GET /guilds/{guildId}/staff/quotas/progress

How the caller is doing against their own quota.

Key permissionAny key of this server.

Query parameters

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

FieldTypeRequiredWhat it is
discordUserIdstringNoat most 32 characters

No request body.

Example

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

GET /staff/quotas/results

GET /guilds/{guildId}/staff/quotas/results

Finished periods and who met them.

Key permissionstaff.read (See staff)

Query parameters

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

FieldTypeRequiredWhat it is
reviewState"pending" | "approved" | "dismissed"No
discordUserIdstringNodigits only
met"true" | "false"No
cursorstringNoat most 40 characters
limitintegerNo1 to 100 · default 50

No request body.

Example

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

POST /staff/quotas/results/{resultId}/review

POST /guilds/{guildId}/staff/quotas/results/{resultId}/review

Excuses or confirms a missed period.

Key permissionstaff.manage (Manage staff roles, leave and quotas)

In the address

FieldTypeRequiredWhat it is
resultIdstringYesA quota result’s id (qtr_…).

Request body

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

FieldTypeRequiredWhat it is
decision"approve" | "dismiss"Yes

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/quotas/results/RESULTID/review" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"decision":"approve"}'

GET /staff/records

GET /guilds/{guildId}/staff/records

Key permissionstaff.read (See staff)

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"
kind"strike" | "note"Nostrike or note.
state"active" | "expired" | "revoked"NoOnly records in this state.
discordUserIdstringNoOnly records about this staff member.digits only

No request body.

Example

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

POST /staff/records

POST /guilds/{guildId}/staff/records

Key permissionstaff.write (Write notes and strikes)

Request body

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

kind decides whether it is a strike or a note.

kind: "strike" · A strike: a formal warning for staff.

FieldTypeRequiredWhat it is
kind"strike"Yes
subjectDiscordUserIdstringYesThe staff member it is about (Discord user id).digits only
reasonstringYesWhat happened. The staff member sees it.1 to 2000 characters
evidencestring or nullNoLinks or words backing it up.at most 4000 characters · default null
severity"low" | "medium" | "high"Nolow, medium or high.default "low"
expiresInDaysinteger or nullNoDays until it stops counting, or null to count until it is withdrawn.1 to 3650 · default null
actorobjectNoThe person who used your tool, credited in the record.
actor.labelstringNoTheir name, shown in the record.1 to 100 characters
actor.robloxUserIdstringNoTheir Roblox user id.1 to 32 characters · digits only
actor.discordUserIdstringNoTheir Discord user id.digits only

kind: "note" · A note: something to remember about a staff member.

FieldTypeRequiredWhat it is
kind"note"Yes
subjectDiscordUserIdstringYesThe staff member it is about (Discord user id).digits only
reasonstringYesWhat happened. The staff member sees it.1 to 2000 characters
evidencestring or nullNoLinks or words backing it up.at most 4000 characters · default null
importantbooleanNoMarks it so it stands out.default false
actorobjectNoThe person who used your tool, credited in the record.
actor.labelstringNoTheir name, shown in the record.1 to 100 characters
actor.robloxUserIdstringNoTheir Roblox user id.1 to 32 characters · digits only
actor.discordUserIdstringNoTheir Discord user id.digits only

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/records" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kind":"strike","subjectDiscordUserId":"123456789012345678","reason":"…"}'

PATCH /staff/records/{recordId}

PATCH /guilds/{guildId}/staff/records/{recordId}

Amends one.

Key permissionstaff.write (Write notes and strikes)

In the address

FieldTypeRequiredWhat it is
recordIdstringYesA note’s or strike’s id (rec_…).

Request body

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

FieldTypeRequiredWhat it is
reasonstringNo1 to 2000 characters
evidencestring or nullNoat most 4000 characters
severity"low" | "medium" | "high"No
importantbooleanNo

Example

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

POST /staff/records/{recordId}/revoke

POST /guilds/{guildId}/staff/records/{recordId}/revoke

Withdraws one. The record stays and says it was withdrawn.

Key permissionstaff.write (Write notes and strikes)

In the address

FieldTypeRequiredWhat it is
recordIdstringYesA note’s or strike’s id (rec_…).

Request body

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

FieldTypeRequiredWhat it is
reasonstringYesWhy it is withdrawn.1 to 1000 characters

Example

curl -X POST "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/records/RECORDID/revoke" \
  -H "Authorization: Bearer $TECHNIFIED_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason":"…"}'

POST /staff/refresh

POST /guilds/{guildId}/staff/refresh

Reads the member list again now, rather than when it is next due.

Key permissionstaff.read (See staff)

No request body.

Example

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

GET /staff/roles

GET /guilds/{guildId}/staff/roles

The staff roles and what each may do. A role with scope: "organization" applies on every server of the organization.

Key permissionstaff.read (See staff)

No request body.

Example

curl -X GET "https://api.technified.xyz/v1/guilds/YOUR_SERVER_ID/staff/roles" \
  -H "Authorization: Bearer $TECHNIFIED_KEY"
Answer · 200
{
  "items": [
    {
      "id": "str_01M5TXYJQJSKT8MH128K65JPTZ",
      "name": "Moderator",
      "rank": 200,
      "permissions": [
        "moderation.read",
        "moderation.write",
        "tickets.read",
        "tickets.write"
      ],
      "matchType": "discord_role",
      "discordRoleId": "17929789298638349990003",
      "robloxGroupId": null,
      "robloxMinRank": null,
      "robloxMaxRank": null,
      "robloxRoleId": null,
      "robloxRoleName": null,
      "scope": "guild"
    }
  ]
}

Still stuck? Get help from the Technified team.