Skip to content
API documentation
View as MarkdownOpen in Claude

Group challenges

Send a group’s finished work for one of your students

POST
/v1/{organizationId}/group-challenge/{challengeId}/group/{groupId}/final-submit

Sends a group’s finished work, once every step is submitted, for one of your students who is a member of the group, exactly as the student would in the panel. The group becomes completed. Read the group first: canFinalSubmit says whether this would be accepted now.

The body names the student you act for: { "studentId": "<studentId>" }. The group’s history records the submit as your account (partner) acting for them.

Checks, in order. The first that fails decides the answer, and nothing is written for any of them.

  1. The student is yours (404), and has signed in to this organization once (409).
  2. The challenge exists and is published or closed (404).
  3. The group belongs to the challenge and the student is an active member of it (404).
  4. The work has not been sent already. If it has, the answer is 200 with changed: false and "Group work already submitted.", and nothing changes, so a retry after a timeout is safe.
  5. The challenge is published (409, challenge_closed) and now is between windowStart and windowEnd (409, window_closed).
  6. The teacher has confirmed the group (409, payment_pending or group_not_confirmed).
  7. Every step is submitted (409, steps_incomplete, with stepsSubmitted and stepCount in details).

Every 409 carries error.details.reason; branch on it, not on the message.

Side effects. The group becomes completed, and an entry is added to its history. Every member of the group and its teacher receive an e-mail saying the group has sent its work.

Busy. As for submitGroupChallengeStep: 503 with Retry-After: 1 and details.reason: busy when someone is changing the group at that moment; nothing was written, so send it again.

Parameters

Path parameters

NameTypeDescription
organizationIdrequiredstringpattern ^[0-9a-f]{24}$

The organization’s _id: 24 hexadecimal digits, as listOrganizations (GET /v1/organization) lists it.

Example 64b7f0c2a1d3e4f5a6b7c8d9

challengeIdrequiredstring

The group challenge’s _id, from listGroupChallenges.

groupIdrequiredstring

The group’s _id, from listGroupChallengeGroups or a student’s group.

Request body

application/jsonrequired

  • studentIdstringrequired

    The student the submit is made for: their _id, as registerStudent returned it. They must be one of your students and an active member of the group; the group’s log records the submit as your account acting for them.

    example6650a1b2c3d4e5f6a7b8c9d0

Responses

200 OK

Success: message is "Group work submitted.".

Or message is "Group work already submitted.": The work had already been sent, by anyone. changed is false and nothing changed.

Body

  • successbooleanrequired

    Always true on a success.

    one oftrue

  • messagestringrequired

    exampleGroup work submitted.

  • dataobject · GroupChallengeWorkSubmitResponserequired

    A group’s work sent for one of your students.

    4 fields of data
    • groupIdstringrequired

      The group’s id.

      example6650a1b2c3d4e5f6a7b8c9ed

    • groupStatusstringrequired

      The group’s state now: completed.

      one ofawaiting_paymentdraftfinalizedcompleted

      examplecompleted

    • finalSubmittedAtstringnullablerequired

      When the work was sent: now, or the first time on a repeat.

      formatdate-timeexample2026-10-20T16:02:11.000Z

    • changedbooleanrequired

      true when this request sent the work; false when it had already been sent, and nothing changed.

      exampletrue

Headers

X-RateLimit-Limit integer

Requests your account may make to this operation per window (100).

X-RateLimit-Remaining integer

Requests left in the current window.

X-RateLimit-Reset integer

Seconds until the current window ends.

Example

{
  "data": {
    "changed": true,
    "finalSubmittedAt": "2026-10-20T16:02:11.000Z",
    "groupId": "6650a1b2c3d4e5f6a7b8c9ed",
    "groupStatus": "completed"
  },
  "message": "Group work submitted.",
  "success": true
}

Example request

# $TOKEN: a short-lived token you minted with your API key and secret
curl -sS -X POST 'https://api.main-team.org/v1/<organizationId>/group-challenge/<challengeId>/group/<groupId>/final-submit' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  --data-binary @- <<'JSON'
{
  "studentId": "6650a1b2c3d4e5f6a7b8c9d0"
}
JSON

Search the API documentation

Guides, endpoints by name, path or permission, and error codes such as not_found.