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
/api/v1/projectsLists 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.
-projectKeyincludestring- Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, updatedByUser.
createdByUserfields[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,updatedAtpage[size]integer- Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25page[number]integer- 1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2page[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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
projectKey | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != 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
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"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
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
/api/v1/projects/aggregateAggregates 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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
projectKey | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != 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
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"application/vnd.api+json
{
"data": {
"type": "projects_aggregate",
"id": "(aggregate)",
"attributes": {
"count": 128
}
},
"jsonapi": {
"version": "1.1"
}
}Show an error response
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
/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.
createdByUserfields[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_TOKENAcceptstring- 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-onlycreatedByuuid | nullread-onlyexternalIdstring | nulliduuidread-onlyorganizationIduuidread-onlyprojectKeystringupdatedAtdate-timeread-onlyupdatedByuuid | 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
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"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
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
/api/v1/organizationsLists 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,idpage[size]integer- Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25page[number]integer- 1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2page[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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= 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
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"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
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
/api/v1/organizations/aggregateAggregates 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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= 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
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"application/vnd.api+json
{
"data": {
"type": "organizations_aggregate",
"id": "(aggregate)",
"attributes": {
"count": 128
}
},
"jsonapi": {
"version": "1.1"
}
}Show an error response
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
/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_TOKENAcceptstring- Send application/vnd.api+json, or leave it out. Asking for application/json returns 406 Not Acceptable.
application/vnd.api+json
Attributes returned4
createdAtdate-timeexternalIdstring | nulliduuidread-onlyupdatedAtdate-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
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"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
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
/api/v1/usersLists 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.
createdByUserfields[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,createdBypage[size]integer- Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25page[number]integer- 1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2page[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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != in (…) not in (…) is null is not null |
role | string | = != 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
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"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
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
/api/v1/users/aggregateAggregates 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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != in (…) not in (…) is null is not null |
role | string | = != 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
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"application/vnd.api+json
{
"data": {
"type": "users_aggregate",
"id": "(aggregate)",
"attributes": {
"count": 128
}
},
"jsonapi": {
"version": "1.1"
}
}Show an error response
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
/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.
createdByUserfields[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_TOKENAcceptstring- 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-onlycreatedByuuid | nullread-onlyexternalIdstring | nulliduuidread-onlyorganizationIduuidread-onlyrolestringdefaultmemberupdatedAtdate-timeread-onlyupdatedByuuid | 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
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"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
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
/api/v1/environmentsLists 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.
-nameincludestring- Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, project, updatedByUser.
createdByUserfields[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,updatedAtpage[size]integer- Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25page[number]integer- 1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2page[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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
projectId | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
name | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != 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
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"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
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
/api/v1/environments/aggregateAggregates 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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
projectId | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
name | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != 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
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"application/vnd.api+json
{
"data": {
"type": "environments_aggregate",
"id": "(aggregate)",
"attributes": {
"count": 128
}
},
"jsonapi": {
"version": "1.1"
}
}Show an error response
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
/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.
createdByUserfields[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_TOKENAcceptstring- 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-onlycreatedByuuid | nullread-onlyexternalIdstring | nulliduuidread-onlynamestringorganizationIduuidread-onlyprojectIduuidupdatedAtdate-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
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"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
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
/api/v1/versionsLists 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.
createdByUserfields[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,createdBypage[size]integer- Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25page[number]integer- 1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2page[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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
projectId | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != 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
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"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
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
/api/v1/versions/aggregateAggregates 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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
projectId | uuid | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != 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
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"application/vnd.api+json
{
"data": {
"type": "versions_aggregate",
"id": "(aggregate)",
"attributes": {
"count": 128
}
},
"jsonapi": {
"version": "1.1"
}
}Show an error response
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
/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.
createdByUserfields[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_TOKENAcceptstring- 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-onlycreatedByuuid | nullread-onlyexternalIdstring | nulliduuidread-onlyorganizationIduuidread-onlyprojectIduuidupdatedAtdate-timeread-onlyupdatedByuuid | 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
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"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
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
/api/v1/fix_versionsLists 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.
-versionNameincludestring- Comma-separated relation names to include; dot-notation for nested includes (up to 3 levels deep). Permitted top-level relations: createdByUser, organization, project, updatedByUser.
createdByUserfields[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,updatedAtpage[size]integer- Number of resources per page (applies to both offset and cursor pagination). Minimum 1, maximum 100, default 25 when omitted.
25page[number]integer- 1-indexed page number for offset-based pagination. Mutually exclusive with "page[after]" - supplying both is rejected with a 400 (CONFLICTING_PAGINATION).
2page[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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
projectId | uuid | = != in (…) not in (…) is null is not null |
versionName | string | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != 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
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"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
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
/api/v1/fix_versions/aggregateAggregates 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_TOKENAcceptstring- 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
| Field | Type | Operators |
|---|---|---|
id | uuid | = != in (…) not in (…) is null is not null |
organizationId | uuid | = != in (…) not in (…) is null is not null |
projectId | uuid | = != in (…) not in (…) is null is not null |
versionName | string | = != in (…) not in (…) is null is not null |
externalId | string | = != in (…) not in (…) is null is not null |
createdAt | datetime | = != < <= > >= is null is not null |
updatedAt | datetime | = != < <= > >= is null is not null |
createdBy | uuid | = != in (…) not in (…) is null is not null |
updatedBy | uuid | = != 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
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"application/vnd.api+json
{
"data": {
"type": "fixVersions_aggregate",
"id": "(aggregate)",
"attributes": {
"count": 128
}
},
"jsonapi": {
"version": "1.1"
}
}Show an error response
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
/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.
createdByUserfields[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_TOKENAcceptstring- 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-onlycreatedByuuid | nullread-onlyexternalIdstring | nulliduuidread-onlyorganizationIduuidread-onlyprojectIduuidupdatedAtdate-timeread-onlyupdatedByuuid | 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
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"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
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
