# List submissions for an opportunity (https://terac.com/docs/developers/reference/listSubmissions)

`GET https://terac.com/api/external/v2/opportunities/{opportunityId}/submissions`

Lists an opportunity's submissions, newest first, each with its status and screening answers. Filter to one `status`; the `awaiting_review` ones wait on you to approve or reject them. Applicants still in the screener, or waiting on your invite decision, are not listed; the latter are in `GET /opportunities/{opportunityId}/applicants`. Returns up to `limit` per page; while `pagination.has_more` is true, pass `pagination.next_cursor` back as `cursor` for the next page. For totals, read `submission_stats` on the opportunity rather than counting pages.

## Authorization

Requires a Bearer token via the `Authorization` header.

```
Authorization: Bearer <token>
```

## Path Parameters

- `opportunityId` (string) **(required)**: ID of the opportunity, as returned by `POST /opportunities` or `GET /opportunities`.

## Query Parameters

- `limit` (integer): Most items to return in one page, from 1 to 100. Defaults to 25.
- `cursor` (string): `pagination.next_cursor` from the previous page, to fetch the page after it. Omit it for the first page.
- `status` (string: one of: `screen_passed`, `screened_out`, `in_progress`, `awaiting_review`, `approved`, `rejected`, `abandoned`): "screened_out" never reached the work, "rejected" did the work and was not accepted, "abandoned" stopped part-way.

## Responses

### 200: One page of submissions, with the dashboard page where they are reviewed.

- `data` (array) **(required)**
  - `id` (string) **(required)**
  - `opportunity_id` (string) **(required)**
  - `status` (string) **(required)**: one of: `screen_passed`, `screened_out`, `in_progress`, `awaiting_review`, `approved`, `rejected`, `abandoned`: "screened_out" never reached the work, "rejected" did the work and was not accepted, "abandoned" stopped part-way.
  - `participant_id` (string) **(required)**
  - `created_at` (string) **(required)**
  - `updated_at` (string) **(required)**
  - `participant_name` (string, nullable) **(required)**: The participant's name. Null when your organization hides participant identity in Terac, or when we hold none.
  - `participant_linkedin_url` (string, nullable) **(required)**: The participant's LinkedIn profile URL. Null when your organization hides participant identity in Terac, or when they have none on file.
  - `participant_background` (object, nullable) **(required)**: The participant's work and education history, with names and contact details removed. Null when we hold no history for them.
    - `experiences` (array) **(required)**: Their work history.
      - `company` (string) **(required)**
      - `role` (string, nullable) **(required)**
      - `started_at` (string, nullable) **(required)**
      - `ended_at` (string, nullable) **(required)**
      - `description` (string, nullable) **(required)**: What they did there, with contact details removed.
    - `educations` (array) **(required)**: Their education history.
      - `school` (string) **(required)**
      - `degree` (string, nullable) **(required)**
      - `major` (string, nullable) **(required)**
  - `screening_outcome` (string, nullable) **(required)**: one of: `passed`, `failed`, `review`, `null`: The screener's overall verdict; "review" means qualified but flagged for a human. null while it is unfinished or absent.
  - `screening_answers` (array) **(required)**: Every answer given, with each verdict. Empty when the screener recorded nothing.
    - `key` (string): The `screening_questions[].key` this answers. Absent only on legacy panel-backed screenings, which stored answers per insight.
    - `question` (string) **(required)**: The prompt as asked, in plain text.
    - `answer` (array) **(required)**
    - `outcome` (string, nullable) **(required)**: one of: `qualify`, `reject`, `not_important`, `review`, `null`: The verdict this answer received; do not re-derive it from `qualify_logic`. null if a branching screener never graded it.
- `pagination` (object) **(required)**
  - `next_cursor` (string, nullable) **(required)**
  - `has_more` (boolean) **(required)**
- `dashboard_url` (string, nullable) **(required)**: Who applied, who is in progress, who is awaiting review. Set exactly when `draft_editor` here is null. Do not read that as the opportunity being live: the `status` field reports several settled states (cancelled, expired, failed) as `draft`, so read status from `status` and treat this only as a link. Give this when the customer asks about progress or has submissions to review. Null if Terac cannot resolve the organization or project this link belongs to.
### 400: Invalid input data

- `message` (string) **(required)**: The error message
- `code` (string) **(required)**: The error code
- `issues` (array): An array of issues that were responsible for the error
  - `message` (string) **(required)**
### 401: The API key is missing, invalid, disabled, expired or revoked, its owner no longer exists, or it is not linked to an organization. The body is nested under `error`.

- `error` (object) **(required)**
  - `code` (string) **(required)**: one of: `UNAUTHORIZED`: The error code.
  - `message` (string) **(required)**: What went wrong.
### 403: Either the account that owns the API key is banned or deleted (from the key check, nested under `error`), or the key's owner lacks the organization permission this operation needs (from the operation, with `code` and `message` at the top level).

- One of: API key error (403)
  - `error` (object) **(required)**
    - `code` (string) **(required)**: one of: `FORBIDDEN`: The error code.
    - `message` (string) **(required)**: What went wrong.
- One of: Insufficient access error (403)
  - `message` (string) **(required)**: The error message
  - `code` (string) **(required)**: The error code
  - `issues` (array): An array of issues that were responsible for the error
    - `message` (string) **(required)**
### 404: Not found

- `message` (string) **(required)**: The error message
- `code` (string) **(required)**: The error code
- `issues` (array): An array of issues that were responsible for the error
  - `message` (string) **(required)**
### 429: The API key is rate limited. A key accepts 100 requests, then refuses every request until more than 60 seconds pass with no accepted request; refused requests do not extend the wait. Wait the number of seconds in `Retry-After`, then retry. The body is nested under `error`.

- `error` (object) **(required)**
  - `code` (string) **(required)**: one of: `RATE_LIMITED`: The error code.
  - `message` (string) **(required)**: What went wrong.
### 500: Internal server error

- `message` (string) **(required)**: The error message
- `code` (string) **(required)**: The error code
- `issues` (array): An array of issues that were responsible for the error
  - `message` (string) **(required)**