REST API reference

Spaces and people

Read-only reference data. Your token reaches exactly one Space, so GET /projects returns that one Space, and its id is the projectId every create request needs.

List projects

GET/api/v1/projects

Lists project resources as a JSON:API collection document. Narrow the set with filter, order it with sort, embed related resources with include, select attributes with fields[<type>], and page with page[size] plus page[number] (offset) or page[after] (cursor, taken from the previous response's links.next).

Query parameters

filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
projectKey = "A"
sortstring
Comma-separated sort fields; prefix a field with "-" for descending order (e.g. "-createdAt,title"). Permitted fields: id, organizationId, externalId, projectKey.
-projectKey
includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, updatedByUser.
createdByUser
fields[projects]string[]
Sparse fieldset for resource type "projects" - comma-separated subset of its exposed fields: id, organizationId, externalId, projectKey, createdAt, updatedAt, createdBy, updatedBy, createdByUser, updatedByUser, organization.
projectKey,createdAt,updatedAt
page[size]integer
Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25
page[number]integer
1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2
page[after]string
Opaque cursor for cursor-based pagination - always taken verbatim from a previous response's "links.next" value, never client-constructed or decoded. Mutually exclusive with "page[number]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields8

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
projectKeystring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example comments ANY (id = "…"). Relations: comments, environments, fixVersions, gqlithCustomFields, issues, links, createdByUser, organization, updatedByUser, requirementFolders, requirements, savedFilters, testCampaignCycles, testCampaignFixVersions, testCampaignFolders, testCampaigns, testCaseExecutions, testCaseFolders, testCases, testCollectionFolders, testCollectionRequirements, testCollectionTestCases, testCollections, testCycleFolders, testCycles, testStepExecutions, testSteps, versions.

Returns the same attributes as Get a project.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INVALID_TYPED_JSON_FILTERUNKNOWN_SORT_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDUNKNOWN_TYPEUNKNOWN_FIELDCONFLICTING_PAGINATIONINVALID_PAGE_SIZEPAGE_SIZE_EXCEEDEDINVALID_PAGE_NUMBERINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/projects?page%5Bsize%5D=25" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": [
    {
      "type": "projects",
      "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
      "attributes": {
        "updatedAt": "2026-10-05T09:30:00Z"
      },
      "links": {
        "self": "/projects/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
      }
    }
  ],
  "links": {
    "self": "/projects?page[size]=25",
    "first": "/projects?page[size]=25&page[number]=1",
    "prev": null,
    "next": "/projects?page[size]=25&page[number]=2",
    "last": "/projects?page[size]=25&page[number]=6"
  },
  "meta": {
    "totalCount": 128
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Count and aggregate projects

GET/api/v1/projects/aggregate

Aggregates project resources - a count and per-column aggregations, optionally grouped - over the same filter the collection route accepts.

Query parameters

aggregations[count]boolean
Include the row count in the aggregate result. When no aggregation is requested at all, the runtime defaults to count.
aggregations[min][]string[]
Column(s) to take the minimum of - repeat the bracketed key per column (aggregations[min][]=a&aggregations[min][]=b). Permitted columns: externalId, projectKey, createdAt, updatedAt.
aggregations[max][]string[]
Column(s) to take the maximum of - repeat the bracketed key per column (aggregations[max][]=a&aggregations[max][]=b). Permitted columns: externalId, projectKey, createdAt, updatedAt.
aggregations[groupBy][]string[]
Column(s) to group by - repeating the bracketed key switches the response to the grouped shape (aggregations[groupBy][]=a&aggregations[groupBy][]=b). Permitted columns: id, organizationId, externalId, projectKey.
filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
projectKey = "A"

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields8

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
projectKeystring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example comments ANY (id = "…"). Relations: comments, environments, fixVersions, gqlithCustomFields, issues, links, createdByUser, organization, updatedByUser, requirementFolders, requirements, savedFilters, testCampaignCycles, testCampaignFixVersions, testCampaignFolders, testCampaigns, testCaseExecutions, testCaseFolders, testCases, testCollectionFolders, testCollectionRequirements, testCollectionTestCases, testCollections, testCycleFolders, testCycles, testStepExecutions, testSteps, versions.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/projects/aggregate?aggregations%5Bcount%5D=true" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "projects_aggregate",
    "id": "(aggregate)",
    "attributes": {
      "count": 128
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Get a project

GET/api/v1/projects/{id}

Returns the project with this id as a JSON:API resource document; include embeds related resources and fields[<type>] selects the attributes returned.

Path parameters

iduuidrequired
The resource id (a UUID).

Query parameters

includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, updatedByUser.
createdByUser
fields[projects]string[]
Sparse fieldset for resource type "projects" - comma-separated subset of its exposed fields: id, organizationId, externalId, projectKey, createdAt, updatedAt, createdBy, updatedBy, createdByUser, updatedByUser, organization.
projectKey,createdAt,updatedAt

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Attributes returned8

createdAtdate-timeread-only
createdByuuid | nullread-only
externalIdstring | null
iduuidread-only
organizationIduuidread-only
projectKeystring
updatedAtdate-timeread-only
updatedByuuid | nullread-only

Responses

  • 200Success.
12 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.UNKNOWN_TYPEUNKNOWN_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 410Gone.GONE
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/projects/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "projects",
    "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
    "attributes": {
      "updatedAt": "2026-10-05T09:30:00Z"
    },
    "links": {
      "self": "/projects/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

List organizations

GET/api/v1/organizations

Lists organization resources as a JSON:API collection document. Narrow the set with filter, order it with sort, embed related resources with include, select attributes with fields[<type>], and page with page[size] plus page[number] (offset) or page[after] (cursor, taken from the previous response's links.next).

Query parameters

filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
sortstring
Comma-separated sort fields; prefix a field with "-" for descending order (e.g. "-createdAt,title"). Permitted fields: id, externalId.
fields[organizations]string[]
Sparse fieldset for resource type "organizations" - comma-separated subset of its exposed fields: id, externalId, createdAt, updatedAt.
createdAt,updatedAt,id
page[size]integer
Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25
page[number]integer
1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2
page[after]string
Opaque cursor for cursor-based pagination - always taken verbatim from a previous response's "links.next" value, never client-constructed or decoded. Mutually exclusive with "page[number]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields4

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null

Filter through a relation with ANY, ALL or NONE, for example commentMentions ANY (id = "…"). Relations: commentMentions, comments, environments, fixVersions, gqlithCustomFields, issues, links, projects, requirementFolders, requirements, savedFilters, testCampaignCycles, testCampaignFixVersions, testCampaignFolders, testCampaigns, testCaseExecutions, testCaseFolders, testCases, testCollectionFolders, testCollectionRequirements, testCollectionTestCases, testCollections, testCycleFolders, testCycles, testStepExecutions, testSteps, users, versions.

Returns the same attributes as Get an organization.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INVALID_TYPED_JSON_FILTERUNKNOWN_SORT_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDUNKNOWN_TYPEUNKNOWN_FIELDCONFLICTING_PAGINATIONINVALID_PAGE_SIZEPAGE_SIZE_EXCEEDEDINVALID_PAGE_NUMBERINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/organizations?page%5Bsize%5D=25" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": [
    {
      "type": "organizations",
      "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
      "attributes": {
        "updatedAt": "2026-10-05T09:30:00Z"
      },
      "links": {
        "self": "/organizations/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
      }
    }
  ],
  "links": {
    "self": "/organizations?page[size]=25",
    "first": "/organizations?page[size]=25&page[number]=1",
    "prev": null,
    "next": "/organizations?page[size]=25&page[number]=2",
    "last": "/organizations?page[size]=25&page[number]=6"
  },
  "meta": {
    "totalCount": 128
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Count and aggregate organizations

GET/api/v1/organizations/aggregate

Aggregates organization resources - a count and per-column aggregations, optionally grouped - over the same filter the collection route accepts.

Query parameters

aggregations[count]boolean
Include the row count in the aggregate result. When no aggregation is requested at all, the runtime defaults to count.
aggregations[min][]string[]
Column(s) to take the minimum of - repeat the bracketed key per column (aggregations[min][]=a&aggregations[min][]=b). Permitted columns: externalId, createdAt, updatedAt.
aggregations[max][]string[]
Column(s) to take the maximum of - repeat the bracketed key per column (aggregations[max][]=a&aggregations[max][]=b). Permitted columns: externalId, createdAt, updatedAt.
aggregations[groupBy][]string[]
Column(s) to group by - repeating the bracketed key switches the response to the grouped shape (aggregations[groupBy][]=a&aggregations[groupBy][]=b). Permitted columns: id, externalId.
filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields4

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null

Filter through a relation with ANY, ALL or NONE, for example commentMentions ANY (id = "…"). Relations: commentMentions, comments, environments, fixVersions, gqlithCustomFields, issues, links, projects, requirementFolders, requirements, savedFilters, testCampaignCycles, testCampaignFixVersions, testCampaignFolders, testCampaigns, testCaseExecutions, testCaseFolders, testCases, testCollectionFolders, testCollectionRequirements, testCollectionTestCases, testCollections, testCycleFolders, testCycles, testStepExecutions, testSteps, users, versions.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/organizations/aggregate?aggregations%5Bcount%5D=true" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "organizations_aggregate",
    "id": "(aggregate)",
    "attributes": {
      "count": 128
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Get an organization

GET/api/v1/organizations/{id}

Returns the organization with this id as a JSON:API resource document; include embeds related resources and fields[<type>] selects the attributes returned.

Path parameters

iduuidrequired
The resource id (a UUID).

Query parameters

fields[organizations]string[]
Sparse fieldset for resource type "organizations" - comma-separated subset of its exposed fields: id, externalId, createdAt, updatedAt.
createdAt,updatedAt,id

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Attributes returned4

createdAtdate-time
externalIdstring | null
iduuidread-only
updatedAtdate-timeread-only

Responses

  • 200Success.
12 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.UNKNOWN_TYPEUNKNOWN_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 410Gone.GONE
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/organizations/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "organizations",
    "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
    "attributes": {
      "updatedAt": "2026-10-05T09:30:00Z"
    },
    "links": {
      "self": "/organizations/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

List users

GET/api/v1/users

Lists user resources as a JSON:API collection document. Narrow the set with filter, order it with sort, embed related resources with include, select attributes with fields[<type>], and page with page[size] plus page[number] (offset) or page[after] (cursor, taken from the previous response's links.next).

Query parameters

filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
sortstring
Comma-separated sort fields; prefix a field with "-" for descending order (e.g. "-createdAt,title"). Permitted fields: id, organizationId, externalId.
includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, updatedByUser.
createdByUser
fields[users]string[]
Sparse fieldset for resource type "users" - comma-separated subset of its exposed fields: id, organizationId, externalId, createdAt, updatedAt, createdBy, updatedBy, role, createdByUser, updatedByUser, organization.
createdAt,updatedAt,createdBy
page[size]integer
Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25
page[number]integer
1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2
page[after]string
Opaque cursor for cursor-based pagination - always taken verbatim from a previous response's "links.next" value, never client-constructed or decoded. Mutually exclusive with "page[number]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields8

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null
rolestring= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example commentMentions ANY (id = "…"). Relations: commentMentions, authorComments, createdByComments, updatedByComments, createdByEnvironments, updatedByEnvironments, createdByFixVersions, updatedByFixVersions, createdByIssues, updatedByIssues, createdByLinks, updatedByLinks, createdByProjects, updatedByProjects, createdByRequirementFolders, updatedByRequirementFolders, createdByRequirements, ownerRequirements, updatedByRequirements, createdBySavedFilters, updatedBySavedFilters, createdByTestCampaignCycles, updatedByTestCampaignCycles, createdByTestCampaignFixVersions, updatedByTestCampaignFixVersions, createdByTestCampaignFolders, updatedByTestCampaignFolders, createdByTestCampaigns, updatedByTestCampaigns, assigneeTestCaseExecutions, createdByTestCaseExecutions, updatedByTestCaseExecutions, createdByTestCaseFolders, updatedByTestCaseFolders, createdByTestCases, formatModeChangedByTestCases, ownerTestCases, updatedByTestCases, createdByTestCollectionFolders, updatedByTestCollectionFolders, createdByTestCollectionRequirements, updatedByTestCollectionRequirements, createdByTestCollectionTestCases, updatedByTestCollectionTestCases, defaultAssigneeTestCollectionTestCases, createdByTestCollections, updatedByTestCollections, defaultRuleAssigneeTestCollections, createdByTestCycleFolders, updatedByTestCycleFolders, assigneeTestCycles, createdByTestCycles, updatedByTestCycles, createdByTestStepExecutions, updatedByTestStepExecutions, createdByTestSteps, updatedByTestSteps, createdByUser, createdByUsers, organization, updatedByUser, updatedByUsers, createdByVersions, updatedByVersions.

Returns the same attributes as Get a user.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INVALID_TYPED_JSON_FILTERUNKNOWN_SORT_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDUNKNOWN_TYPEUNKNOWN_FIELDCONFLICTING_PAGINATIONINVALID_PAGE_SIZEPAGE_SIZE_EXCEEDEDINVALID_PAGE_NUMBERINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/users?page%5Bsize%5D=25" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": [
    {
      "type": "users",
      "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
      "attributes": {
        "updatedAt": "2026-10-05T09:30:00Z"
      },
      "links": {
        "self": "/users/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
      }
    }
  ],
  "links": {
    "self": "/users?page[size]=25",
    "first": "/users?page[size]=25&page[number]=1",
    "prev": null,
    "next": "/users?page[size]=25&page[number]=2",
    "last": "/users?page[size]=25&page[number]=6"
  },
  "meta": {
    "totalCount": 128
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Count and aggregate users

GET/api/v1/users/aggregate

Aggregates user resources - a count and per-column aggregations, optionally grouped - over the same filter the collection route accepts.

Query parameters

aggregations[count]boolean
Include the row count in the aggregate result. When no aggregation is requested at all, the runtime defaults to count.
aggregations[min][]string[]
Column(s) to take the minimum of - repeat the bracketed key per column (aggregations[min][]=a&aggregations[min][]=b). Permitted columns: externalId, createdAt, updatedAt, role.
aggregations[max][]string[]
Column(s) to take the maximum of - repeat the bracketed key per column (aggregations[max][]=a&aggregations[max][]=b). Permitted columns: externalId, createdAt, updatedAt, role.
aggregations[groupBy][]string[]
Column(s) to group by - repeating the bracketed key switches the response to the grouped shape (aggregations[groupBy][]=a&aggregations[groupBy][]=b). Permitted columns: id, organizationId, externalId.
filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields8

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null
rolestring= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example commentMentions ANY (id = "…"). Relations: commentMentions, authorComments, createdByComments, updatedByComments, createdByEnvironments, updatedByEnvironments, createdByFixVersions, updatedByFixVersions, createdByIssues, updatedByIssues, createdByLinks, updatedByLinks, createdByProjects, updatedByProjects, createdByRequirementFolders, updatedByRequirementFolders, createdByRequirements, ownerRequirements, updatedByRequirements, createdBySavedFilters, updatedBySavedFilters, createdByTestCampaignCycles, updatedByTestCampaignCycles, createdByTestCampaignFixVersions, updatedByTestCampaignFixVersions, createdByTestCampaignFolders, updatedByTestCampaignFolders, createdByTestCampaigns, updatedByTestCampaigns, assigneeTestCaseExecutions, createdByTestCaseExecutions, updatedByTestCaseExecutions, createdByTestCaseFolders, updatedByTestCaseFolders, createdByTestCases, formatModeChangedByTestCases, ownerTestCases, updatedByTestCases, createdByTestCollectionFolders, updatedByTestCollectionFolders, createdByTestCollectionRequirements, updatedByTestCollectionRequirements, createdByTestCollectionTestCases, updatedByTestCollectionTestCases, defaultAssigneeTestCollectionTestCases, createdByTestCollections, updatedByTestCollections, defaultRuleAssigneeTestCollections, createdByTestCycleFolders, updatedByTestCycleFolders, assigneeTestCycles, createdByTestCycles, updatedByTestCycles, createdByTestStepExecutions, updatedByTestStepExecutions, createdByTestSteps, updatedByTestSteps, createdByUser, createdByUsers, organization, updatedByUser, updatedByUsers, createdByVersions, updatedByVersions.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/users/aggregate?aggregations%5Bcount%5D=true" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "users_aggregate",
    "id": "(aggregate)",
    "attributes": {
      "count": 128
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Get a user

GET/api/v1/users/{id}

Returns the user with this id as a JSON:API resource document; include embeds related resources and fields[<type>] selects the attributes returned.

Path parameters

iduuidrequired
The resource id (a UUID).

Query parameters

includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, updatedByUser.
createdByUser
fields[users]string[]
Sparse fieldset for resource type "users" - comma-separated subset of its exposed fields: id, organizationId, externalId, createdAt, updatedAt, createdBy, updatedBy, role, createdByUser, updatedByUser, organization.
createdAt,updatedAt,createdBy

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Attributes returned8

createdAtdate-timeread-only
createdByuuid | nullread-only
externalIdstring | null
iduuidread-only
organizationIduuidread-only
rolestringdefault member
updatedAtdate-timeread-only
updatedByuuid | nullread-only

Responses

  • 200Success.
12 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.UNKNOWN_TYPEUNKNOWN_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 410Gone.GONE
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/users/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "users",
    "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
    "attributes": {
      "updatedAt": "2026-10-05T09:30:00Z"
    },
    "links": {
      "self": "/users/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

List environments

GET/api/v1/environments

Lists environment resources as a JSON:API collection document. Narrow the set with filter, order it with sort, embed related resources with include, select attributes with fields[<type>], and page with page[size] plus page[number] (offset) or page[after] (cursor, taken from the previous response's links.next).

Query parameters

filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
name = "example"
sortstring
Comma-separated sort fields; prefix a field with "-" for descending order (e.g. "-createdAt,title"). Permitted fields: id, organizationId, projectId, externalId, name.
-name
includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, project, updatedByUser.
createdByUser
fields[environments]string[]
Sparse fieldset for resource type "environments" - comma-separated subset of its exposed fields: id, organizationId, projectId, externalId, name, createdAt, updatedAt, createdBy, updatedBy, createdByUser, updatedByUser, organization, project.
name,createdAt,updatedAt
page[size]integer
Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25
page[number]integer
1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2
page[after]string
Opaque cursor for cursor-based pagination - always taken verbatim from a previous response's "links.next" value, never client-constructed or decoded. Mutually exclusive with "page[number]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields9

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
projectIduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
namestring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example createdByUser ANY (id = "…"). Relations: createdByUser, organization, project, updatedByUser, testCaseExecutions, testCycles.

Returns the same attributes as Get an environment.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INVALID_TYPED_JSON_FILTERUNKNOWN_SORT_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDUNKNOWN_TYPEUNKNOWN_FIELDCONFLICTING_PAGINATIONINVALID_PAGE_SIZEPAGE_SIZE_EXCEEDEDINVALID_PAGE_NUMBERINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/environments?page%5Bsize%5D=25" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": [
    {
      "type": "environments",
      "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
      "attributes": {
        "name": "Checkout",
        "updatedAt": "2026-10-05T09:30:00Z"
      },
      "links": {
        "self": "/environments/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
      }
    }
  ],
  "links": {
    "self": "/environments?page[size]=25",
    "first": "/environments?page[size]=25&page[number]=1",
    "prev": null,
    "next": "/environments?page[size]=25&page[number]=2",
    "last": "/environments?page[size]=25&page[number]=6"
  },
  "meta": {
    "totalCount": 128
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Count and aggregate environments

GET/api/v1/environments/aggregate

Aggregates environment resources - a count and per-column aggregations, optionally grouped - over the same filter the collection route accepts.

Query parameters

aggregations[count]boolean
Include the row count in the aggregate result. When no aggregation is requested at all, the runtime defaults to count.
aggregations[min][]string[]
Column(s) to take the minimum of - repeat the bracketed key per column (aggregations[min][]=a&aggregations[min][]=b). Permitted columns: externalId, name, createdAt, updatedAt.
aggregations[max][]string[]
Column(s) to take the maximum of - repeat the bracketed key per column (aggregations[max][]=a&aggregations[max][]=b). Permitted columns: externalId, name, createdAt, updatedAt.
aggregations[groupBy][]string[]
Column(s) to group by - repeating the bracketed key switches the response to the grouped shape (aggregations[groupBy][]=a&aggregations[groupBy][]=b). Permitted columns: id, organizationId, projectId, externalId, name.
filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
name = "example"

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields9

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
projectIduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
namestring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example createdByUser ANY (id = "…"). Relations: createdByUser, organization, project, updatedByUser, testCaseExecutions, testCycles.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/environments/aggregate?aggregations%5Bcount%5D=true" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "environments_aggregate",
    "id": "(aggregate)",
    "attributes": {
      "count": 128
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Get an environment

GET/api/v1/environments/{id}

Returns the environment with this id as a JSON:API resource document; include embeds related resources and fields[<type>] selects the attributes returned.

Path parameters

iduuidrequired
The resource id (a UUID).

Query parameters

includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, project, updatedByUser.
createdByUser
fields[environments]string[]
Sparse fieldset for resource type "environments" - comma-separated subset of its exposed fields: id, organizationId, projectId, externalId, name, createdAt, updatedAt, createdBy, updatedBy, createdByUser, updatedByUser, organization, project.
name,createdAt,updatedAt

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Attributes returned9

createdAtdate-timeread-only
createdByuuid | nullread-only
externalIdstring | null
iduuidread-only
namestring
organizationIduuidread-only
projectIduuid
updatedAtdate-timeread-only
Show the remaining 1
updatedByuuid | nullread-only

Responses

  • 200Success.
12 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.UNKNOWN_TYPEUNKNOWN_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 410Gone.GONE
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/environments/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "environments",
    "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
    "attributes": {
      "name": "Checkout",
      "updatedAt": "2026-10-05T09:30:00Z"
    },
    "links": {
      "self": "/environments/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

List versions

GET/api/v1/versions

Lists version resources as a JSON:API collection document. Narrow the set with filter, order it with sort, embed related resources with include, select attributes with fields[<type>], and page with page[size] plus page[number] (offset) or page[after] (cursor, taken from the previous response's links.next).

Query parameters

filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
testCaseExecutions ANY (testCaseExecutionKey = "A-EXEC-1")
sortstring
Comma-separated sort fields; prefix a field with "-" for descending order (e.g. "-createdAt,title"). Permitted fields: id, organizationId, projectId, externalId.
includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, project, updatedByUser.
createdByUser
fields[versions]string[]
Sparse fieldset for resource type "versions" - comma-separated subset of its exposed fields: id, organizationId, projectId, externalId, createdAt, updatedAt, createdBy, updatedBy, createdByUser, updatedByUser, organization, project.
createdAt,updatedAt,createdBy
page[size]integer
Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25
page[number]integer
1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2
page[after]string
Opaque cursor for cursor-based pagination - always taken verbatim from a previous response's "links.next" value, never client-constructed or decoded. Mutually exclusive with "page[number]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields8

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
projectIduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example testCaseExecutions ANY (id = "…"). Relations: testCaseExecutions, testCycles, createdByUser, organization, project, updatedByUser.

Returns the same attributes as Get a version.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INVALID_TYPED_JSON_FILTERUNKNOWN_SORT_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDUNKNOWN_TYPEUNKNOWN_FIELDCONFLICTING_PAGINATIONINVALID_PAGE_SIZEPAGE_SIZE_EXCEEDEDINVALID_PAGE_NUMBERINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/versions?page%5Bsize%5D=25" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": [
    {
      "type": "versions",
      "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
      "attributes": {
        "updatedAt": "2026-10-05T09:30:00Z"
      },
      "links": {
        "self": "/versions/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
      }
    }
  ],
  "links": {
    "self": "/versions?page[size]=25",
    "first": "/versions?page[size]=25&page[number]=1",
    "prev": null,
    "next": "/versions?page[size]=25&page[number]=2",
    "last": "/versions?page[size]=25&page[number]=6"
  },
  "meta": {
    "totalCount": 128
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Count and aggregate versions

GET/api/v1/versions/aggregate

Aggregates version resources - a count and per-column aggregations, optionally grouped - over the same filter the collection route accepts.

Query parameters

aggregations[count]boolean
Include the row count in the aggregate result. When no aggregation is requested at all, the runtime defaults to count.
aggregations[min][]string[]
Column(s) to take the minimum of - repeat the bracketed key per column (aggregations[min][]=a&aggregations[min][]=b). Permitted columns: externalId, createdAt, updatedAt.
aggregations[max][]string[]
Column(s) to take the maximum of - repeat the bracketed key per column (aggregations[max][]=a&aggregations[max][]=b). Permitted columns: externalId, createdAt, updatedAt.
aggregations[groupBy][]string[]
Column(s) to group by - repeating the bracketed key switches the response to the grouped shape (aggregations[groupBy][]=a&aggregations[groupBy][]=b). Permitted columns: id, organizationId, projectId, externalId.
filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
testCaseExecutions ANY (testCaseExecutionKey = "A-EXEC-1")

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields8

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
projectIduuid= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example testCaseExecutions ANY (id = "…"). Relations: testCaseExecutions, testCycles, createdByUser, organization, project, updatedByUser.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/versions/aggregate?aggregations%5Bcount%5D=true" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "versions_aggregate",
    "id": "(aggregate)",
    "attributes": {
      "count": 128
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Get a version

GET/api/v1/versions/{id}

Returns the version with this id as a JSON:API resource document; include embeds related resources and fields[<type>] selects the attributes returned.

Path parameters

iduuidrequired
The resource id (a UUID).

Query parameters

includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, project, updatedByUser.
createdByUser
fields[versions]string[]
Sparse fieldset for resource type "versions" - comma-separated subset of its exposed fields: id, organizationId, projectId, externalId, createdAt, updatedAt, createdBy, updatedBy, createdByUser, updatedByUser, organization, project.
createdAt,updatedAt,createdBy

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Attributes returned8

createdAtdate-timeread-only
createdByuuid | nullread-only
externalIdstring | null
iduuidread-only
organizationIduuidread-only
projectIduuid
updatedAtdate-timeread-only
updatedByuuid | nullread-only

Responses

  • 200Success.
12 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.UNKNOWN_TYPEUNKNOWN_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 410Gone.GONE
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/versions/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "versions",
    "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
    "attributes": {
      "updatedAt": "2026-10-05T09:30:00Z"
    },
    "links": {
      "self": "/versions/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

List fix versions

GET/api/v1/fix_versions

Lists fix version resources as a JSON:API collection document. Narrow the set with filter, order it with sort, embed related resources with include, select attributes with fields[<type>], and page with page[size] plus page[number] (offset) or page[after] (cursor, taken from the previous response's links.next).

Query parameters

filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
versionName = "example"
sortstring
Comma-separated sort fields; prefix a field with "-" for descending order (e.g. "-createdAt,title"). Permitted fields: id, organizationId, projectId, versionName, externalId.
-versionName
includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, project, updatedByUser.
createdByUser
fields[fix_versions]string[]
Sparse fieldset for resource type "fix_versions" - comma-separated subset of its exposed fields: id, organizationId, projectId, versionName, externalId, createdAt, updatedAt, createdBy, updatedBy, createdByUser, updatedByUser, organization, project.
versionName,createdAt,updatedAt
page[size]integer
Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25
page[number]integer
1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2
page[after]string
Opaque cursor for cursor-based pagination - always taken verbatim from a previous response's "links.next" value, never client-constructed or decoded. Mutually exclusive with "page[number]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields9

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
projectIduuid= != in (…) not in (…) is null is not null
versionNamestring= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example createdByUser ANY (id = "…"). Relations: createdByUser, organization, project, updatedByUser, testCampaignFixVersions.

Returns the same attributes as Get a fix version.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INVALID_TYPED_JSON_FILTERUNKNOWN_SORT_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDUNKNOWN_TYPEUNKNOWN_FIELDCONFLICTING_PAGINATIONINVALID_PAGE_SIZEPAGE_SIZE_EXCEEDEDINVALID_PAGE_NUMBERINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/fix_versions?page%5Bsize%5D=25" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": [
    {
      "type": "fix_versions",
      "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
      "attributes": {
        "updatedAt": "2026-10-05T09:30:00Z"
      },
      "links": {
        "self": "/fix_versions/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
      }
    }
  ],
  "links": {
    "self": "/fix_versions?page[size]=25",
    "first": "/fix_versions?page[size]=25&page[number]=1",
    "prev": null,
    "next": "/fix_versions?page[size]=25&page[number]=2",
    "last": "/fix_versions?page[size]=25&page[number]=6"
  },
  "meta": {
    "totalCount": 128
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Count and aggregate fix versions

GET/api/v1/fix_versions/aggregate

Aggregates fix version resources - a count and per-column aggregations, optionally grouped - over the same filter the collection route accepts.

Query parameters

aggregations[count]boolean
Include the row count in the aggregate result. When no aggregation is requested at all, the runtime defaults to count.
aggregations[min][]string[]
Column(s) to take the minimum of - repeat the bracketed key per column (aggregations[min][]=a&aggregations[min][]=b). Permitted columns: versionName, externalId, createdAt, updatedAt.
aggregations[max][]string[]
Column(s) to take the maximum of - repeat the bracketed key per column (aggregations[max][]=a&aggregations[max][]=b). Permitted columns: versionName, externalId, createdAt, updatedAt.
aggregations[groupBy][]string[]
Column(s) to group by - repeating the bracketed key switches the response to the grouped shape (aggregations[groupBy][]=a&aggregations[groupBy][]=b). Permitted columns: id, organizationId, projectId, versionName, externalId.
filterstring
A FiltrQL expression, url-encoded. Combine conditions with AND / OR and parentheses. The fields you can filter on, and the operators each accepts, are listed under Filterable fields.
versionName = "example"

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Filterable fields9

Show fields and operators
FieldTypeOperators
iduuid= != in (…) not in (…) is null is not null
organizationIduuid= != in (…) not in (…) is null is not null
projectIduuid= != in (…) not in (…) is null is not null
versionNamestring= != in (…) not in (…) is null is not null
externalIdstring= != in (…) not in (…) is null is not null
createdAtdatetime= != < <= > >= is null is not null
updatedAtdatetime= != < <= > >= is null is not null
createdByuuid= != in (…) not in (…) is null is not null
updatedByuuid= != in (…) not in (…) is null is not null

Filter through a relation with ANY, ALL or NONE, for example createdByUser ANY (id = "…"). Relations: createdByUser, organization, project, updatedByUser, testCampaignFixVersions.

Responses

  • 200Success.
11 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.INPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/fix_versions/aggregate?aggregations%5Bcount%5D=true" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "fixVersions_aggregate",
    "id": "(aggregate)",
    "attributes": {
      "count": 128
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Get a fix version

GET/api/v1/fix_versions/{id}

Returns the fix version with this id as a JSON:API resource document; include embeds related resources and fields[<type>] selects the attributes returned.

Path parameters

iduuidrequired
The resource id (a UUID).

Query parameters

includestring
Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, project, updatedByUser.
createdByUser
fields[fix_versions]string[]
Sparse fieldset for resource type "fix_versions" - comma-separated subset of its exposed fields: id, organizationId, projectId, versionName, externalId, createdAt, updatedAt, createdBy, updatedBy, createdByUser, updatedByUser, organization, project.
versionName,createdAt,updatedAt

Headers

Authorizationstringrequired
Your API token as a bearer credential.
Bearer $BESTEST_TOKEN
Acceptstring
Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json

Attributes returned9

createdAtdate-timeread-only
createdByuuid | nullread-only
externalIdstring | null
iduuidread-only
organizationIduuidread-only
projectIduuid
updatedAtdate-timeread-only
updatedByuuid | nullread-only
Show the remaining 1
versionNamestring

Responses

  • 200Success.
12 error responses
  • 400The request is malformed: an unknown field, a filter that does not parse, or conflicting paging parameters.UNKNOWN_TYPEUNKNOWN_FIELDINCLUDE_DEPTH_EXCEEDEDUNKNOWN_RELATIONINCLUDE_RESOURCES_EXCEEDEDINPUT_DEPTH_EXCEEDEDGRAPHQL_PARSE_FAILEDGRAPHQL_VALIDATION_FAILEDBAD_USER_INPUT
  • 401The token has expired or could not be authenticated.TOKEN_EXPIREDUNAUTHENTICATED
  • 403The token is missing or not recognised, belongs to another region, or is read-only and this is a write.FORBIDDEN
  • 404No such resource, or it is outside the Space your token reaches.NOT_FOUND
  • 406The Accept header asked for something other than application/vnd.api+json.NOT_ACCEPTABLE
  • 409The write conflicts with existing data, for example a duplicate or a reference to something that does not exist.UNIQUE_VIOLATIONFOREIGN_KEY_VIOLATIONCONFLICT
  • 410Gone.GONE
  • 415The Content-Type was not application/vnd.api+json.PARAMETERIZED_ACCEPT
  • 422The body is well-formed but a value is invalid, such as an enum outside its list or a missing required attribute.VALIDATION_FAILEDCHECK_VIOLATIONMISSING_REQUIREDATMOST_EXCEEDEDHOOK_ABORT
  • 429Rate limited (RATE_LIMITED). Limits are per person and shared with MCP. Back off a few seconds and retry.RATE_LIMITEDQUOTA_EXCEEDED
  • 500Server error. Safe to retry a read; check before retrying a write.INTERNAL_ERROR
  • 503Temporarily unavailable. Retry with backoff.UNAVAILABLE
Request

curl

curl "https://prod-eu.getbestest.com/api/v1/fix_versions/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33" \
  -H "Authorization: Bearer $BESTEST_TOKEN" \
  -H "Accept: application/vnd.api+json"
Response

application/vnd.api+json

{
  "data": {
    "type": "fix_versions",
    "id": "3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33",
    "attributes": {
      "updatedAt": "2026-10-05T09:30:00Z"
    },
    "links": {
      "self": "/fix_versions/3f2b9c14-8d5e-4a71-9f60-2c1e7b4a8d33"
    }
  },
  "jsonapi": {
    "version": "1.1"
  }
}
Show an error response
Error

every 4xx and 5xx has this shape

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "code": "UNKNOWN_FIELD",
      "detail": "Unknown field \"displayName\" on resource type \"users\". Valid fields: id, externalId, role, ...",
      "source": {
        "parameter": "fields[users]"
      }
    }
  ]
}

Related-resource endpoints

Each to-many relation has its own URL, such as a test case's steps or a cycle's executions. They return a paginated collection of the related resource and take that resource's own filter, sort, paging and fields parameters, so they are listed rather than documented one by one. For to-one relations, use ?include= on the parent request instead: one round trip instead of two.

Show all 119
  • GET/api/v1/projects/{id}/comments
  • GET/api/v1/projects/{id}/environments
  • GET/api/v1/projects/{id}/fixVersions
  • GET/api/v1/projects/{id}/gqlithCustomFields
  • GET/api/v1/projects/{id}/issues
  • GET/api/v1/projects/{id}/links
  • GET/api/v1/projects/{id}/requirementFolders
  • GET/api/v1/projects/{id}/requirements
  • GET/api/v1/projects/{id}/savedFilters
  • GET/api/v1/projects/{id}/testCampaignCycles
  • GET/api/v1/projects/{id}/testCampaignFixVersions
  • GET/api/v1/projects/{id}/testCampaignFolders
  • GET/api/v1/projects/{id}/testCampaigns
  • GET/api/v1/projects/{id}/testCaseExecutions
  • GET/api/v1/projects/{id}/testCaseFolders
  • GET/api/v1/projects/{id}/testCases
  • GET/api/v1/projects/{id}/testCollectionFolders
  • GET/api/v1/projects/{id}/testCollectionRequirements
  • GET/api/v1/projects/{id}/testCollections
  • GET/api/v1/projects/{id}/testCollectionTestCases
  • GET/api/v1/projects/{id}/testCycleFolders
  • GET/api/v1/projects/{id}/testCycles
  • GET/api/v1/projects/{id}/testStepExecutions
  • GET/api/v1/projects/{id}/testSteps
  • GET/api/v1/projects/{id}/versions
  • GET/api/v1/organizations/{id}/commentMentions
  • GET/api/v1/organizations/{id}/comments
  • GET/api/v1/organizations/{id}/environments
  • GET/api/v1/organizations/{id}/fixVersions
  • GET/api/v1/organizations/{id}/gqlithCustomFields
  • GET/api/v1/organizations/{id}/issues
  • GET/api/v1/organizations/{id}/links
  • GET/api/v1/organizations/{id}/projects
  • GET/api/v1/organizations/{id}/requirementFolders
  • GET/api/v1/organizations/{id}/requirements
  • GET/api/v1/organizations/{id}/savedFilters
  • GET/api/v1/organizations/{id}/testCampaignCycles
  • GET/api/v1/organizations/{id}/testCampaignFixVersions
  • GET/api/v1/organizations/{id}/testCampaignFolders
  • GET/api/v1/organizations/{id}/testCampaigns
  • GET/api/v1/organizations/{id}/testCaseExecutions
  • GET/api/v1/organizations/{id}/testCaseFolders
  • GET/api/v1/organizations/{id}/testCases
  • GET/api/v1/organizations/{id}/testCollectionFolders
  • GET/api/v1/organizations/{id}/testCollectionRequirements
  • GET/api/v1/organizations/{id}/testCollections
  • GET/api/v1/organizations/{id}/testCollectionTestCases
  • GET/api/v1/organizations/{id}/testCycleFolders
  • GET/api/v1/organizations/{id}/testCycles
  • GET/api/v1/organizations/{id}/testStepExecutions
  • GET/api/v1/organizations/{id}/testSteps
  • GET/api/v1/organizations/{id}/users
  • GET/api/v1/organizations/{id}/versions
  • GET/api/v1/users/{id}/assigneeTestCaseExecutions
  • GET/api/v1/users/{id}/assigneeTestCycles
  • GET/api/v1/users/{id}/authorComments
  • GET/api/v1/users/{id}/commentMentions
  • GET/api/v1/users/{id}/createdByComments
  • GET/api/v1/users/{id}/createdByEnvironments
  • GET/api/v1/users/{id}/createdByFixVersions
  • GET/api/v1/users/{id}/createdByIssues
  • GET/api/v1/users/{id}/createdByLinks
  • GET/api/v1/users/{id}/createdByProjects
  • GET/api/v1/users/{id}/createdByRequirementFolders
  • GET/api/v1/users/{id}/createdByRequirements
  • GET/api/v1/users/{id}/createdBySavedFilters
  • GET/api/v1/users/{id}/createdByTestCampaignCycles
  • GET/api/v1/users/{id}/createdByTestCampaignFixVersions
  • GET/api/v1/users/{id}/createdByTestCampaignFolders
  • GET/api/v1/users/{id}/createdByTestCampaigns
  • GET/api/v1/users/{id}/createdByTestCaseExecutions
  • GET/api/v1/users/{id}/createdByTestCaseFolders
  • GET/api/v1/users/{id}/createdByTestCases
  • GET/api/v1/users/{id}/createdByTestCollectionFolders
  • GET/api/v1/users/{id}/createdByTestCollectionRequirements
  • GET/api/v1/users/{id}/createdByTestCollections
  • GET/api/v1/users/{id}/createdByTestCollectionTestCases
  • GET/api/v1/users/{id}/createdByTestCycleFolders
  • GET/api/v1/users/{id}/createdByTestCycles
  • GET/api/v1/users/{id}/createdByTestStepExecutions
  • GET/api/v1/users/{id}/createdByTestSteps
  • GET/api/v1/users/{id}/createdByUsers
  • GET/api/v1/users/{id}/createdByVersions
  • GET/api/v1/users/{id}/defaultAssigneeTestCollectionTestCases
  • GET/api/v1/users/{id}/defaultRuleAssigneeTestCollections
  • GET/api/v1/users/{id}/formatModeChangedByTestCases
  • GET/api/v1/users/{id}/ownerRequirements
  • GET/api/v1/users/{id}/ownerTestCases
  • GET/api/v1/users/{id}/updatedByComments
  • GET/api/v1/users/{id}/updatedByEnvironments
  • GET/api/v1/users/{id}/updatedByFixVersions
  • GET/api/v1/users/{id}/updatedByIssues
  • GET/api/v1/users/{id}/updatedByLinks
  • GET/api/v1/users/{id}/updatedByProjects
  • GET/api/v1/users/{id}/updatedByRequirementFolders
  • GET/api/v1/users/{id}/updatedByRequirements
  • GET/api/v1/users/{id}/updatedBySavedFilters
  • GET/api/v1/users/{id}/updatedByTestCampaignCycles
  • GET/api/v1/users/{id}/updatedByTestCampaignFixVersions
  • GET/api/v1/users/{id}/updatedByTestCampaignFolders
  • GET/api/v1/users/{id}/updatedByTestCampaigns
  • GET/api/v1/users/{id}/updatedByTestCaseExecutions
  • GET/api/v1/users/{id}/updatedByTestCaseFolders
  • GET/api/v1/users/{id}/updatedByTestCases
  • GET/api/v1/users/{id}/updatedByTestCollectionFolders
  • GET/api/v1/users/{id}/updatedByTestCollectionRequirements
  • GET/api/v1/users/{id}/updatedByTestCollections
  • GET/api/v1/users/{id}/updatedByTestCollectionTestCases
  • GET/api/v1/users/{id}/updatedByTestCycleFolders
  • GET/api/v1/users/{id}/updatedByTestCycles
  • GET/api/v1/users/{id}/updatedByTestStepExecutions
  • GET/api/v1/users/{id}/updatedByTestSteps
  • GET/api/v1/users/{id}/updatedByUsers
  • GET/api/v1/users/{id}/updatedByVersions
  • GET/api/v1/environments/{id}/testCaseExecutions
  • GET/api/v1/environments/{id}/testCycles
  • GET/api/v1/versions/{id}/testCaseExecutions
  • GET/api/v1/versions/{id}/testCycles
  • GET/api/v1/fix_versions/{id}/testCampaignFixVersions