---
title: "List recent test submissions for a repository."
method: GET
path: "/api/repos/{owner}/{name}/submissions"
tags: ["Submissions"]
---

# List recent test submissions for a repository.

`GET /api/repos/{owner}/{name}/submissions`

## Request

- Base URL: `https://platform.buildpulse.io`
- URL: `https://platform.buildpulse.io/api/repos/{owner}/{name}/submissions`
- Auth: one of:
  - API key in header `Authorization`
  - HTTP bearer

Returns the last 14 days of test result sets ("submissions") for
the named repository, newest first. Pagination is keyset-based on
the document ID — `metadata.after` is an opaque cursor that
should be passed back as the `after` query parameter to fetch the
next page.

Repository lookup is case-insensitive; `OWNER/REPO` matches
`owner/repo`.

## Path parameters

- `owner` string, required
- `name` string, required

## Query parameters

- `limit` integer
- `after` string

## Response `200`

Paginated submissions.

- SubmissionsResponse
  - `count` integer, required: Total submissions matching the filter (not just this page).
  - `submissions` Submission[], required
    - `id` string, required: Submission identifier (24-char hex ObjectID). Pass to `/api/repos/{owner}/{name}/submissions/{submission_id}/tests` to fetch the per-test results for this submission.
    - `key` string, required: Legacy S3 object key for the raw test result archive. Stable and unique per submission in the legacy stack; empty string on the new pipeline. Prefer `id` for cross-endpoint joins.
    - `build_url` string, uri, required: CI run URL that produced this submission.
    - `commit_oid` string, required: Git commit SHA-1 (40 hex chars).
    - `recorded_at` string, date-time, required: ISO 8601 timestamp (UTC, second precision).
    - `status` string, required: Processing status. Currently `processed`, `processing`, or other internal states.
    - `test_result_count` integer, required: Number of individual test results in this submission. Counts every recorded attempt — retries and skipped tests included — so it can exceed the number of distinct tests in the run.
  - `metadata` Metadata, required
    - `after` string, nullable, required: Opaque cursor for the next page; `null` if there is no next page.
    - `limit` integer, required

## Other responses

- `400`: Cursor failed to decode.
- `401`: Missing, malformed, or invalid token; or — for legacy 40-hex tokens only — the organization has no active plan (`marketplacePurchases.unitCount > 0`). The new `bp_<64-hex>` path has no plan gate, so a 401 there means the token shape was wrong, the hash didn't match, or the token has expired. Response body is empty (matches legacy Rails).
- `402`: The organization is over its plan's monthly test-result limit and data-read access is restricted (staged-overage stage `soft` or `hard`). At `soft` the data is locked but safe — ingestion keeps recording. At `hard` ingestion is also paused (raw retained ~30 days) and an upgrade resumes processing. Read `GET /api/v1/usage` for the current stage and usage, and visit `upgradeUrl` to restore access. Only returned for organizations positively identified as over the enforced limit while enforcement is enabled.
- `404`: Resource not found.

---

[API](https://skmtc.dev/buildpulse/apis/buildpulse-platform-api.md) · [All operations](https://skmtc.dev/buildpulse/apis/buildpulse-platform-api/llms.txt) · [OpenAPI document](https://skmtc.dev/buildpulse/apis/buildpulse-platform-api/revisions/2e68b4b2df6a?raw)
