---
title: "List group invitations"
method: GET
path: "/api/v1/groups/invitations/{id}/"
tags: ["Group Members"]
---

# List group invitations

`GET /api/v1/groups/invitations/{id}/`

## Request

- Base URL: `https://plagiarismcheck.org`
- URL: `https://plagiarismcheck.org/api/v1/groups/invitations/{id}/`
- Auth: API key in header `X-API-TOKEN`

Return a paginated list of invitations to join a group, newest first unless `sort` says otherwise. **Only a group owner can call this** — it is deliberately narrower than `GET /api/v1/groups/members/{id}/`, which any member of the group can read.

An invitation exists when `add-member` was called for an email that **already has an account**: that person is emailed and becomes a member only once they accept. See `POST /api/v1/groups/add-member/{id}/` for how the two outcomes differ.

Every status is returned, not just the outstanding ones, because a declined or expired invitation is usually the answer to "why is this person not in the group". Use `status` to narrow it.

Note that `status: 1` (Pending) and an `expires_at` in the past can occur together: the job that moves timed-out invitations to `status: 4` (Expired) runs periodically, so an invitation that is past `expires_at` is no longer answerable even while it still reads as pending. Treat `expires_at` as authoritative.

The invitation token is never returned. Holding it is what accepts the invitation, so it is not part of this contract and will not be added to it.

The nested `user` is deliberately minimal — `id`, `name` and `email` only. An invitee has not joined the group and may yet decline, so the account state returned by other endpoints (balance, orders, blocked and verification flags) is not exposed here.

## Path parameters

- `id` integer, required

## Query parameters

- `status` 1 | 2 | 3 | 4 | 5
- `search` string
- `sort` 'status_label' | 'email' | 'role' | 'created_at'
- `dir` 'asc' | 'desc'
- `page` integer
- `size` integer

## Response `200`

The request succeeded and returned paginated group invitations.

- object
  - `success` boolean
  - `data` object
    - `invitations` GroupMemberInvitation[]
      - `id` integer: Numeric invitation ID. Not a group member ID.
      - `email` string: Email of the invited account, lifted out of `user` for convenience. Always the address the invitation was sent to.
      - `role` 1 | 2 | 3: Role the membership will carry **once accepted**. | ID | Name | Description | |:---|:-------|------------:| | 1 | ROLE_OWNER | Group administrator. | | 2 | ROLE_TEACHER | Teacher | | 3 | ROLE_STUDENT | Student |
      - `limit` integer, nullable: Page limit the membership will carry once accepted. `null` means no explicit member limit.
      - `status` 1 | 2 | 3 | 4 | 5: | ID | Name | Description | |:---|:-------|------------:| | 1 | Pending | Sent, not yet answered. Check `expires_at` before treating it as answerable. | | 2 | Accepted | Answered yes; the group member exists. | | 3 | Declined | Answered no. | | 4 | Expired | Timed out unanswered. | | 5 | Cancelled | Withdrawn before it was answered. |
      - `status_label` string: Human-readable form of `status`. `Unknown` for a code this version does not recognise.
      - `source` 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8: Where the invitation came from. | ID | Name | |:---|:-------| | 1 | API v1 | | 2 | B2B API | | 3 | Admin panel | | 4 | Bulk import | | 5 | Moodle | | 6 | Canvas | | 7 | OneRoster | | 8 | LTI |
      - `source_label` string: Human-readable form of `source`. `Unknown` for a code this version does not recognise.
      - `sent_count` integer: How many times this invitation has been emailed. Re-inviting the same person refreshes this row rather than creating a new one, so this counts resends.
      - `created_at` string: Timestamp in milliseconds when the invitation was first created. Rendered as a decimal **string**, not a number — as every other timestamp this API returns is.
      - `expires_at` string: Timestamp in milliseconds after which the invitation can no longer be answered, as a decimal string. Authoritative: an invitation past this moment is dead even while `status` still reads `1`.
      - `responded_at` string, nullable: Timestamp in milliseconds when the invitation was answered, as a decimal string, or `null` if it was not answered.
      - `user` InvitedUser: An invited account, as seen by the group owner who invited them. Three fields, and it will stay three fields — the person described here has consented to nothing beyond having an account.
        - `id` integer: Numeric user ID of the invited account.
        - `name` string: Display name on the account. Empty string when the account has no name set.
        - `email` string: Email of the invited account. Same value as the invitation's `email`.
  - `pagination` Pagination: Pagination metadata returned by list endpoints.
    - `last` integer: Last available page number.
    - `current` integer: Current page number.
    - `num_items_per_page` integer: Requested page size.
    - `first` integer: First available page number.
    - `page_count` integer: Total number of pages.
    - `total_count` integer: Total number of items across all pages.
    - `page_range` integer: Number of page links included in the current range.
    - `start_page` integer: First page number in the displayed range.
    - `end_page` integer: Last page number in the displayed range.
    - `pages_in_range` integer[]: The page numbers the pager displays. Returned by every paginated endpoint; it was missing from this schema until the dashboard endpoint's contract test compared a real response against it.
    - `first_page_in_range` integer: First page number available in the current range.
    - `lastPage_in_range` integer: Last page number available in the current range.
    - `current_item_count` integer: Number of items returned on the current page.
    - `first_item_number` integer: One-based index of the first item on the current page.
    - `last_item_number` integer: One-based index of the last item on the current page.

## Other responses

- `400`: The request is invalid. Check required fields, field formats, and resource ownership.
- `403`: Authentication or authorization failed because the token is missing, invalid, blocked, or not allowed to access the resource.

## Changes

- **2026-10-12** `d0c0f996c9d4`: 2 info
  - added the new optional `query` request parameter `dir`
  - added the new optional `query` request parameter `sort`
- **2026-09-21** `9736bbb77e84`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/plagiarismcheck/apis/plagiarismcheck-org-api/changes/api/v1/groups/invitations/:id/get.md)

---

[API](https://skmtc.dev/plagiarismcheck/apis/plagiarismcheck-org-api.md) - [All operations](https://skmtc.dev/plagiarismcheck/apis/plagiarismcheck-org-api/llms.txt) - [OpenAPI document](https://skmtc.dev/plagiarismcheck/apis/plagiarismcheck-org-api/revisions/2c81c29267dc?raw)
