The cases namespace provides API methods for getting, adding,
updating or deleting cases from a Testmo project. The following endpoints
allow single and bulk operations
-
GET
projects/{project_id}/cases -
POST
projects/{project_id}/cases -
PATCH
projects/{project_id}/cases -
DELETE
projects/{project_id}/cases -
GET
projects/{project_id}/cases/{case_id}/result-history -
GET
projects/{project_id}/templates -
GET
projects/{project_id}/repos -
GET
projects/{project_id}/tags
GET /projects/{project_id}/cases
Returns a list of cases from the specified project.
This method uses pagination so you might need to request additional pages to retrieve all results.
project_id id required
ID of the project.
Request
page integer
Number of page to return (default: first page).
per_page integer
Maximum number of cases to return (supported: 15,
25, 50, 100; default:
100).
order string
Sort order (supported: asc, desc; default:
asc).
sort string
Sort field for the list of cases (supported:
repository_cases:created_at,
repository_cases:name,
repository_cases:has_automation_status; default:
repository_cases:created_at).
name string
Filter cases by name (partial match, max 255 characters).
folder_id string
Comma-separated list of folder IDs to filter by. Use with
recursive=true to include cases from all sub-folders.
recursive boolean
When true, returns cases from all sub-folders of
the specified folder_id (default: false).
template_id string
Comma-separated list of template IDs to filter by.
state_id string
Comma-separated list of state IDs to filter by.
status_id string
Comma-separated list of status IDs to filter by.
priority string
Comma-separated list of priority IDs to filter by.
tags string
Comma-separated list of tag names or IDs to filter by. Use with
tag_match to control matching behaviour.
tag_match string
Controls how multiple tags values are matched (supported:
any, all; default: any).
created_after string
Limit results to cases created after this date/time (ISO 8601,
UTC; e.g. 2025-06-01T00:00:00Z or 2025-06-01).
created_before string
Limit results to cases created before this date/time (ISO 8601,
UTC; e.g. 2025-06-30T23:59:59Z or 2025-06-30).
updated_from string
Limit results to cases updated on or after this date/time (ISO
8601, UTC; e.g. 2025-06-01T00:00:00Z or
2025-06-01).
updated_to string
Limit results to cases updated on or before this date/time (ISO
8601, UTC; e.g. 2025-06-30T23:59:59Z or
2025-06-30).
updated_by string
Comma-separated list of user IDs to filter by last-updated user.
has_automation boolean
Filter cases with (true) or without (false)
automation links.
has_automation_status boolean
Filter cases with (true) or without (false)
an automation status.
expands string
Comma-separated list of expands to return.
{
"page": {
"type": "integer",
"format": "int64",
"description": "Number of page to return (default: first page)."
},
"per_page": {
"type": "integer",
"format": "int64",
"enum": [15, 25, 50, 100],
"description": "Maximum number of items to return per page (default: 100)."
},
"order": {
"type": "string",
"enum": ["asc", "desc"],
"default": "asc",
"description": "Sort order (ascending or descending)."
},
"sort": {
"type": "string",
"enum": [
"repository_cases:created_at",
"repository_cases:name",
"repository_cases:has_automation_status",
"repository_cases:state_id",
"repository_cases:status_id",
"repository_cases:template_id",
"repository_cases:updated_at"
],
"default": "repository_cases:created_at",
"description": "Sort field for the list of cases."
},
"name": {
"type": "string",
"description": "Filter cases by name (partial match, max 255 characters)."
},
"folder_id": {
"type": "string",
"description": "Comma-separated list of folder IDs to filter by."
},
"recursive": {
"type": "boolean",
"description": "When true, returns cases from all sub-folders of the specified folder_id."
},
"template_id": {
"type": "string",
"description": "Comma-separated list of template IDs to filter by."
},
"state_id": {
"type": "string",
"description": "Comma-separated list of state IDs to filter by."
},
"status_id": {
"type": "string",
"description": "Comma-separated list of status IDs to filter by."
},
"priority": {
"type": "string",
"description": "Comma-separated list of priority IDs to filter by."
},
"tags": {
"type": "string",
"description": "Comma-separated list of tag names or IDs to filter by."
},
"tag_match": {
"type": "string",
"enum": ["any", "all"],
"default": "any",
"description": "Controls how multiple tags values are matched."
},
"created_after": {
"type": "string",
"format": "date-time",
"description": "Limit results to cases created after this date/time (ISO 8601, UTC)."
},
"created_before": {
"type": "string",
"format": "date-time",
"description": "Limit results to cases created before this date/time (ISO 8601, UTC)."
},
"updated_from": {
"type": "string",
"format": "date-time",
"description": "Limit results to cases updated on or after this date/time (ISO 8601, UTC)."
},
"updated_to": {
"type": "string",
"format": "date-time",
"description": "Limit results to cases updated on or before this date/time (ISO 8601, UTC)."
},
"updated_by": {
"type": "string",
"description": "Comma-separated list of user IDs to filter by last-updated user."
},
"has_automation": {
"type": "boolean",
"description": "Filter cases with (true) or without (false) automation links."
},
"has_automation_status": {
"type": "boolean",
"description": "Filter cases with (true) or without (false) automation status."
},
"expands": {
"type": "string",
"description": "Comma-separated list of expands to return (automation_links, comments, folders, history, tags, templates, users)."
}
}
This method supports the following expands so you can automatically include additional information for referenced objects:
-
automation_links -
comments -
folders -
history -
tags -
templates -
users
Response
GET /api/v1/projects/1/cases
200 OK
{
"page": 1,
"prev_page": null,
"next_page": 2,
"last_page": 31,
"per_page": 100,
"total": 3042,
"result": [
{
"id": 35802,
"estimate": null,
"folder_id": 1,
"forecast": null,
"has_automation": false,
"has_automation_status": false,
"key": 35802,
"name": "Verify login with valid credentials",
"project_id": 1,
"repo_id": 1,
"state_id": 4,
"status_id": null,
"status_at": null,
"template_id": 2,
"created_at": "2025-09-22T08:36:02.572541Z",
"created_by": 1,
"updated_at": "2025-09-22T08:44:19.455334Z",
"updated_by": 1,
"custom_priority": 2,
"custom_steps": [
{
"column_name": "custom_steps",
"id": 1,
"case_id": 35802,
"text1": "<p>Navigate to login page</p>",
"text2": null,
"text3": "<p>Login page is displayed</p>",
"text4": null,
"display_order": 1
}
]
},
..
]
}
Examples
// Filter by name (partial match)
GET /api/v1/projects/1/cases?name=login
// Filter by folder and include all sub-folders
GET /api/v1/projects/1/cases?folder_id=10&recursive=true
// Filter by template
GET /api/v1/projects/1/cases?template_id=3
// Filter by tags (cases matching any of the listed tags)
GET /api/v1/projects/1/cases?tags=smoke,regression
// Filter by tags (cases matching all listed tags)
GET /api/v1/projects/1/cases?tags=smoke,regression&tag_match=all
// Filter by priority
GET /api/v1/projects/1/cases?priority=1,2
// Filter by date range (cases created in June 2025)
GET /api/v1/projects/1/cases?created_after=2025-06-01&created_before=2025-06-30
// Filter by last updated date range
GET /api/v1/projects/1/cases?updated_from=2025-09-01&updated_to=2025-09-30
// Include tags and automation links
GET /api/v1/projects/1/cases?expands=tags,automation_links
// Paginate through results
GET /api/v1/projects/1/cases?page=2&per_page=50
Status codes
200 401 403 404
422 429 (details)
POST /projects/{project_id}/cases
Creates one or more test cases (minimum 1, maximum 100 per request).
Where case details aren't provided, default settings from the administration area will be used. If a folder isn't specified, one will be created automatically.
Custom fields are specified with the custom_ prefix. Fields
that are not defined in the case's template will return a 422
validation error. Restricted custom fields require appropriate user permissions
(403 Forbidden if user lacks permission).
project_id id required
ID of the project.
Request
cases array required
Array of case objects to create.
name string required
The name of the test case.
folder_id integer
A valid folder ID to which the case should be added. A folder
will be created automatically if not specified.
template_id integer
A valid template ID to apply to the test case. Uses the project
default if not specified.
state_id integer
A valid state ID to apply to the test case.
estimate integer
Estimated execution duration in seconds.
automation_links array
Array of automation links to apply to the test case (automation_case_id,
name, automation_source_id).
issues array
Array of issues to link to the test case (display_id,
integration_id, connection_project_id
for GitHub and GitLab issues).
tags array
Array of tag strings to apply to the test case.
custom_* various
Any custom fields defined for the case's template, specified
with the custom_ prefix (e.g.
custom_priority, custom_steps). Fields
not defined in the template will return a 422 error.
{
"cases": {
"type": "array",
"description": "Array of test case objects to create (minimum 1, maximum 100).",
"minItems": 1,
"maxItems": 100,
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the test case (required)."
},
"folder_id": {
"type": "integer",
"format": "int64",
"nullable": true,
"description": "Folder ID. A folder is created automatically if not provided."
},
"template_id": {
"type": "integer",
"format": "int64",
"description": "Template ID. Uses project default if not specified."
},
"state_id": {
"type": "integer",
"format": "int64",
"description": "State ID to apply to the case."
},
"estimate": {
"type": "integer",
"format": "int64",
"description": "Estimated execution duration in seconds."
},
"automation_links": {
"type": "array",
"description": "Array of automation link objects (automation_case_id, name, automation_source_id)."
},
"issues": {
"type": "array",
"description": "Array of issue objects (display_id, integration_id, connection_project_id)."
},
"tags": {
"type": "array",
"items": { "type": "string" },
"description": "Array of tag strings."
}
},
"required": ["name"]
}
}
}
Example
POST /api/v1/projects/1/cases
{
"cases": [
{
"name": "Verify user login",
"folder_id": 10,
"template_id": 2,
"state_id": 2,
"estimate": 120,
"custom_priority": 1,
"custom_steps": [
{
"text1": "<p>Navigate to login page</p>",
"text3": "<p>Login page is displayed</p>"
},
{
"text1": "<p>Enter valid credentials and click Login</p>",
"text3": "<p>User is authenticated and redirected to dashboard</p>"
}
],
"tags": ["smoke", "authentication"],
"issues": [
{
"display_id": "ABC-123",
"integration_id": 3
}
]
}
]
}
201 Created
{
"result": [
{
"id": 35812,
"estimate": 120,
"folder_id": 10,
"forecast": 120,
"has_automation": false,
"has_automation_status": false,
"key": 35812,
"name": "Verify user login",
"project_id": 1,
"repo_id": 1,
"state_id": 2,
"status_id": null,
"status_at": null,
"template_id": 2,
"created_at": "2025-09-24T08:26:09.366217Z",
"created_by": 1,
"updated_at": null,
"updated_by": null,
"custom_priority": 1,
"custom_steps": [
{
"column_name": "custom_steps",
"id": 4,
"case_id": 35812,
"text1": "<p>Navigate to login page</p>",
"text2": null,
"text3": "<p>Login page is displayed</p>",
"text4": null,
"display_order": 1
}
]
}
]
}
Status codes
201 400 401 403
404 422 429 (details)
PATCH /projects/{project_id}/cases
Bulk updates up to 100 cases (minimum 1, maximum 100).
When updating cases with different templates, custom fields must exist in
ALL templates or a 422 error will be returned.
project_id id required
ID of the project.
Request
ids array required
Array of case IDs to update (minimum 1, maximum 100).
name string
The name to apply to the test cases.
folder_id integer
A valid folder ID to move the cases to.
state_id integer
A valid state ID to apply to the test cases.
status_id integer
A valid status ID to apply to the test cases.
estimate integer
Estimated execution duration in seconds.
automation_links array
Array of automation links to apply (automation_case_id,
name, automation_source_id).
issues array
Array of issues to link (display_id,
integration_id, connection_project_id
for GitHub and GitLab issues).
tags array
Array of tag strings to apply to the test cases.
custom_* various
Any custom field specified with the custom_ prefix.
When updating cases with different templates, the field must
exist in all templates.
{
"ids": {
"type": "array",
"description": "Array of case IDs to update (minimum 1, maximum 100).",
"minItems": 1,
"maxItems": 100,
"items": { "type": "integer", "format": "int64" }
},
"name": {
"type": "string",
"description": "New name for the test cases."
},
"folder_id": {
"type": "integer",
"format": "int64",
"description": "New folder ID."
},
"state_id": {
"type": "integer",
"format": "int64",
"description": "New state ID to apply."
},
"status_id": {
"type": "integer",
"format": "int64",
"description": "New status ID to apply."
},
"estimate": {
"type": "integer",
"format": "int64",
"description": "New estimated execution duration in seconds."
},
"automation_links": {
"type": "array",
"description": "Array of automation link objects."
},
"issues": {
"type": "array",
"description": "Array of issue objects."
},
"tags": {
"type": "array",
"items": { "type": "string" },
"description": "Array of tag strings."
}
}
Example
PATCH /api/v1/projects/1/cases
{
"ids": [1, 2, 3, 4, 5],
"folder_id": 1,
"state_id": 1,
"estimate": 200,
"custom_priority": 1,
"tags": ["authentication"],
"automation_links": [1, 2, 3]
}
200 OK
{
"result": [
{
"id": 1,
"estimate": 200,
"folder_id": 1,
"forecast": 200,
"has_automation": false,
"has_automation_status": false,
"key": 1,
"name": "Verify login with valid credentials",
"project_id": 1,
"repo_id": 1,
"state_id": 1,
"status_id": 2,
"status_at": "2025-09-10T14:16:32.619735Z",
"template_id": 3,
"created_at": "2025-09-19T14:13:40.616240Z",
"created_by": 1,
"updated_at": "2025-09-24T08:48:14.365222Z",
"updated_by": 1,
"custom_priority": 1,
"custom_description": null,
"custom_expected": null
},
..
]
}
Status codes
200 400 401 403
404 422 429 (details)
DELETE /projects/{project_id}/cases
Deletes up to 100 cases (minimum 1, maximum 100).
project_id id required
ID of the project.
Request
ids array required
Array of case IDs to delete (minimum 1, maximum 100).
{
"ids": {
"type": "array",
"description": "Array of case IDs to delete (minimum 1, maximum 100).",
"minItems": 1,
"maxItems": 100,
"items": { "type": "integer", "format": "int64" }
}
}
Returns a 204 no content response.
Example
DELETE /api/v1/projects/1/cases
{
"ids": [1, 2, 3, 4, 5]
}
204 No Content
Status codes
204 401 403 404
429 (details)
GET /projects/{project_id}/cases/{case_id}/result-history
Returns a paginated list of test results recorded against the specified case across all runs.
This method uses pagination so you might need to request additional pages to retrieve all results. Results are always returned in descending order by date (most recent first).
project_id id required
ID of the project.
case_id id required
ID of the test case.
Request
page integer
Number of page to return (default: first page).
per_page integer
Maximum number of results to return (supported: 15,
25, 50, 100; default:
100).
{
"page": {
"type": "integer",
"format": "int64",
"description": "Number of page to return (default: first page)."
},
"per_page": {
"type": "integer",
"format": "int64",
"enum": [15, 25, 50, 100],
"description": "Maximum number of items to return per page (default: 100)."
}
}
Response
GET /api/v1/projects/1/cases/35802/result-history
200 OK
{
"page": 1,
"prev_page": null,
"next_page": null,
"last_page": 1,
"per_page": 100,
"total": 3,
"result": [
{
"id": 1042,
"project_id": 1,
"run_id": 87,
"test_id": 4201,
"case_id": 35802,
"status_id": 2,
"note": "Passed after fixing environment config",
"elapsed": 45,
"assignee_id": 3,
"created_at": "2025-09-24T09:14:22.000000Z",
"created_by": 3,
"updated_at": "2025-09-24T09:14:22.000000Z",
"updated_by": 3
},
..
]
}
Examples
// Get result history for a case
GET /api/v1/projects/1/cases/35802/result-history
// Paginate through results
GET /api/v1/projects/1/cases/35802/result-history?page=2&per_page=50
Status codes
200 401 403 404
429 (details)
GET /projects/{project_id}/templates
Returns the list of templates available for test cases in the specified project, including each template's field definitions. Use this endpoint to discover available templates and their fields before creating or filtering cases.
project_id id required
ID of the project.
Response
GET /api/v1/projects/1/templates
200 OK
{
"result": [
{
"id": 1,
"name": "Default Template",
"is_default": true,
"fields": [
{
"id": 1,
"name": "Priority",
"type": 8,
"options": [
{ "id": 1, "value": "Critical" },
{ "id": 2, "value": "High" },
{ "id": 3, "value": "Medium" },
{ "id": 4, "value": "Low" }
]
}
]
},
{
"id": 2,
"name": "Steps Template",
"is_default": false,
"fields": [
{
"id": 1,
"name": "Priority",
"type": 8,
"options": [
{ "id": 1, "value": "Critical" },
{ "id": 2, "value": "High" },
{ "id": 3, "value": "Medium" },
{ "id": 4, "value": "Low" }
]
},
{
"id": 2,
"name": "Steps",
"type": 10
}
]
},
..
]
}
The type field in each field definition indicates the field
type:
-
1— String -
2— Text -
3— Integer -
4— Float -
5— Date -
6— URL -
7— Checkbox -
8— Dropdown (includesoptionsarray) -
9— Multi-select (includesoptionsarray) -
10— Steps
Status codes
200 401 403 404
429 (details)
GET /projects/{project_id}/repos
Returns the list of test case repositories for the specified project. Each project has a default (master) repository. This endpoint can be used to retrieve repository IDs for use in other API calls.
project_id id required
ID of the project.
Response
GET /api/v1/projects/1/repos
200 OK
{
"result": [
{
"id": 1,
"name": "Main Repository",
"is_default": true
}
]
}
Status codes
200 401 403 404
429 (details)
GET /projects/{project_id}/tags
Returns the list of tags defined in the specified project, along with a usage
count for each tag. Use this endpoint to discover available tag names and
IDs for use with the tags filter on the cases endpoint.
project_id id required
ID of the project.
Response
GET /api/v1/projects/1/tags
200 OK
{
"result": [
{
"id": 1,
"name": "smoke",
"usage_count": 42
},
{
"id": 2,
"name": "regression",
"usage_count": 118
},
{
"id": 3,
"name": "authentication",
"usage_count": 27
},
..
]
}
Status codes
200 401 403 404
429 (details)