Using secret collections¶
Info
Learn the concepts and fundamentals of secret collections in the Explanation page.
A secret collection defines one or more secrets used by your optimization model during execution. You can attach secret collections to an instance configuration, or directly when starting a run.
This how-to guide explains how to interact with secret collections using the
/v1/applications/{application_id}/secrets endpoints. Go to the
reference section to see all the available
parameters for each endpoint.
Create a secrets collection¶
Use the POST /v1/applications/{application_id}/secrets
endpoint to create a new secret collection for an application. Pass the
secrets field in the request payload as a list of
ApplicationSecret objects. Each secret has the
following attributes:
type: Eitherenvorfile, which determines how the secret is injected into the runtime.location: Where to place the secret.env: the environment variable name. E.g.:BURROW_ENTRANCE.file: the relative path from the execution directory. E.g.:licenses/burrow.entr.
value: The secret value as text (limited to 1 KB).
Here is an example that uses both secrets defined above to create a secrets
collection. Unlike applications, the endpoint requires an id and a name
in the request payload, so generate them yourself if you don't want to
choose custom values:
SECRETS_ID="secrets-$(openssl rand -hex 4)"
curl -s -X POST "https://api.cloud.nextmv.io/v1/applications/whispering-badger/secrets" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
-H "Content-Type: application/json" \
-d "{
\"id\": \"${SECRETS_ID}\",
\"name\": \"${SECRETS_ID}\",
\"secrets\": [
{\"type\": \"env\", \"location\": \"ACME_LICENSE_KEY\", \"value\": \"abc123\"},
{\"type\": \"file\", \"location\": \"config/app.conf\", \"value\": \"server=prod\\nport=8080\"}
]
}" \
| jq '.'
The call above uses a randomly generated ID, and the same identifier for the
collection's name. The name of the collection is used as a human-readable
label. You can pass different values for the id and name fields in the
payload to specify a custom ID and name for the collection. For example:
curl -s -X POST "https://api.cloud.nextmv.io/v1/applications/whispering-badger/secrets" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"id": "fluffy-secrets",
"name": "Secrets kept by a fluffy bunny",
"secrets": [
{"type": "env", "location": "ACME_LICENSE_KEY", "value": "abc123"},
{"type": "file", "location": "config/app.conf", "value": "server=prod\nport=8080"}
]
}' \
| jq '.'
Run with a secrets collection¶
Once a secrets collection has been created you can use it when starting a run in two ways:
- Use directly when starting a run with the
secrets_collection_idfield of theconfigurationobject in the run payload, or - Attach it to an instance configuration with the
secrets_collection_idfield of theconfigurationobject in the instance payload, and use that instance when starting a run.
Here is an example where the secrets collection is used directly when starting a run.
curl -s -X POST "https://api.cloud.nextmv.io/v1/applications/whispering-badger/runs?instance_id=latest" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"input": {"name": "world", "radius": 6378, "distance": 147.6},
"configuration": {"secrets_collection_id": "fluffy-secrets"}
}' \
| jq '.'
Once the run finishes, fetch its result with the
GET /v1/applications/{application_id}/runs/{run_id}
endpoint.
{
"id": "latest-y9H4mQPvR",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"metadata": {
"status": "succeeded",
"status_v2": "succeeded",
"created_at": "2026-07-29T06:45:29Z",
"initiated_at": "2026-07-29T06:45:29.433345208Z",
"duration": 6075,
"execution_duration": 5025,
"input_size": 52,
"output_size": 25099,
"error": "",
"application_id": "whispering-badger",
"application_instance_id": "latest",
"application_version_id": "",
"secrets_collection_id": "fluffy-secrets",
"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.
Let's say we have an instance identified as production. First, let's update
it to use the secrets collection. The snippet below does this in three steps:
it sends a GET request to fetch the current instance, uses jq to merge
the configuration field into that response, and pipes the merged payload to
a PUT /v1/applications/{application_id}/instances/{instance_id}
request that updates the instance.
curl -s -X GET "https://api.cloud.nextmv.io/v1/applications/whispering-badger/instances/production" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
| jq '. + {"configuration": {"secrets_collection_id": "fluffy-secrets"}}' \
| curl -s -X PUT "https://api.cloud.nextmv.io/v1/applications/whispering-badger/instances/production" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
-H "Content-Type: application/json" \
-d @- \
| jq '.'
{
"name": "The main production instance",
"id": "production",
"application_id": "whispering-badger",
"version_id": "version-7vdhines",
"description": "",
"configuration": {
"execution_class": "6c9500mb870s",
"secrets_collection_id": "fluffy-secrets",
"queuing": {
"priority": 6,
"disabled": false
}
},
"locked": false,
"created_at": "2026-07-29T06:45:08.853378506Z",
"updated_at": "2026-07-29T06:45:58.509515505Z"
}
We can now start a run using the production instance, and the secrets
collection will be used automatically.
After getting the run, we can see that the secrets_collection_id field is set
to the secrets collection we attached to the instance.
{
"id": "production-L-vImwPDg",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"metadata": {
"status": "succeeded",
"status_v2": "succeeded",
"created_at": "2026-07-29T06:46:02Z",
"initiated_at": "2026-07-29T06:46:02.857989017Z",
"duration": 7000,
"execution_duration": 6107,
"input_size": 52,
"output_size": 25099,
"error": "",
"application_id": "whispering-badger",
"application_instance_id": "production",
"application_version_id": "version-7vdhines",
"secrets_collection_id": "fluffy-secrets",
"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"
}
}
}
Get a secrets collection¶
Use the GET /v1/applications/{application_id}/secrets/{collection_id}
endpoint to retrieve an existing secrets collection for an application by its
ID. The response is a SecretsCollection
object.
Warning
The secret values will be shown in the output.
{
"id": "fluffy-secrets",
"application_id": "whispering-badger",
"name": "Secrets kept by a fluffy bunny",
"description": "",
"created_at": "2026-07-29T06:45:23Z",
"updated_at": "2026-07-29T06:45:23Z",
"secrets": [
{
"type": "env",
"location": "ACME_LICENSE_KEY",
"value": "abc123"
},
{
"type": "file",
"location": "config/app.conf",
"value": "server=prod\nport=8080"
}
]
}
You can list all collections in the application using the
GET /v1/applications/{application_id}/secrets
endpoint. The value of the secrets is omitted in the output, as this
endpoint returns a list of
SecretsCollectionSummary objects.
This endpoint is paginated, so the snippet below always uses pagination: it
passes pagereturn=true to receive a next_page_token in the response, and
keeps requesting pages by passing that token back as pagetoken until no
token is returned.
ITEMS="[]"
PAGE_TOKEN=""
while :; do
RESPONSE=$(curl -s -G "https://api.cloud.nextmv.io/v1/applications/whispering-badger/secrets" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
--data-urlencode "pagereturn=true" \
--data-urlencode "pagetoken=${PAGE_TOKEN}")
ITEMS=$(jq -n --argjson existing "$ITEMS" --argjson page "$(echo "$RESPONSE" | jq '.items')" '$existing + $page')
PAGE_TOKEN=$(echo "$RESPONSE" | jq -r '.next_page_token // empty')
[ -z "$PAGE_TOKEN" ] && break
done
echo "$ITEMS" | jq '.'
[
{
"id": "fluffy-secrets",
"application_id": "whispering-badger",
"name": "Secrets kept by a fluffy bunny",
"description": "",
"created_at": "2026-07-29T06:45:23Z",
"updated_at": "2026-07-29T06:45:23Z"
},
{
"id": "secrets-ba404179",
"application_id": "whispering-badger",
"name": "secrets-ba404179",
"description": "",
"created_at": "2026-07-29T06:45:19Z",
"updated_at": "2026-07-29T06:45:19Z"
}
]
Update a secrets collection¶
You can update attributes of a secrets collection with the
PUT /v1/applications/{application_id}/secrets/{collection_id}
endpoint, such as its:
- Name
- Description
- Secrets
Go the reference section to see all the available fields for updating a secrets collection. The fields are similar to the ones available when creating a secrets collection.
When updating secrets, they will be completely replaced with the new secrets
provided. If you need to keep some of the existing secrets, you must include
them in the secrets field. You cannot update the ID of a secrets
collection.
The endpoint expects the full secrets collection payload, so get the collection first and merge in the fields you want to change.
curl -s -X GET "https://api.cloud.nextmv.io/v1/applications/whispering-badger/secrets/fluffy-secrets" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
| jq '. + {"secrets": [{"type": "env", "location": "CARROT_KEY", "value": "delicious-vegetables"}]}' \
| curl -s -X PUT "https://api.cloud.nextmv.io/v1/applications/whispering-badger/secrets/fluffy-secrets" \
-H "Authorization: Bearer ${NEXTMV_API_KEY}" \
-H "Content-Type: application/json" \
-d @- \
| jq '.'
Delete a secrets collection¶
Warning
Deleting a secrets collection is irreversible. All the secrets in the collection will be permanently deleted.
Delete a secrets collection using the
DELETE /v1/applications/{application_id}/secrets/{collection_id}
endpoint.