Run Cloud applications¶
Info
Learn the concepts and fundamentals of runs in the Explanation page.
A run is a single execution of an app against an instance. It is the basic functionality encompassed of receiving an input, running the app, and returning an output.
This how-to guide explains how to interact with runs using the
/v1/applications/{application_id}/runs endpoints. Go to the
reference section to see all the available
parameters for each endpoint.
There are limits for submitting a new run and retrieving the results. If your input (or output) exceeds those limits, use the upload URL endpoint shown in the multi-file section of this guide to work with large payloads.
Start and get a run¶
Use the POST /v1/applications/{application_id}/runs endpoint
to start a new run. The instance_id is passed as a query parameter, and the
json input data is passed in the input field of the request
payload. The endpoint returns a run_id that can be used to retrieve
information about the run, including metadata and results.
Retrieve the run information using the run_id with the
GET /v1/applications/{application_id}/runs/{run_id}/metadata
endpoint. The result includes important metadata, such as the status.
{
"id": "latest-Lfjm3UPvg",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"metadata": {
"status": "succeeded",
"status_v2": "succeeded",
"created_at": "2026-07-29T05:33:44Z",
"initiated_at": "2026-07-29T05:33:45.354762332Z",
"duration": 5397,
"execution_duration": 4537,
"input_size": 52,
"output_size": 913,
"error": "",
"application_id": "uncanny-rodent",
"application_instance_id": "latest",
"application_version_id": "",
"execution_class": "6c9500mb870s",
"runtime": "python-3_11",
"run_type": {
"type": "standard",
"definition_id": "",
"reference_id": ""
},
"format": {
"input": {
"type": "json"
},
"output": {
"type": "json"
}
},
"options": {
"active_options": {
"details": "true"
},
"request_options": null,
"options_summary": [
{
"name": "details",
"value": "true",
"source": "version"
}
]
},
"queuing_priority": 6,
"queuing_disabled": false,
"metrics": {
"message": "Hello, world",
"value": 1.23
}
}
}
Use the .metadata.status_v2 field to determine the status of the run. Please
read our documentation on run polling to learn how to wait for a
run to finish before retrieving its results.
Once the run completes, you can retrieve the results using the run_id with
the GET /v1/applications/{application_id}/runs/{run_id}
endpoint. The response includes the output of the run, along with the run
information.
{
"id": "latest-Lfjm3UPvg",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"metadata": {
"status": "succeeded",
"status_v2": "succeeded",
"created_at": "2026-07-29T05:33:44Z",
"initiated_at": "2026-07-29T05:33:45.354762332Z",
"duration": 5397,
"execution_duration": 4537,
"input_size": 52,
"output_size": 913,
"error": "",
"application_id": "uncanny-rodent",
"application_instance_id": "latest",
"application_version_id": "",
"execution_class": "6c9500mb870s",
"runtime": "python-3_11",
"run_type": {
"type": "standard",
"definition_id": "",
"reference_id": ""
},
"format": {
"input": {
"type": "json"
},
"output": {
"type": "json"
}
},
"options": {
"active_options": {
"details": "true"
},
"request_options": null,
"options_summary": [
{
"name": "details",
"value": "true",
"source": "version"
}
]
},
"queuing_priority": 6,
"queuing_disabled": false,
"metrics": {
"message": "Hello, world",
"value": 1.23
}
},
"output": {
"options": {
"details": true
},
"solution": {
"message": "Hello, world"
},
"metrics": {
"value": 1.23,
"message": "Hello, world"
}
}
}
.output.assets was removed from the response above for a cleaner display.
Run with options¶
If an application is designed to accept options, you can pass
them when starting a run using the options field in the request payload.
The format for the options is a JSON object of string keys and string values.
curl -s -X POST "https://api.cloud.nextmv.io/v1/applications/uncanny-rodent/runs?instance_id=latest" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"input": {"name": "world", "radius": 6378, "distance": 147.6},
"options": {"details": "false"}
}' \
| jq '.'
Once the run finishes, fetch its result with the same
GET /v1/applications/{application_id}/runs/{run_id}
endpoint used above.
{
"id": "latest-jZlWq8PDR",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"metadata": {
"status": "succeeded",
"status_v2": "succeeded",
"created_at": "2026-07-29T05:34:14Z",
"initiated_at": "2026-07-29T05:34:14.374125279Z",
"duration": 3986,
"execution_duration": 3701,
"input_size": 52,
"output_size": 914,
"error": "",
"application_id": "uncanny-rodent",
"application_instance_id": "latest",
"application_version_id": "",
"execution_class": "6c9500mb870s",
"runtime": "python-3_11",
"run_type": {
"type": "standard",
"definition_id": "",
"reference_id": ""
},
"format": {
"input": {
"type": "json"
},
"output": {
"type": "json"
}
},
"options": {
"active_options": {
"details": "false"
},
"request_options": {
"details": "false"
},
"options_summary": [
{
"name": "details",
"value": "false",
"source": "run"
}
]
},
"queuing_priority": 6,
"queuing_disabled": false,
"metrics": {
"message": "Hello, world",
"value": 1.23
}
},
"output": {
"options": {
"details": false
},
"solution": {
"message": "Hello, world"
},
"metrics": {
"value": 1.23,
"message": "Hello, world"
}
}
}
List runs¶
Use the GET /v1/applications/{application_id}/runs endpoint
to list all runs for an application. This endpoint is paginated, so the
snippet below always uses pagination: it keeps requesting pages by passing the
next_page_token value returned in each response as the pagetoken query
parameter, until no token is returned.
ITEMS="[]"
PAGE_TOKEN=""
while :; do
RESPONSE=$(curl -s -G "https://api.cloud.nextmv.io/v1/applications/uncanny-rodent/runs" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
--data-urlencode "limit=50" \
--data-urlencode "pagetoken=${PAGE_TOKEN}")
ITEMS=$(jq -n --argjson existing "$ITEMS" --argjson page "$(echo "$RESPONSE" | jq '.runs')" '$existing + $page')
PAGE_TOKEN=$(echo "$RESPONSE" | jq -r '.next_page_token // empty')
[ -z "$PAGE_TOKEN" ] && break
done
echo "$ITEMS" | jq '.'
[
{
"id": "latest-jZlWq8PDR",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"created_at": "2026-07-29T05:34:14.14158846Z",
"application_id": "uncanny-rodent",
"application_instance_id": "latest",
"application_version_id": "",
"run_type": {
"type": "standard",
"definition_id": "",
"reference_id": ""
},
"execution_class": "6c9500mb870s",
"queuing_priority": 6,
"queuing_disabled": false,
"runtime": "python-3_11",
"status": "succeeded",
"status_v2": "succeeded",
"options": {
"details": "false"
},
"request_options": {
"details": "false"
},
"options_summary": [
{
"name": "details",
"value": "false",
"source": "run"
}
]
},
...
]
You can also filter the query by passing the start and end query
parameters (RFC3339 timestamps), and include experiment, shadow, or ensemble
child runs with the include_exp_runs, include_shad_runs, and
include_ens_runs query parameters, respectively.
Get run logs¶
The Nextmv platform stores logs for applications that correctly implement
logging. Each run that produces logs will have them available
for inspection. You can retrieve the logs for a finished run using the
GET /v1/applications/{application_id}/runs/{run_id}/logs
endpoint.
If a run is still in a running state, use the
GET /v1/applications/{application_id}/runs/{run_id}/logs/live
endpoint instead, which returns log lines produced so far (retained for 13
hours). Each response includes a status_v2 field and, while the run is not
finalized, a next_available_in_seconds hint for when to poll again. If more
log lines are available than fit in a single response, a next_page_token is
also returned, which can be passed back as the since query parameter to
continue reading from where you left off.
Get the input of a run¶
As a DecisionOps platform, Nextmv is focused on reproducibility. This means
that you can always retrieve the input of a run using the
GET /v1/applications/{application_id}/runs/{run_id}/input
endpoint.
If the input is large, or its content format is not json, the
response instead contains a url field (pass format=url as a query
parameter to always get this shape) that you can use to download the raw
input file.
Cancel a run¶
You can cancel a run that is in these states using the
PATCH /v1/applications/{application_id}/runs/{run_id}/cancel
endpoint.
Run multi-file and large inputs¶
Up to now in this how-to guide, we have been using the json content
format for showing how to run applications. The Nextmv platform
also supports the multi-file content format for running
applications. When you run with the multi-file content format, input data is
provided from one or more files.
When running json content format runs that exceed the
limits for input or output, you can also use this methodology to
submit runs with large payloads.
The steps for running multi-file or a large payload are as follows:
- Package the input files into a
tar.gzfile. - Request an upload URL with the
POST /v1/applications/{application_id}/runs/uploadurlendpoint. - Upload the packaged input files directly to that URL.
- Start the run using the returned
upload_idinstead ofinput. - Retrieve the result using the
GET /v1/applications/{application_id}/runs/{run_id}endpoint, passingformat=urlas a query parameter to get a URL for downloading the output as atar.gzfile. - Extract the output files from the downloaded
tar.gzfile.
For this example, assume the input data lives in a directory called inputs.
tar -czf inputs.tar.gz -C inputs .
UPLOAD_RESPONSE=$(curl -s -X POST "https://api.cloud.nextmv.io/v1/applications/uncanny-rodent/runs/uploadurl" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}")
UPLOAD_URL=$(echo "$UPLOAD_RESPONSE" | jq -r '.upload_url')
UPLOAD_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.upload_id')
curl -s -X PUT "$UPLOAD_URL" --data-binary @inputs.tar.gz
curl -s -X POST "https://api.cloud.nextmv.io/v1/applications/uncanny-rodent/runs?instance_id=multi-file" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
-H "Content-Type: application/json" \
-d "{
\"upload_id\": \"${UPLOAD_ID}\"
}" \
| jq '.'
You can use all the same endpoints to get the run information and logs as
shown in previous sections of this how-to guide. The difference lies in
getting the result: because the output is not json, the
GET /v1/applications/{application_id}/runs/{run_id}
endpoint returns a 400 error asking you to pass format=url as a query
parameter instead. That returns a url you can use to download the output as
a tar.gz file, which you then extract into a directory of your choosing.
DOWNLOAD_URL=$(curl -s -G "https://api.cloud.nextmv.io/v1/applications/uncanny-rodent/runs/multi-file-a_KrVqUPvg" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
--data-urlencode "format=url" \
| jq -r '.output.url')
mkdir -p outputs
curl -s "$DOWNLOAD_URL" -o output.tar.gz
tar -xzf output.tar.gz -C outputs
find outputs -type f
Normally, you specify the content format of the application in the app.yaml
manifest, but you can also override it when starting a run with the
configuration field.