Apply batch
POSThttps://api.instacloud.com/projects/{projectId}/apply
Token scope: account · org · project — read-only tokens refused (not a GET).
Write a batch of user secrets, then redeploy the compute services those values reach, one deploy per service. Entries are reported written individually and services are reported deployed, started, skipped or failed individually, because the writes commit before the deploys run and a failed deploy never rolls a value back. skipDeploy writes without deploying. excludeFromDeploy drops services the caller is deploying itself; deployOnly names the services to deploy and ignores derivation, which is how a failed deploy is retried with no entries. A rename writes no env, so it deploys nothing on its own and needs no deploy grant — a batch that both renames and writes still deploys, for the write. Gated on what the body contains: secrets.write for any set or delete, service.rename for a rename, deploy only for what can actually deploy. A project-scoped entry is authorized against every branch, since that is where its value lands. Deploying a stopped service starts it. A suspended service is skipped instead of deployed: a deploy would invalidate the RAM snapshot suspension exists to preserve, so it is left untouched and reported with reason suspended.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
projectId | path | string | yes |
Request body
application/json
| Field | Type | Required | Description |
|---|---|---|---|
branch | string | no | branch name (default branch if omitted) |
entries | object[] | yes | |
skipDeploy | boolean | no | |
excludeFromDeploy | string[] | no | |
deployOnly | string[] | no |
Responses
200
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
entries | object[] | yes | |
entries.name | string | yes | |
entries.written | boolean | yes | |
services | object[] | yes | |
services.serviceId | string | yes | |
services.result | "deployed" | "started" | "skipped" | "failed" | yes | |
services.reason | string | no |
202
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
status | "approval_required" | no | |
approvalId | string | no | |
action | string | no | the gated action, or a comma-joined compound set — prefer `actions` |
actions | string[] | no | every capability this approval covers |
message | string | no | |
url | string | no | the console page where a project admin reviews this request |
nextActions | object[] | no | |
nextActions.op | string | yes | Neutral logical action id, e.g. "service.add" — NOT an operationId or a CLI/MCP tool name; each client maps it to its own surface. |
nextActions.reason | string | yes | Natural-language, human/LLM-facing "why do this now". |
nextActions.args | object | no | Suggested, flat named arguments; "<placeholder>"s where a value is unknown. |
nextActions.gated | boolean | no | True if the action passes a governance gate. |
400
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |
403
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |
404
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |
409
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |
429
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |