Currents Test Results API

Query historical test execution results. Test results provide detailed information about individual test executions across multiple runs. You can filter by date range, branch, tags, git author, and outcome (`status[]` values use the `RecordedTestOutcome` schema).

GitHub OpenAPI

Operations 1

GET /test-results/{signature} Get test results #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/currents-dev:currents-dev-test-results-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

currents-dev-test-results-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Currents Dev Test Results API
  version: 1.0.0
  contact:
    name: Currents Support
    url: https://currents.dev
  description: 'Operations tagged Test Results across 2 of this provider''s published API definitions: currents-dev-openapi.json, currents-dev-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.currents.dev/v1
  description: Production API
- url: https://api-staging.currents.dev/v1
  description: Staging API
- url: http://localhost:4000/v1
  description: Local development
security:
- BearerAuth: []
tags:
- name: Test Results
  description: 'Query historical test execution results.


    Test results provide detailed information about individual test executions

    across multiple runs. You can filter by date range, branch, tags, git author,

    and outcome (`status[]` values use the `RecordedTestOutcome` schema).'
paths:
  /test-results/{signature}:
    get:
      summary: Get test results
      description: Get historical test execution results for a specific test signature
      operationId: getTestResults
      security:
      - BearerAuth: []
      - OAuth2:
        - results:read
      tags:
      - Test Results
      parameters:
      - $ref: '#/components/parameters/SignaturePath'
      - $ref: '#/components/parameters/DateStartQuery'
      - $ref: '#/components/parameters/DateEndQuery'
      - $ref: '#/components/parameters/TestResultsLimitQuery'
      - $ref: '#/components/parameters/StartingAfterQuery'
      - $ref: '#/components/parameters/EndingBeforeQuery'
      - $ref: '#/components/parameters/TagsQuery'
      - $ref: '#/components/parameters/BranchesQuery'
      - $ref: '#/components/parameters/AuthorsQuery'
      - $ref: '#/components/parameters/GroupsQuery'
      - $ref: '#/components/parameters/EnvironmentsQuery'
      - name: branch[]
        in: query
        required: false
        deprecated: true
        description: Deprecated. Use branches[] instead. Filter by git branch (can be specified multiple times using bracket notation, e.g., branch[]=main&branch[]=develop). Each value supports a trailing `*` for prefix search. Each branch value is limited to 250 characters (exact or wildcard).
        schema:
          type: array
          items:
            $ref: '#/components/schemas/BranchFilterQueryValue'
        style: form
        explode: true
        example:
        - main
        - release/*
      - name: tag[]
        in: query
        required: false
        deprecated: true
        description: Deprecated. Use tags[] instead. Filter by run tags (can be specified multiple times using bracket notation, e.g., tag[]=tag1&tag[]=tag2)
        schema:
          type: array
          items:
            type: string
        style: form
        explode: true
        example:
        - tag1
        - tag2
      - name: status[]
        in: query
        required: false
        description: Filter by outcome(s). Each value is a `RecordedTestOutcome` (see schemas). Multiple values OR together. Combine with `flaky` using AND when both are set.
        schema:
          type: array
          items:
            $ref: '#/components/schemas/RecordedTestOutcome'
        style: form
        explode: true
        example:
        - passed
        - failed
      - name: flaky
        in: query
        required: false
        description: Filter by flaky status. When true, returns only flaky tests. When false, returns only non-flaky tests. When omitted, returns all tests regardless of flaky status. Can be combined with status filter using AND logic (e.g., status[]=passed&flaky=true returns only flaky passed tests).
        schema:
          type: boolean
      - name: annotations
        in: query
        required: false
        description: 'Filter by test annotations. The parameter value must be a JSON-stringified array of objects: `[{ "type": "string", "description": "string" | ["string"] or null }]`. description is optional; omit or set to null to match any value for that annotation.'
        schema:
          type: string
        example: '[{"type":"owner","description":["John Doe"]},{"type":"skip"}]'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestResultsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          description: 'Payload Too Large - Response size exceeds limits. Use Accept-Encoding: gzip header.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    servers:
    - url: https://api.currents.dev/v1
      description: Production API
    - url: https://api-staging.currents.dev/v1
      description: Staging API
    - url: http://localhost:4000/v1
      description: Local development
components:
  parameters:
    GroupsQuery:
      name: groups[]
      in: query
      required: false
      description: Filter by groups (can be specified multiple times using bracket notation, e.g., groups[]=group1&groups[]=group2)
      schema:
        type: array
        items:
          type: string
      style: form
      explode: true
      example:
      - group1
      - group2
    TagsQuery:
      name: tags[]
      in: query
      required: false
      description: Filter by tags (can be specified multiple times using bracket notation, e.g., tags[]=value1&tags[]=value2)
      schema:
        type: array
        items:
          type: string
      style: form
      explode: true
      example:
      - tag1
      - tag2
    SignaturePath:
      name: signature
      in: path
      required: true
      description: The test signature
      schema:
        type: string
      example: abc123def456
    EnvironmentsQuery:
      name: environments[]
      in: query
      required: false
      description: Filter by environment (can be specified multiple times using bracket notation, e.g., environments[]=staging&environments[]=production)
      schema:
        type: array
        items:
          type: string
      style: form
      explode: true
      example:
      - staging
      - production
    StartingAfterQuery:
      name: starting_after
      in: query
      required: false
      description: Cursor for pagination. Returns items after this cursor value.
      schema:
        type: string
    DateEndQuery:
      name: date_end
      in: query
      required: true
      description: End date in ISO 8601 format
      schema:
        type: string
        format: date-time
      example: '2024-01-31T23:59:59.999Z'
    EndingBeforeQuery:
      name: ending_before
      in: query
      required: false
      description: Cursor for pagination. Returns items before this cursor value.
      schema:
        type: string
    TestResultsLimitQuery:
      name: limit
      in: query
      required: false
      description: 'Maximum number of items to return (default: 10, max: 100)'
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 10
    BranchesQuery:
      name: branches[]
      in: query
      required: false
      description: Filter by git branch. Use trailing `*` for prefix match (e.g. `release/*`). Max 250 characters per value.
      schema:
        type: array
        items:
          $ref: '#/components/schemas/BranchFilterQueryValue'
      style: form
      explode: true
      example:
      - main
      - release/*
    AuthorsQuery:
      name: authors[]
      in: query
      required: false
      description: Filter by git authors (can be specified multiple times using bracket notation, e.g., authors[]=author1&authors[]=author2)
      schema:
        type: array
        items:
          type: string
      style: form
      explode: true
      example:
      - author1
      - author2
    DateStartQuery:
      name: date_start
      in: query
      required: true
      description: Start date in ISO 8601 format
      schema:
        type: string
        format: date-time
      example: '2024-01-01T00:00:00.000Z'
  schemas:
    TestResultsResponse:
      type: object
      required:
      - status
      - has_more
      - data
      properties:
        status:
          type: string
          enum:
          - OK
        has_more:
          type: boolean
        data:
          type: array
          items:
            $ref: '#/components/schemas/TestResult'
    BranchFilterQueryValue:
      description: 'Branch filter value: an exact branch name, or a trailing `*` for prefix match (e.g. `release/*`). Max 250 characters.'
      oneOf:
      - type: string
        description: Exact branch name (must not contain `*` or spaces).
        pattern: ^[!-)+-~]+$
        maxLength: 250
      - type: string
        description: 'Prefix match: branch prefix followed by `*`.'
        pattern: ^[!-)+-~]+\*$
        maxLength: 250
    ErrorResponse:
      type: object
      required:
      - status
      - error
      properties:
        status:
          type: string
          enum:
          - FAILED
        error:
          type: string
          description: Error message
        code:
          type: string
          description: Stable machine-readable discriminator, present on refusals a client is expected to branch on (for example `AI_CONSENT_REQUIRED`). The `error` text is free-form; branch on `code`.
        candidates:
          type: array
          description: 'With `code: ambiguous_target`: the runs, spec files or tests the request matched. Send one of their IDs.'
          items:
            type: object
            properties:
              runId:
                type: string
              ciBuildId:
                type: string
              instanceId:
                type: string
              groupId:
                type: string
              spec:
                type: string
              machineId:
                type:
                - string
                - 'null'
              testId:
                type: string
              title:
                type: array
                items:
                  type: string
    TestResult:
      type: object
      properties:
        cursor:
          type: string
        signature:
          type: string
        framework:
          type: string
        createdAt:
          type: string
          format: date-time
        projectId:
          type: string
        groupId:
          type: string
        runId:
          type: string
        instanceId:
          type: string
        spec:
          type: string
        machineId:
          type: string
        tags:
          type: array
          items:
            type: string
        title:
          type: array
          items:
            type: string
        testId:
          type: string
        displayError:
          type:
          - string
          - 'null'
        commit:
          type: object
          properties:
            branch:
              type: string
            authorEmail:
              type: string
            authorName:
              type: string
            sha:
              type: string
            message:
              type: string
        duration:
          type: integer
        flaky:
          type: boolean
        expectedStatus:
          type:
          - string
          - 'null'
        status:
          $ref: '#/components/schemas/RecordedTestOutcome'
        attempts:
          type: array
          items:
            type: object
            properties:
              attemptId:
                type: string
              state:
                type: string
              error:
                type:
                - object
                - 'null'
                properties:
                  message:
                    type: string
                  stack:
                    type: string
                  location:
                    type: object
              startedAt:
                type: string
                format: date-time
              duration:
                type: integer
        annotations:
          type:
          - array
          - 'null'
          items:
            type: object
            properties:
              type:
                type: string
              description:
                type: string
    RecordedTestOutcome:
      type: string
      description: 'Final per-test outcome stored in Currents.


        - **passed** — Runner reported success.

        - **failed** — Runner reported failure (assertions, errors, timeouts, etc.).

        - **pending** — Intentional skip or disabled test (e.g. `test.skip()` / `it.skip()`). In **Tests Explorer** (`GET /tests/{projectId}`) this increments `metrics.ignored` and does **not** increment `metrics.failures`.

        - **skipped** — Runner reported a skip without a normal pass/fail (often interrupted or never executed as pass/fail). In **Tests Explorer** this increments `metrics.failures` together with `failed` (there is no separate `skipped` counter in that response). On **run and spec** payloads, `stats.skipped` is still reported separately from `stats.failures` and `stats.pending`.'
      enum:
      - passed
      - failed
      - pending
      - skipped
  responses:
    Forbidden:
      description: 'The credential authenticated but is not permitted to use this endpoint. Five refusals share the status: a `read` API key on an endpoint that writes, an OAuth token that was not granted the scope the endpoint needs (`insufficient_scope`), an OAuth token that was granted it but whose holder no longer has a role permitting it (`insufficient_role`), an OAuth token on an endpoint that accepts an API key and nothing else (`api_key_required`), and an API key on an endpoint that answers for a user (`user_credential_required`). Discriminate on `code` rather than on the message, which is free-form. The first refusal predates the codes and sets none. Only `insufficient_scope` carries the challenge header, because it is the only one a client can act on by re-authorizing.'
      headers:
        WWW-Authenticate:
          description: 'Present on the `insufficient_scope` refusal only, naming the scope to re-authorize for (RFC 6750 3.1): `Bearer error="insufficient_scope", scope="webhooks:read"`. Absent on `insufficient_role`, where the scope is already granted, and on `api_key_required` and `user_credential_required`, where no scope would help.'
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            apiKeyIsReadOnly:
              summary: A read API key on an endpoint that writes
              value:
                status: FAILED
                error: 'Insufficient permissions: write access required'
            scopeNotGranted:
              summary: An OAuth token missing the endpoint's scope
              value:
                status: FAILED
                error: 'Insufficient permissions: this endpoint requires the webhooks:read scope'
                code: insufficient_scope
            scopeAboveRole:
              summary: An OAuth token holding the scope, whose holder was since demoted
              value:
                status: FAILED
                error: 'Insufficient permissions: the webhooks:write scope requires the admin role in this organization'
                code: insufficient_role
            apiKeyRequired:
              summary: An OAuth token on an endpoint that takes an API key
              value:
                status: FAILED
                error: This endpoint accepts an API key, not an OAuth access token
                code: api_key_required
            userCredentialRequired:
              summary: An API key on an endpoint that answers for a user
              value:
                status: FAILED
                error: This endpoint requires an OAuth access token or a personal access token; an API key belongs to an organization, not a user
                code: user_credential_required
    Unauthorized:
      description: Authentication failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            status: FAILED
            error: Invalid authentication credentials
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            status: FAILED
            error: 'Invalid request body: name is required'
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            status: FAILED
            error: Not found
  securitySchemes:
    RecordKey:
      type: apiKey
      in: header
      name: x-currents-key
      description: An organization's record key, the one a reporter sends. Accepted only by the two attachment routes under `/runs`, `POST /runs/{runId}/context-links`, `POST /sessions`, `POST /sessions/{sessionId}/attachments` and, for a session, `POST /share`, so a CI job can attach files, link its failed and flaky tests, record a session and share it with the key it already has.
    BearerAuth:
      type: http
      scheme: bearer
      description: 'An organization API key, sent as `Authorization: Bearer <key>`. A key carries one scope for the whole API: a `read` key reaches the GET endpoints, a `write` key reaches all of them. A `crnts_pat_` personal access token is accepted as a Bearer while its owner remains an eligible administrator in its active organization. Each operation requires the corresponding scope stored on that token.'
    OAuth2:
      type: oauth2
      description: 'An access token from the Currents authorization server, for an application acting as a user in one organization. Unlike an API key it is confined per endpoint: the operation lists the scope it needs, and a token that was not granted that scope gets 403.


        **The endpoints below are production''s.** They are written out so this specification can be exercised against production, and they are wrong for every other deployment — a token minted by `id.currents.dev` is refused by a staging or on-premise API, whose `OAUTH_ISSUER` and `OAUTH_API_AUDIENCE` are its own. Against anything but production, and in a client generated from this document, discover them instead: `GET {api origin}/.well-known/oauth-protected-resource`, then the `authorization_servers[0]` document.


        **The audience named here is the REST API''s.** `POST /mcp` is a second resource server on the same origin, identified by `{api origin}/mcp` and described by its own document at `/.well-known/oauth-protected-resource/mcp`. Every operation below refuses a token minted for it, and it refuses every token minted for these, so a client of this specification wants the audience above and not that one.'
      flows:
        authorizationCode:
          authorizationUrl: https://id.currents.dev/api/auth/oauth2/authorize
          tokenUrl: https://id.currents.dev/api/auth/oauth2/token
          refreshUrl: https://id.currents.dev/api/auth/oauth2/token
          scopes:
            projects:read: See which projects exist and their names
            projects:write: Change project configuration, including a project's tags
            results:read: See runs, specs and failure detail — errors, stacks and artifacts
            analytics:read: 'See aggregate metrics: flake and failure rates, error counts, durations and trends'
            actions:read: See quarantine and skip rules, and the tests they affect
            actions:write: Create, edit, enable, disable and archive quarantine and skip rules
            issues:write: Create and link issues in a connected issue tracker, and list its projects and issue types
            runs:write: Cancel and reset runs, and permanently delete runs and their artifacts
            webhooks:read: See webhook configuration, including destination URLs and headers
            webhooks:write: Create, edit and delete webhooks
            shares:write: Create public links to test results that anyone with the link can open until they expire
x-refined-from:
- currents-dev-openapi.json
- currents-dev-openapi.yml