Skip to main content

Player Support

All operations use an allowed documentId and require Authorization: Bearer <sessionId>. Internal processing and Omnidesk share the same public contract.

Support portal​

QuerydocumentId: playerSupportPortalauth: Bearer session

playerSupportPortal​

Returns published form rules, categories, the selected processing provider, and the player's current write access.

Input​

This operation has no variables.

Result: PlayerSupportPortal!

Request
documentId: playerSupportPortal
{
"documentId": "playerSupportPortal",
"variables": {}
}
Response
200 OK
{
"data": {
"playerSupportPortal": {
"enabled": true,
"provider": "INTERNAL",
"minimumTitleLength": 5,
"maximumTitleLength": 160,
"minimumMessageLength": 10,
"maximumMessageLength": 5000,
"attachmentsEnabled": true,
"maxFileSizeMb": 10,
"maxFiles": 5,
"maxTotalSizeMb": 25,
"allowedMimeTypes": [
"image/jpeg",
"image/png",
"image/webp"
],
"writeAccess": {
"allowed": true,
"reason": null,
"expiresAt": null
},
"categories": [
{
"id": "1",
"name": "Payments",
"icon": "ti ti-credit-card"
},
{
"id": "2",
"name": "Game account",
"icon": "ti ti-user"
}
]
}
}
}

Ticket list​

QuerydocumentId: playerSupportTicketsauth: Bearer session

playerSupportTickets​

Returns the current player's tickets and an independent summary. Pass a pageInfo cursor to continue.

Input​

FieldTypeRequiredDescription
cursorString-Cursor for the next or previous slice.
limitInt-Slice size; defaults to 20.

Result: PlayerSupportTicketConnection! and PlayerSupportTicketSummary!

Request
documentId: playerSupportTickets
{
"documentId": "playerSupportTickets",
"variables": {
"cursor": null,
"limit": 20
}
}
Response
200 OK
{
"data": {
"playerSupportTickets": {
"items": [
{
"id": "1042",
"title": "Payment completed but balance did not change",
"categoryId": 1,
"status": "WAITING_FOR_STAFF",
"messagesCount": 1,
"unreadCount": 0,
"lastMessage": "I attached the receipt.",
"createdAt": "2026-08-08T10:24:15Z",
"updatedAt": "2026-08-08T10:24:15Z"
}
],
"pageInfo": {
"nextCursor": "eyJpZCI6MTA0Mn0",
"previousCursor": null,
"hasMore": true
}
},
"playerSupportTicketSummary": {
"all": 3,
"waitingForPlayer": 1,
"waitingForStaff": 1,
"closed": 1
}
}
}

Ticket and messages​

QuerydocumentId: playerSupportTicketauth: Bearer session

playerSupportTicket​

Returns one of the current player's tickets and its cursor-based message history.

Input​

FieldTypeRequiredDescription
ticketIdID!✓Ticket ID.
cursorString-Message history cursor.
limitInt-Slice size; defaults to 50.

Result: PlayerSupportTicket or null

Request
documentId: playerSupportTicket
{
"documentId": "playerSupportTicket",
"variables": {
"ticketId": "1042",
"cursor": null,
"limit": 50
}
}
Response
200 OK
{
"data": {
"playerSupportTicket": {
"id": "1042",
"title": "Payment completed but balance did not change",
"categoryId": 1,
"status": "WAITING_FOR_PLAYER",
"messages": {
"items": [
{
"id": "9101",
"content": "We verified the payment and updated the balance.",
"author": "STAFF",
"authorLabel": "Support team",
"redacted": false,
"deliveryState": "DELIVERED",
"feedback": null,
"feedbackAllowed": true,
"attachments": [
{
"url": "https://project.example/support/attachments/9101/original?token=short-lived",
"thumbnailUrl": "https://project.example/support/attachments/9101/thumbnail?token=short-lived"
}
],
"createdAt": "2026-08-08T11:02:41Z"
}
],
"pageInfo": {
"nextCursor": null,
"previousCursor": null,
"hasMore": false
}
},
"messagesCount": 2,
"unreadCount": 1,
"lastMessage": "We verified the payment and updated the balance.",
"createdAt": "2026-08-08T10:24:15Z",
"updatedAt": "2026-08-08T11:02:41Z"
}
}
}

Ticket access check​

QuerydocumentId: playerSupportTicketAccessauth: Bearer session

playerSupportTicketAccess​

Checks whether the current session can read a ticket before a protected resource is served.

Input​

FieldTypeRequiredDescription
ticketIdID!✓Ticket ID.

Result: Boolean!

Request
documentId: playerSupportTicketAccess
{
"documentId": "playerSupportTicketAccess",
"variables": {
"ticketId": "1042"
}
}
Response
200 OK
{
"data": {
"playerSupportTicketAccess": true
}
}

Message access check​

QuerydocumentId: playerSupportMessageAccessauth: Bearer session

playerSupportMessageAccess​

Checks access to a message before opening one of its attachments.

Input​

FieldTypeRequiredDescription
messageIdID!✓Message ID.

Result: Boolean!

Request
documentId: playerSupportMessageAccess
{
"documentId": "playerSupportMessageAccess",
"variables": {
"messageId": "9101"
}
}
Response
200 OK
{
"data": {
"playerSupportMessageAccess": true
}
}

Create a ticket​

MutationdocumentId: createPlayerSupportTicketauth: Bearer session

createPlayerSupportTicket​

Idempotently creates a ticket and its first message. A new user action gets a new requestId; a safe retry of the same request reuses it.

Input​

FieldTypeRequiredDescription
input.requestIdID!✓Unique attempt ID.
input.categoryIdInt!✓Published category ID.
input.titleString!✓Title within portal limits.
input.messageString!✓Initial message.
input.accountString-Game account.
input.characterString-Character.
input.attachmentClaimPlayerSupportAttachmentClaimInput-ID and credential of a previously uploaded file claim.

Result: PlayerSupportMutationResult!

Request
documentId: createPlayerSupportTicket
{
"documentId": "createPlayerSupportTicket",
"variables": {
"input": {
"requestId": "3a124288-6ced-4a58-9956-7ed994c419a7",
"categoryId": 1,
"title": "Payment completed but balance did not change",
"message": "I attached the receipt and transaction number.",
"account": "demo_account",
"character": "Aster",
"attachmentClaim": {
"id": "01J4Q6N8WQ4G4Q5S8YQJ6R7M2D",
"credential": "claim-capability"
}
}
}
}
Response
200 OK
{
"data": {
"createPlayerSupportTicket": {
"message": "Ticket created.",
"ticketId": "1042",
"messageId": "9100",
"deliveryPending": false
}
}
}

Reply to a ticket​

MutationdocumentId: replyPlayerSupportTicketauth: Bearer session

replyPlayerSupportTicket​

Idempotently appends a player message to an accessible, open ticket.

Input​

FieldTypeRequiredDescription
input.requestIdID!✓Unique attempt ID.
input.ticketIdID!✓Current player's ticket ID.
input.messageString!✓Reply text.
input.attachmentClaimPlayerSupportAttachmentClaimInput-Optional claim for uploaded files.

Result: PlayerSupportMutationResult!

Request
documentId: replyPlayerSupportTicket
{
"documentId": "replyPlayerSupportTicket",
"variables": {
"input": {
"requestId": "e8c00d5d-f727-4b7c-96a4-413bd8d6207c",
"ticketId": "1042",
"message": "The balance is updated, thank you.",
"attachmentClaim": null
}
}
}
Response
200 OK
{
"data": {
"replyPlayerSupportTicket": {
"message": "Reply sent.",
"ticketId": "1042",
"messageId": "9102",
"deliveryPending": false
}
}
}

Rate a staff response​

MutationdocumentId: ratePlayerSupportMessageauth: Bearer session

ratePlayerSupportMessage​

Stores feedback for one staff response in the current player's ticket. Only a delivered, non-redacted staff response can be rated. Repeating the same selection creates no duplicate, while choosing the other option replaces the previous value.

Input​

FieldTypeRequiredDescription
input.messageIdID!✓Accessible staff-message ID.
input.feedbackPlayerSupportMessageFeedback!✓HELPFUL or NOT_HELPFUL.

Result: PlayerSupportMessageFeedbackResult!

Request
documentId: ratePlayerSupportMessage
{
"documentId": "ratePlayerSupportMessage",
"variables": {
"input": {
"messageId": "9101",
"feedback": "HELPFUL"
}
}
}
Response
200 OK
{
"data": {
"ratePlayerSupportMessage": {
"messageId": "9101",
"feedback": "HELPFUL"
}
}
}

Public errors​

Errors use extensions.category = support and a client-safe extensions.code.

CodeMeaning
SUPPORT_DISABLEDThe feature is disabled for the project
BANNEDThe player cannot create tickets or replies
RATE_LIMITEDThe configured cooldown has not elapsed
INVALID_CATEGORYThe category is disabled or missing
TITLE_LENGTH / MESSAGE_LENGTHPublished content limits were violated
TICKET_NOT_FOUNDThe ticket is missing or inaccessible
TICKET_CLOSED / TICKET_BANNEDReplies are blocked for this ticket
MESSAGE_NOT_FOUNDThe message is missing or inaccessible
FEEDBACK_NOT_ALLOWEDThis message cannot be rated
INVALID_ATTACHMENT_CLAIMThe file claim is invalid or belongs to another session
ATTACHMENTS_DISABLED / TOO_MANY_ATTACHMENTSAttachments violate portal rules
ATTACHMENT_SERVICE_UNAVAILABLEAttachment storage is temporarily unavailable
REQUEST_CONFLICTAn idempotency ID was reused with different content
SENSITIVE_CONTENTThe content policy rejected the message
Invalid request
documentId: createPlayerSupportTicket
{
"documentId": "createPlayerSupportTicket",
"variables": {
"input": {
"requestId": "3a124288-6ced-4a58-9956-7ed994c419a7",
"categoryId": 1,
"title": "No",
"message": "Too short"
}
}
}
Error
200 OK
{
"errors": [
{
"message": "The title must contain between 5 and 160 characters.",
"extensions": {
"code": "TITLE_LENGTH",
"category": "support"
}
}
],
"data": {
"createPlayerSupportTicket": null
}
}