CEEJAYDocs

List the quests

List the community's quests, with how far the connected player has come in each.

GET /v1/player/quests · for player session

Use it to show the quests the member sees in Discord, with the player's progress, in the game. Send the player session as the bearer token. The request needs the game loop. For the three conditions (game loop enabled for the game, member consent, server membership) and the error each returns, see What has to be true first.

Query parameters

Prop

Type

Returns

data is a list of quests, in the community's order. The response also includes page, with nextCursor and limit.

Prop

Type

Each task in tasks contains:

Prop

Type

answer contains the question and its limits. One object covers the three kinds, distinguished by kind; a key that does not apply to the kind is omitted:

Prop

Type

What the game does with a task

Each task says what the game can do with it in action:

actionWhat the game shows
verifyA button that calls Verify a quest task
answerA text or number field that calls Answer a quest task
rateA rating from 1 to answer.scale that calls Answer a quest task
discordNo action in the game: the task must be completed in Discord. Show that and offer nothing else
nullNo action in the game: the task completes automatically from what the member does in the server

A task that the community's team reviews is always discord, even when it asks for text or a number. A game never submits anything for review, and no direct message is ever sent for anything a game starts.

Quests that are locked

A quest that requires a level is evaluated from the member's stored XP, so the level is always known. A quest that requires a role is evaluated from CEEJAY's cache of the server's members. For a member who is not in the cache, locked is null and lockCheck is checked_on_start. Show the quest as startable and let Start a quest decide. A quest is never shown as locked for a member who is simply missing from the cache.

Paging

Pass page.nextCursor as cursor and stop when it is null. A quest added or removed between two pages can cause a repeat or a skipped quest, so key the list by the quest's id.

Example

Request
curl "https://ceejay.communitystudios.xyz/api/v1/player/quests?limit=20" \
  -H "Authorization: Bearer $CEEJAY_PLAYER_SESSION"

The TypeScript example uses connect.hub.listQuests from the Connect client in the TypeScript SDK. The player must be connected first: the client manages and refreshes the player session. It returns the full response below, with the list in data.

200 OK
{
  "success": true,
  "data": [
    {
      "id": 12,
      "title": "First steps",
      "iconEmoji": "🏆",
      "description": "Get started in the community.",
      "category": "Onboarding",
      "xpReward": 100,
      "currencyReward": 50,
      "badge": "Newcomer",
      "endsAt": "2026-11-01T00:00:00.000Z",
      "status": "in_progress",
      "progress": {
        "current": 1,
        "target": 5
      },
      "locked": false,
      "lockedReason": null,
      "lockCheck": "known",
      "taskCount": 5,
      "tasksDone": 1,
      "tasks": [
        {
          "id": 41,
          "position": 0,
          "type": "send_messages",
          "title": "Say hello",
          "description": null,
          "verification": "automatic",
          "status": "in_progress",
          "progress": {
            "current": 4,
            "target": 10
          },
          "url": null,
          "action": null,
          "answer": null,
          "statusLine": "4/10 messages"
        },
        {
          "id": 42,
          "position": 1,
          "type": "text_answer",
          "title": "Tell us your favourite",
          "description": "One sentence is enough.",
          "verification": "automatic",
          "status": "available",
          "progress": null,
          "url": null,
          "action": "answer",
          "answer": {
            "kind": "text",
            "question": "What is your favourite game?",
            "minLength": 10
          },
          "statusLine": null
        },
        {
          "id": 43,
          "position": 2,
          "type": "number_answer",
          "title": "Hours a week",
          "description": null,
          "verification": "automatic",
          "status": "available",
          "progress": null,
          "url": null,
          "action": "answer",
          "answer": {
            "kind": "number",
            "question": "How many hours a week do you play?",
            "min": 0,
            "max": 168
          },
          "statusLine": null
        },
        {
          "id": 44,
          "position": 3,
          "type": "rating",
          "title": "Rate the last event",
          "description": null,
          "verification": "automatic",
          "status": "available",
          "progress": null,
          "url": null,
          "action": "rate",
          "answer": {
            "kind": "scale",
            "question": "How was the last event?",
            "scale": 5
          },
          "statusLine": null
        },
        {
          "id": 45,
          "position": 4,
          "type": "social_follow",
          "title": "Follow the studio",
          "description": null,
          "verification": "automatic",
          "status": "available",
          "progress": null,
          "url": "https://social.example/rugby",
          "action": "verify",
          "answer": null,
          "statusLine": null
        }
      ]
    }
  ],
  "page": {
    "nextCursor": null,
    "limit": 50
  }
}

Limits

120 reads a minute for one player session. The three X-RateLimit headers report that count. Every request made with a player session also counts toward 140 a minute. See Rate limits. Over a limit the response is 429 with the code rate_limited, retryAfter and a Retry-After header.

Errors

StatuscodeerrorWhen
400bad_requestlimit must be a whole number from 1 to 100limit is above 100, negative, a fraction or text
400bad_requestcursor is not one this list gave. Send page.nextCursor as it was answeredcursor was not issued by this list
401connection_endedThis connection has endedThe connection or this device was ended since the player session was made. Discard the stored tokens and show the player as disconnected. See Renew a player session for the reasons
409hub_not_enabledThis game does not show the community's quests, shop and rankThe game loop is disabled for the game. Do not show the community's quests, shop or rank in the game
409sharing_neededThe member has not consented to sharing their data with this gameThe member has not consented to share their quests, rewards, shop and rank with the game, or must consent again. The body includes manageUrl: send the player there
409membership_requiredThe member has to be in the server to use thisThe Discord account is not in the server. The body includes membership (pending, left or not_member) and, for left and not_member, joinUrl, the URL to send the player to
503bot_unavailableThis could not be done right now and nothing was changed. Try again in a few secondsCEEJAY's bot could not be reached or was too busy, and nothing was changed. The body includes retryAfter, in seconds: retry after that many seconds
504bot_timeoutThe answer did not arrive in time, and the request may or may not have been done. Send the same request again: it is safe to repeatThe request timed out, so it is not known whether it was processed. Retry the same request: it is safe to repeat

Every error body also includes requestId, and a 400 with the code bad_request identifies the invalid field in field. Match on code; message text can change.

The errors every request of a game shares (the key, the state of the game, the origin, 405, 429, 500) are on the Errors page, and the errors specific to the game loop are under Codes of the game loop.

On this page

Community StudiosPrivacyTerms