Configure the workspace
Egress credentials
Give agents outbound service access through network injection.
On this page
Choose outbound access
Platform Environments support outbound service credentials through Sandbox0's
network injection. The authored platform-openapi.json and generated
API details
cover creation, list/detail, configuration replacement, material rotation and
deletion, with request examples. Supported projections are HTTP headers,
request placeholder substitution, mTLS, username/password and SSH proxy.
These credentials are separate from your Session model API keys.
Outbound restrictions
Credential injection authenticates matching outbound requests; it is not a destination allowlist. A credential's domains, ports and fail-closed policy restrict that credential rule, not all Environment traffic.
Configure the Environment's base network policy through the API or console. In block-all, enabled egress credentials with a current source version also allow their configured destinations and ports. Removing all base domain exceptions therefore does not block these credential destinations. Do not assume that omitting credentials blocks network access.
Credential rules do not merge. When enabled rules overlap for the same domain,
port and protocol, only the first matching credential is injected. Sandpi orders
rules by credential creation time, then credential ID; editing a credential does
not move it ahead of an older rule. Keep all HTTP headers needed for one service
in a single credential projection, or use destinations that do not overlap.
The Platform API does not expose Sandbox0's request-level httpMatch selector.
Scope and secret material
Use a personal token for a personal Environment, or a token for its owning Project. Cross-owner, cross-Project and personal-to-Project access returns 404 before any credential source access. Secret material goes directly to Sandbox0; Sandpi stores only configuration and observed version/status. Reads never return material or the internal source reference. Do not put secrets in projection templates; refer to material variables instead.
Update credentials during execution
Mutations take the Environment lifecycle lock and require its state to be ready. They also work while its Sandbox is paused. An active Run or checkpoint can delay credential mutations while holding the lifecycle lock. After they acquire the lock and apply, rotation and policy edits affect subsequent outbound connections; established connections are not retroactively reauthenticated. Resolver kind is immutable. Disabling a credential retains its source; deleting it removes both the binding and source. Failed operations retain reconciliation state, so inspect the list before retrying creation after an ambiguous failure. Creating the same display name twice returns a conflict rather than allocating another source.
Fork and rollback behavior
Credentials are Environment configuration outside RootFS checkpoints. Rollback does not restore an earlier credential version. Forks start without credential records or bindings; configure the child explicitly. Environment deletion removes the Sandbox before deleting its credential sources. The existing TUI credential routes remain unavailable for Platform Environments.
Create an Environment egress credential
/v1/environments/{environmentId}/egress-credentialsRequires a personal token for a personal Environment or a token scoped to the owning Project. Secret material is stored only in Sandbox0. Mutations use the Environment lifecycle lock and require a ready Environment; paused Environments are supported. Active work can delay mutations while holding the lifecycle lock. Applied changes affect subsequent outbound connections. Credentials are not inherited by forks and are not restored by Run rollback.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
Request example
curl -X POST \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/egress-credentials" \
-H "Authorization: Bearer $SANDPI_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "GitHub API",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "Authorization",
"valueTemplate": "Bearer {{ .token }}"
}
]
},
"rule": {
"protocol": "https",
"domains": [
"api.github.com"
],
"ports": [
{
"port": 443
}
],
"failurePolicy": "fail-closed"
},
"enabled": true,
"material": {
"type": "static_headers",
"values": {
"token": "YOUR_GITHUB_TOKEN"
}
}
}'Request body · required application/json
Maximum bytes: 2,097,152
Outbound credential configuration and write-only material for creation.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
name | string · min length 1; max length 80Validation pattern\S | Yes | Human-readable name for this resource. |
resolverKind | string · values: "static_headers" | "static_tls_client_certificate" | "static_username_password" | "static_ssh_private_key" | Yes | Credential material resolver. Its kind is immutable after creation and must match the material type. |
projection | one of the variants below | Yes | Projection variant applied at the network boundary. Choose the type matching the configured resolver. |
projection | object | Yestype = "http_headers" | — |
projection.type | string · values: "http_headers" | Yestype = "http_headers" | Discriminator selecting the configuration or secret-material variant. |
projection.headers | array · min 1 items; max 32 items | Yestype = "http_headers" | Header definitions or secret header values applied by this configuration. |
projection.headers[] | object | Yeseach array item | — |
projection.headers[].name | string · min length 1; max length 128Validation pattern^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ | Yeseach array item | Human-readable name for this resource. |
projection.headers[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
projection | object | Yestype = "placeholder_substitution" | — |
projection.type | string · values: "placeholder_substitution" | Yestype = "placeholder_substitution" | Discriminator selecting the configuration or secret-material variant. |
projection.replacements | array · min 1 items; max 32 items | Yestype = "placeholder_substitution" | Placeholder replacement rules applied at the network boundary. |
projection.replacements[] | object | Yeseach array item | — |
projection.replacements[].placeholder | string · min length 1; max length 512 | Yeseach array item | Literal placeholder to replace in the selected request locations. |
projection.replacements[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
projection.replacements[].locations | array · min 1 items; max 3 items | Yeseach array item | Request locations where placeholder replacement applies. |
projection.replacements[].locations[] | string · values: "header" | "query" | "body" | Yeseach array item | — |
projection | object | Yestype = "tls_client_certificate" | — |
projection.type | string · values: "tls_client_certificate" | Yestype = "tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
projection | object | Yestype = "username_password" | — |
projection.type | string · values: "username_password" | Yestype = "username_password" | Discriminator selecting the configuration or secret-material variant. |
projection | object | Yestype = "ssh_proxy" | — |
projection.type | string · values: "ssh_proxy" | Yestype = "ssh_proxy" | Discriminator selecting the configuration or secret-material variant. |
projection.upstreamUsername | string · min length 1; max length 255 | Yestype = "ssh_proxy" | Username used for the upstream SSH connection. |
projection.sandboxPublicKeys | array · min 1 items; max 16 items | Yestype = "ssh_proxy" | Public keys allowed to use this Sandbox-side SSH proxy binding. |
projection.sandboxPublicKeys[] | string · min length 1; max length 16384 | Yeseach array item | — |
projection.knownHosts | array · min 0 items; max 64 items | Notype = "ssh_proxy" | Known-host entries for upstream SSH host verification. |
projection.knownHosts[] | string · min length 1; max length 16384 | Yeseach array item | — |
rule | object | Yes | Matching outbound destinations and resolver failure policy. |
rule.protocol | string · values: "http" | "https" | "grpc" | "tls" | "ssh" | "socks5" | "mqtt" | "redis" | Yeswithin rule | Network protocol to which the binding applies. |
rule.domains | array · min 1 items; max 128 items | Yeswithin rule | Destination domain patterns matched by the credential rule. |
rule.domains[] | string · min length 1; max length 255 | Yeseach array item | Exact or wildcard domain, e.g. api.example.com or *.example.com; URLs, paths and ports are rejected. Domains are normalized and deduplicated. |
rule.ports | array · min 1 items; max 16 items | Yeswithin rule | Destination ports matched by the credential rule. |
rule.ports[] | object | Yeseach array item | — |
rule.ports[].port | integer · ≥ 1; ≤ 65535 | Yeseach array item | Port number matched by this destination rule. |
rule.ports[].protocol | string · values: "tcp"; default: "tcp" | Noeach array item | Network protocol to which the binding applies. |
rule.failurePolicy | string · values: "fail-closed" | "fail-open"; default: "fail-closed" | Nowithin rule | Behavior when the network-boundary credential cannot be resolved. |
enabled | boolean · default: true | No | Whether this configuration is enabled for future use. |
material | one of the variants below | Yes | Write-only Sandbox0 source material. Never returned or stored in Sandpi PostgreSQL. The type must match resolverKind. |
material | object | Yestype = "static_headers" | — |
material.type | string · values: "static_headers" | Yestype = "static_headers" | Discriminator selecting the configuration or secret-material variant. |
material.values | object · min 1 keys; max 32 keys | Yestype = "static_headers" | Map of secret variable names to their write-only values. |
material.values.{key} | string · min length 1; max length 1048576; write only | Noadditional keys | — |
material | object | Yestype = "static_tls_client_certificate" | — |
material.type | string · values: "static_tls_client_certificate" | Yestype = "static_tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
material.certificatePem | string · min length 1; max length 1048576; write only | Yestype = "static_tls_client_certificate" | PEM-encoded client certificate supplied only when creating or rotating material. |
material.privateKeyPem | string · min length 1; max length 1048576; write only | Yestype = "static_tls_client_certificate" | PEM-encoded private key supplied only when creating or rotating material. |
material.caPem | string · max length 1048576; write only | Notype = "static_tls_client_certificate" | Optional PEM-encoded certificate authority used with this material. |
material | object | Yestype = "static_username_password" | — |
material.type | string · values: "static_username_password" | Yestype = "static_username_password" | Discriminator selecting the configuration or secret-material variant. |
material.username | string · min length 1; max length 1024; write only | Yestype = "static_username_password" | Write-only upstream authentication username. |
material.password | string · min length 1; max length 1048576; write only | Yestype = "static_username_password" | Write-only upstream authentication password. |
material | object | Yestype = "static_ssh_private_key" | — |
material.type | string · values: "static_ssh_private_key" | Yestype = "static_ssh_private_key" | Discriminator selecting the configuration or secret-material variant. |
material.privateKeyPem | string · min length 1; max length 1048576; write only | Yestype = "static_ssh_private_key" | PEM-encoded private key supplied only when creating or rotating material. |
material.passphrase | string · max length 1048576; write only | Notype = "static_ssh_private_key" | Optional write-only private-key passphrase. |
Example
{
"name": "GitHub API",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "Authorization",
"valueTemplate": "Bearer {{ .token }}"
}
]
},
"rule": {
"protocol": "https",
"domains": [
"api.github.com"
],
"ports": [
{
"port": 443
}
],
"failurePolicy": "fail-closed"
},
"enabled": true,
"material": {
"type": "static_headers",
"values": {
"token": "YOUR_GITHUB_TOKEN"
}
}
}Responses
201 Created.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object · extra fields rejected | Yes | Secret-free configuration and observed source state. Contains neither material nor the internal Sandbox0 source reference. |
data.name | string · min length 1; max length 80Validation pattern\S | Yeswithin data | Human-readable name for this resource. |
data.resolverKind | string · values: "static_headers" | "static_tls_client_certificate" | "static_username_password" | "static_ssh_private_key" | Yeswithin data | Credential material resolver. Its kind is immutable after creation and must match the material type. |
data.projection | one of the variants below | Yeswithin data | Projection variant applied at the network boundary. Choose the type matching the configured resolver. |
data.projection | object | Yestype = "http_headers" | — |
data.projection.type | string · values: "http_headers" | Yestype = "http_headers" | Discriminator selecting the configuration or secret-material variant. |
data.projection.headers | array · min 1 items; max 32 items | Yestype = "http_headers" | Header definitions or secret header values applied by this configuration. |
data.projection.headers[] | object | Yeseach array item | — |
data.projection.headers[].name | string · min length 1; max length 128Validation pattern^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ | Yeseach array item | Human-readable name for this resource. |
data.projection.headers[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data.projection | object | Yestype = "placeholder_substitution" | — |
data.projection.type | string · values: "placeholder_substitution" | Yestype = "placeholder_substitution" | Discriminator selecting the configuration or secret-material variant. |
data.projection.replacements | array · min 1 items; max 32 items | Yestype = "placeholder_substitution" | Placeholder replacement rules applied at the network boundary. |
data.projection.replacements[] | object | Yeseach array item | — |
data.projection.replacements[].placeholder | string · min length 1; max length 512 | Yeseach array item | Literal placeholder to replace in the selected request locations. |
data.projection.replacements[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data.projection.replacements[].locations | array · min 1 items; max 3 items | Yeseach array item | Request locations where placeholder replacement applies. |
data.projection.replacements[].locations[] | string · values: "header" | "query" | "body" | Yeseach array item | — |
data.projection | object | Yestype = "tls_client_certificate" | — |
data.projection.type | string · values: "tls_client_certificate" | Yestype = "tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
data.projection | object | Yestype = "username_password" | — |
data.projection.type | string · values: "username_password" | Yestype = "username_password" | Discriminator selecting the configuration or secret-material variant. |
data.projection | object | Yestype = "ssh_proxy" | — |
data.projection.type | string · values: "ssh_proxy" | Yestype = "ssh_proxy" | Discriminator selecting the configuration or secret-material variant. |
data.projection.upstreamUsername | string · min length 1; max length 255 | Yestype = "ssh_proxy" | Username used for the upstream SSH connection. |
data.projection.sandboxPublicKeys | array · min 1 items; max 16 items | Yestype = "ssh_proxy" | Public keys allowed to use this Sandbox-side SSH proxy binding. |
data.projection.sandboxPublicKeys[] | string · min length 1; max length 16384 | Yeseach array item | — |
data.projection.knownHosts | array · min 0 items; max 64 items | Notype = "ssh_proxy" | Known-host entries for upstream SSH host verification. |
data.projection.knownHosts[] | string · min length 1; max length 16384 | Yeseach array item | — |
data.rule | object | Yeswithin data | Matching outbound destinations and resolver failure policy. |
data.rule.protocol | string · values: "http" | "https" | "grpc" | "tls" | "ssh" | "socks5" | "mqtt" | "redis" | Yeswithin data | Network protocol to which the binding applies. |
data.rule.domains | array · min 1 items; max 128 items | Yeswithin data | Destination domain patterns matched by the credential rule. |
data.rule.domains[] | string · min length 1; max length 255 | Yeseach array item | Exact or wildcard domain, e.g. api.example.com or *.example.com; URLs, paths and ports are rejected. Domains are normalized and deduplicated. |
data.rule.ports | array · min 1 items; max 16 items | Yeswithin data | Destination ports matched by the credential rule. |
data.rule.ports[] | object | Yeseach array item | — |
data.rule.ports[].port | integer · ≥ 1; ≤ 65535 | Yeseach array item | Port number matched by this destination rule. |
data.rule.ports[].protocol | string · values: "tcp"; default: "tcp" | Noeach array item | Network protocol to which the binding applies. |
data.rule.failurePolicy | string · values: "fail-closed" | "fail-open"; default: "fail-closed" | Nowithin data | Behavior when the network-boundary credential cannot be resolved. |
data.enabled | boolean · default: true | Yeswithin data | Whether this configuration is enabled for future use. |
data.id | string · min length 1 | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string · min length 1 | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.status | string · values: "provisioning" | "active" | "error" | "deleting" | Yeswithin data | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data.currentVersion | integer · ≥ 1 | Nowithin data | Observed current credential source version. |
data.sourceStatus | string · min length 1 | Nowithin data | Observed credential source state from Sandbox0. |
data.error | string · min length 1 | Nowithin data | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
data.createdAt | number | Yeswithin data | Creation time as a Unix timestamp in seconds. |
data.updatedAt | number | Yeswithin data | Last update time as a Unix timestamp in seconds. |
Example
{
"data": {
"name": "example",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "example",
"valueTemplate": "example"
}
]
},
"rule": {
"protocol": "http",
"domains": [
"example"
],
"ports": [
{
"port": 1
}
]
},
"enabled": false,
"id": "example",
"environmentId": "example",
"status": "provisioning",
"createdAt": 0,
"updatedAt": 0
}
}Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}Verify and rotate
Inspect the credential’s observed status before testing a new outbound connection. Replace material using the rotation operation, and check status again. Established connections can continue with their earlier authentication; reconnect to exercise the new version.
List Environment egress credentials
/v1/environments/{environmentId}/egress-credentialsRequires a personal token for a personal Environment or a token scoped to the owning Project. Secret material is stored only in Sandbox0. Mutations use the Environment lifecycle lock and require a ready Environment; paused Environments are supported. Active work can delay mutations while holding the lifecycle lock. Applied changes affect subsequent outbound connections. Credentials are not inherited by forks and are not restored by Run rollback.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
Request example
curl \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/egress-credentials" \
-H "Authorization: Bearer $SANDPI_API_TOKEN"No request body.
Responses
200 OK.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | array | Yes | Successful result wrapped by the API. The child fields describe its content. |
data[] | object · extra fields rejected | Yeseach array item | Secret-free configuration and observed source state. Contains neither material nor the internal Sandbox0 source reference. |
data[].name | string · min length 1; max length 80Validation pattern\S | Yeseach array item | Human-readable name for this resource. |
data[].resolverKind | string · values: "static_headers" | "static_tls_client_certificate" | "static_username_password" | "static_ssh_private_key" | Yeseach array item | Credential material resolver. Its kind is immutable after creation and must match the material type. |
data[].projection | one of the variants below | Yeseach array item | Projection variant applied at the network boundary. Choose the type matching the configured resolver. |
data[].projection | object | Yestype = "http_headers" | — |
data[].projection.type | string · values: "http_headers" | Yestype = "http_headers" | Discriminator selecting the configuration or secret-material variant. |
data[].projection.headers | array · min 1 items; max 32 items | Yestype = "http_headers" | Header definitions or secret header values applied by this configuration. |
data[].projection.headers[] | object | Yeseach array item | — |
data[].projection.headers[].name | string · min length 1; max length 128Validation pattern^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ | Yeseach array item | Human-readable name for this resource. |
data[].projection.headers[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data[].projection | object | Yestype = "placeholder_substitution" | — |
data[].projection.type | string · values: "placeholder_substitution" | Yestype = "placeholder_substitution" | Discriminator selecting the configuration or secret-material variant. |
data[].projection.replacements | array · min 1 items; max 32 items | Yestype = "placeholder_substitution" | Placeholder replacement rules applied at the network boundary. |
data[].projection.replacements[] | object | Yeseach array item | — |
data[].projection.replacements[].placeholder | string · min length 1; max length 512 | Yeseach array item | Literal placeholder to replace in the selected request locations. |
data[].projection.replacements[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data[].projection.replacements[].locations | array · min 1 items; max 3 items | Yeseach array item | Request locations where placeholder replacement applies. |
data[].projection.replacements[].locations[] | string · values: "header" | "query" | "body" | Yeseach array item | — |
data[].projection | object | Yestype = "tls_client_certificate" | — |
data[].projection.type | string · values: "tls_client_certificate" | Yestype = "tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
data[].projection | object | Yestype = "username_password" | — |
data[].projection.type | string · values: "username_password" | Yestype = "username_password" | Discriminator selecting the configuration or secret-material variant. |
data[].projection | object | Yestype = "ssh_proxy" | — |
data[].projection.type | string · values: "ssh_proxy" | Yestype = "ssh_proxy" | Discriminator selecting the configuration or secret-material variant. |
data[].projection.upstreamUsername | string · min length 1; max length 255 | Yestype = "ssh_proxy" | Username used for the upstream SSH connection. |
data[].projection.sandboxPublicKeys | array · min 1 items; max 16 items | Yestype = "ssh_proxy" | Public keys allowed to use this Sandbox-side SSH proxy binding. |
data[].projection.sandboxPublicKeys[] | string · min length 1; max length 16384 | Yeseach array item | — |
data[].projection.knownHosts | array · min 0 items; max 64 items | Notype = "ssh_proxy" | Known-host entries for upstream SSH host verification. |
data[].projection.knownHosts[] | string · min length 1; max length 16384 | Yeseach array item | — |
data[].rule | object | Yeseach array item | Matching outbound destinations and resolver failure policy. |
data[].rule.protocol | string · values: "http" | "https" | "grpc" | "tls" | "ssh" | "socks5" | "mqtt" | "redis" | Yeseach array item | Network protocol to which the binding applies. |
data[].rule.domains | array · min 1 items; max 128 items | Yeseach array item | Destination domain patterns matched by the credential rule. |
data[].rule.domains[] | string · min length 1; max length 255 | Yeseach array item | Exact or wildcard domain, e.g. api.example.com or *.example.com; URLs, paths and ports are rejected. Domains are normalized and deduplicated. |
data[].rule.ports | array · min 1 items; max 16 items | Yeseach array item | Destination ports matched by the credential rule. |
data[].rule.ports[] | object | Yeseach array item | — |
data[].rule.ports[].port | integer · ≥ 1; ≤ 65535 | Yeseach array item | Port number matched by this destination rule. |
data[].rule.ports[].protocol | string · values: "tcp"; default: "tcp" | Noeach array item | Network protocol to which the binding applies. |
data[].rule.failurePolicy | string · values: "fail-closed" | "fail-open"; default: "fail-closed" | Noeach array item | Behavior when the network-boundary credential cannot be resolved. |
data[].enabled | boolean · default: true | Yeseach array item | Whether this configuration is enabled for future use. |
data[].id | string · min length 1 | Yeseach array item | Resource identifier used to read or manage this resource. |
data[].environmentId | string · min length 1 | Yeseach array item | Environment identifier. It must belong to the caller’s account or Project. |
data[].status | string · values: "provisioning" | "active" | "error" | "deleting" | Yeseach array item | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data[].currentVersion | integer · ≥ 1 | Noeach array item | Observed current credential source version. |
data[].sourceStatus | string · min length 1 | Noeach array item | Observed credential source state from Sandbox0. |
data[].error | string · min length 1 | Noeach array item | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
data[].createdAt | number | Yeseach array item | Creation time as a Unix timestamp in seconds. |
data[].updatedAt | number | Yeseach array item | Last update time as a Unix timestamp in seconds. |
Example
{
"data": [
{
"name": "example",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "example",
"valueTemplate": "example"
}
]
},
"rule": {
"protocol": "http",
"domains": [
"example"
],
"ports": [
{
"port": 1
}
]
},
"enabled": false,
"id": "example",
"environmentId": "example",
"status": "provisioning",
"createdAt": 0,
"updatedAt": 0
}
]
}Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}Replace egress credential secret material
/v1/environments/{environmentId}/egress-credentials/{credentialId}/materialRequires a personal token for a personal Environment or a token scoped to the owning Project. Secret material is stored only in Sandbox0. Mutations use the Environment lifecycle lock and require a ready Environment; paused Environments are supported. Active work can delay mutations while holding the lifecycle lock. Applied changes affect subsequent outbound connections. Credentials are not inherited by forks and are not restored by Run rollback. Resolver kind is immutable; replacing material advances its version without returning it.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: credentialId | string · min length 1 | Yes | Egress credential identifier within this Environment. |
Request example
curl -X PUT \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/egress-credentials/$CREDENTIAL_ID/material" \
-H "Authorization: Bearer $SANDPI_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"resolverKind": "static_headers",
"material": {
"type": "static_headers",
"values": {
"token": "YOUR_NEW_GITHUB_TOKEN"
}
}
}'Request body · required application/json
Maximum bytes: 2,097,152
Replacement write-only material; the resolver kind must match the existing credential.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
resolverKind | string · values: "static_headers" | "static_tls_client_certificate" | "static_username_password" | "static_ssh_private_key" | Yes | Credential material resolver. Its kind is immutable after creation and must match the material type. |
material | one of the variants below | Yes | Write-only Sandbox0 source material. Never returned or stored in Sandpi PostgreSQL. The type must match resolverKind. |
material | object | Yestype = "static_headers" | — |
material.type | string · values: "static_headers" | Yestype = "static_headers" | Discriminator selecting the configuration or secret-material variant. |
material.values | object · min 1 keys; max 32 keys | Yestype = "static_headers" | Map of secret variable names to their write-only values. |
material.values.{key} | string · min length 1; max length 1048576; write only | Noadditional keys | — |
material | object | Yestype = "static_tls_client_certificate" | — |
material.type | string · values: "static_tls_client_certificate" | Yestype = "static_tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
material.certificatePem | string · min length 1; max length 1048576; write only | Yestype = "static_tls_client_certificate" | PEM-encoded client certificate supplied only when creating or rotating material. |
material.privateKeyPem | string · min length 1; max length 1048576; write only | Yestype = "static_tls_client_certificate" | PEM-encoded private key supplied only when creating or rotating material. |
material.caPem | string · max length 1048576; write only | Notype = "static_tls_client_certificate" | Optional PEM-encoded certificate authority used with this material. |
material | object | Yestype = "static_username_password" | — |
material.type | string · values: "static_username_password" | Yestype = "static_username_password" | Discriminator selecting the configuration or secret-material variant. |
material.username | string · min length 1; max length 1024; write only | Yestype = "static_username_password" | Write-only upstream authentication username. |
material.password | string · min length 1; max length 1048576; write only | Yestype = "static_username_password" | Write-only upstream authentication password. |
material | object | Yestype = "static_ssh_private_key" | — |
material.type | string · values: "static_ssh_private_key" | Yestype = "static_ssh_private_key" | Discriminator selecting the configuration or secret-material variant. |
material.privateKeyPem | string · min length 1; max length 1048576; write only | Yestype = "static_ssh_private_key" | PEM-encoded private key supplied only when creating or rotating material. |
material.passphrase | string · max length 1048576; write only | Notype = "static_ssh_private_key" | Optional write-only private-key passphrase. |
Example
{
"resolverKind": "static_headers",
"material": {
"type": "static_headers",
"values": {
"token": "YOUR_NEW_GITHUB_TOKEN"
}
}
}Responses
200 OK.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object · extra fields rejected | Yes | Secret-free configuration and observed source state. Contains neither material nor the internal Sandbox0 source reference. |
data.name | string · min length 1; max length 80Validation pattern\S | Yeswithin data | Human-readable name for this resource. |
data.resolverKind | string · values: "static_headers" | "static_tls_client_certificate" | "static_username_password" | "static_ssh_private_key" | Yeswithin data | Credential material resolver. Its kind is immutable after creation and must match the material type. |
data.projection | one of the variants below | Yeswithin data | Projection variant applied at the network boundary. Choose the type matching the configured resolver. |
data.projection | object | Yestype = "http_headers" | — |
data.projection.type | string · values: "http_headers" | Yestype = "http_headers" | Discriminator selecting the configuration or secret-material variant. |
data.projection.headers | array · min 1 items; max 32 items | Yestype = "http_headers" | Header definitions or secret header values applied by this configuration. |
data.projection.headers[] | object | Yeseach array item | — |
data.projection.headers[].name | string · min length 1; max length 128Validation pattern^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ | Yeseach array item | Human-readable name for this resource. |
data.projection.headers[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data.projection | object | Yestype = "placeholder_substitution" | — |
data.projection.type | string · values: "placeholder_substitution" | Yestype = "placeholder_substitution" | Discriminator selecting the configuration or secret-material variant. |
data.projection.replacements | array · min 1 items; max 32 items | Yestype = "placeholder_substitution" | Placeholder replacement rules applied at the network boundary. |
data.projection.replacements[] | object | Yeseach array item | — |
data.projection.replacements[].placeholder | string · min length 1; max length 512 | Yeseach array item | Literal placeholder to replace in the selected request locations. |
data.projection.replacements[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data.projection.replacements[].locations | array · min 1 items; max 3 items | Yeseach array item | Request locations where placeholder replacement applies. |
data.projection.replacements[].locations[] | string · values: "header" | "query" | "body" | Yeseach array item | — |
data.projection | object | Yestype = "tls_client_certificate" | — |
data.projection.type | string · values: "tls_client_certificate" | Yestype = "tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
data.projection | object | Yestype = "username_password" | — |
data.projection.type | string · values: "username_password" | Yestype = "username_password" | Discriminator selecting the configuration or secret-material variant. |
data.projection | object | Yestype = "ssh_proxy" | — |
data.projection.type | string · values: "ssh_proxy" | Yestype = "ssh_proxy" | Discriminator selecting the configuration or secret-material variant. |
data.projection.upstreamUsername | string · min length 1; max length 255 | Yestype = "ssh_proxy" | Username used for the upstream SSH connection. |
data.projection.sandboxPublicKeys | array · min 1 items; max 16 items | Yestype = "ssh_proxy" | Public keys allowed to use this Sandbox-side SSH proxy binding. |
data.projection.sandboxPublicKeys[] | string · min length 1; max length 16384 | Yeseach array item | — |
data.projection.knownHosts | array · min 0 items; max 64 items | Notype = "ssh_proxy" | Known-host entries for upstream SSH host verification. |
data.projection.knownHosts[] | string · min length 1; max length 16384 | Yeseach array item | — |
data.rule | object | Yeswithin data | Matching outbound destinations and resolver failure policy. |
data.rule.protocol | string · values: "http" | "https" | "grpc" | "tls" | "ssh" | "socks5" | "mqtt" | "redis" | Yeswithin data | Network protocol to which the binding applies. |
data.rule.domains | array · min 1 items; max 128 items | Yeswithin data | Destination domain patterns matched by the credential rule. |
data.rule.domains[] | string · min length 1; max length 255 | Yeseach array item | Exact or wildcard domain, e.g. api.example.com or *.example.com; URLs, paths and ports are rejected. Domains are normalized and deduplicated. |
data.rule.ports | array · min 1 items; max 16 items | Yeswithin data | Destination ports matched by the credential rule. |
data.rule.ports[] | object | Yeseach array item | — |
data.rule.ports[].port | integer · ≥ 1; ≤ 65535 | Yeseach array item | Port number matched by this destination rule. |
data.rule.ports[].protocol | string · values: "tcp"; default: "tcp" | Noeach array item | Network protocol to which the binding applies. |
data.rule.failurePolicy | string · values: "fail-closed" | "fail-open"; default: "fail-closed" | Nowithin data | Behavior when the network-boundary credential cannot be resolved. |
data.enabled | boolean · default: true | Yeswithin data | Whether this configuration is enabled for future use. |
data.id | string · min length 1 | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string · min length 1 | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.status | string · values: "provisioning" | "active" | "error" | "deleting" | Yeswithin data | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data.currentVersion | integer · ≥ 1 | Nowithin data | Observed current credential source version. |
data.sourceStatus | string · min length 1 | Nowithin data | Observed credential source state from Sandbox0. |
data.error | string · min length 1 | Nowithin data | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
data.createdAt | number | Yeswithin data | Creation time as a Unix timestamp in seconds. |
data.updatedAt | number | Yeswithin data | Last update time as a Unix timestamp in seconds. |
Example
{
"data": {
"name": "example",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "example",
"valueTemplate": "example"
}
]
},
"rule": {
"protocol": "http",
"domains": [
"example"
],
"ports": [
{
"port": 1
}
]
},
"enabled": false,
"id": "example",
"environmentId": "example",
"status": "provisioning",
"createdAt": 0,
"updatedAt": 0
}
}Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}Inbound versus outbound credentials
These credentials let an agent call a third-party service. They do not authenticate events sent to Sandpi. A Parseable webhook password authenticates incoming alerts; configure separate egress access or MCP tools if the agent also needs to query logs. See inbound webhooks.
Read and replace a binding
Read configuration and observed status, then replace the non-secret connection rules or projection. Secret changes use the separate material rotation operation.
Get an Environment egress credential
/v1/environments/{environmentId}/egress-credentials/{credentialId}Requires a personal token for a personal Environment or a token scoped to the owning Project. Secret material is stored only in Sandbox0. Mutations use the Environment lifecycle lock and require a ready Environment; paused Environments are supported. Active work can delay mutations while holding the lifecycle lock. Applied changes affect subsequent outbound connections. Credentials are not inherited by forks and are not restored by Run rollback.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: credentialId | string · min length 1 | Yes | Egress credential identifier within this Environment. |
Request example
curl \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/egress-credentials/$CREDENTIAL_ID" \
-H "Authorization: Bearer $SANDPI_API_TOKEN"No request body.
Responses
200 OK.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object · extra fields rejected | Yes | Secret-free configuration and observed source state. Contains neither material nor the internal Sandbox0 source reference. |
data.name | string · min length 1; max length 80Validation pattern\S | Yeswithin data | Human-readable name for this resource. |
data.resolverKind | string · values: "static_headers" | "static_tls_client_certificate" | "static_username_password" | "static_ssh_private_key" | Yeswithin data | Credential material resolver. Its kind is immutable after creation and must match the material type. |
data.projection | one of the variants below | Yeswithin data | Projection variant applied at the network boundary. Choose the type matching the configured resolver. |
data.projection | object | Yestype = "http_headers" | — |
data.projection.type | string · values: "http_headers" | Yestype = "http_headers" | Discriminator selecting the configuration or secret-material variant. |
data.projection.headers | array · min 1 items; max 32 items | Yestype = "http_headers" | Header definitions or secret header values applied by this configuration. |
data.projection.headers[] | object | Yeseach array item | — |
data.projection.headers[].name | string · min length 1; max length 128Validation pattern^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ | Yeseach array item | Human-readable name for this resource. |
data.projection.headers[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data.projection | object | Yestype = "placeholder_substitution" | — |
data.projection.type | string · values: "placeholder_substitution" | Yestype = "placeholder_substitution" | Discriminator selecting the configuration or secret-material variant. |
data.projection.replacements | array · min 1 items; max 32 items | Yestype = "placeholder_substitution" | Placeholder replacement rules applied at the network boundary. |
data.projection.replacements[] | object | Yeseach array item | — |
data.projection.replacements[].placeholder | string · min length 1; max length 512 | Yeseach array item | Literal placeholder to replace in the selected request locations. |
data.projection.replacements[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data.projection.replacements[].locations | array · min 1 items; max 3 items | Yeseach array item | Request locations where placeholder replacement applies. |
data.projection.replacements[].locations[] | string · values: "header" | "query" | "body" | Yeseach array item | — |
data.projection | object | Yestype = "tls_client_certificate" | — |
data.projection.type | string · values: "tls_client_certificate" | Yestype = "tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
data.projection | object | Yestype = "username_password" | — |
data.projection.type | string · values: "username_password" | Yestype = "username_password" | Discriminator selecting the configuration or secret-material variant. |
data.projection | object | Yestype = "ssh_proxy" | — |
data.projection.type | string · values: "ssh_proxy" | Yestype = "ssh_proxy" | Discriminator selecting the configuration or secret-material variant. |
data.projection.upstreamUsername | string · min length 1; max length 255 | Yestype = "ssh_proxy" | Username used for the upstream SSH connection. |
data.projection.sandboxPublicKeys | array · min 1 items; max 16 items | Yestype = "ssh_proxy" | Public keys allowed to use this Sandbox-side SSH proxy binding. |
data.projection.sandboxPublicKeys[] | string · min length 1; max length 16384 | Yeseach array item | — |
data.projection.knownHosts | array · min 0 items; max 64 items | Notype = "ssh_proxy" | Known-host entries for upstream SSH host verification. |
data.projection.knownHosts[] | string · min length 1; max length 16384 | Yeseach array item | — |
data.rule | object | Yeswithin data | Matching outbound destinations and resolver failure policy. |
data.rule.protocol | string · values: "http" | "https" | "grpc" | "tls" | "ssh" | "socks5" | "mqtt" | "redis" | Yeswithin data | Network protocol to which the binding applies. |
data.rule.domains | array · min 1 items; max 128 items | Yeswithin data | Destination domain patterns matched by the credential rule. |
data.rule.domains[] | string · min length 1; max length 255 | Yeseach array item | Exact or wildcard domain, e.g. api.example.com or *.example.com; URLs, paths and ports are rejected. Domains are normalized and deduplicated. |
data.rule.ports | array · min 1 items; max 16 items | Yeswithin data | Destination ports matched by the credential rule. |
data.rule.ports[] | object | Yeseach array item | — |
data.rule.ports[].port | integer · ≥ 1; ≤ 65535 | Yeseach array item | Port number matched by this destination rule. |
data.rule.ports[].protocol | string · values: "tcp"; default: "tcp" | Noeach array item | Network protocol to which the binding applies. |
data.rule.failurePolicy | string · values: "fail-closed" | "fail-open"; default: "fail-closed" | Nowithin data | Behavior when the network-boundary credential cannot be resolved. |
data.enabled | boolean · default: true | Yeswithin data | Whether this configuration is enabled for future use. |
data.id | string · min length 1 | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string · min length 1 | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.status | string · values: "provisioning" | "active" | "error" | "deleting" | Yeswithin data | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data.currentVersion | integer · ≥ 1 | Nowithin data | Observed current credential source version. |
data.sourceStatus | string · min length 1 | Nowithin data | Observed credential source state from Sandbox0. |
data.error | string · min length 1 | Nowithin data | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
data.createdAt | number | Yeswithin data | Creation time as a Unix timestamp in seconds. |
data.updatedAt | number | Yeswithin data | Last update time as a Unix timestamp in seconds. |
Example
{
"data": {
"name": "example",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "example",
"valueTemplate": "example"
}
]
},
"rule": {
"protocol": "http",
"domains": [
"example"
],
"ports": [
{
"port": 1
}
]
},
"enabled": false,
"id": "example",
"environmentId": "example",
"status": "provisioning",
"createdAt": 0,
"updatedAt": 0
}
}Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}Replace an egress credential configuration
/v1/environments/{environmentId}/egress-credentials/{credentialId}Requires a personal token for a personal Environment or a token scoped to the owning Project. Secret material is stored only in Sandbox0. Mutations use the Environment lifecycle lock and require a ready Environment; paused Environments are supported. Active work can delay mutations while holding the lifecycle lock. Applied changes affect subsequent outbound connections. Credentials are not inherited by forks and are not restored by Run rollback. Resolver kind is immutable. Set enabled=false to disable injection without deleting the source.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: credentialId | string · min length 1 | Yes | Egress credential identifier within this Environment. |
Request example
curl -X PUT \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/egress-credentials/$CREDENTIAL_ID" \
-H "Authorization: Bearer $SANDPI_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "GitHub API",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "Authorization",
"valueTemplate": "Bearer {{ .token }}"
}
]
},
"rule": {
"protocol": "https",
"domains": [
"api.github.com"
],
"ports": [
{
"port": 443
}
],
"failurePolicy": "fail-closed"
},
"enabled": true
}'Request body · required application/json
Maximum bytes: 2,097,152
Non-secret binding configuration; secret material is supplied separately.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
name | string · min length 1; max length 80Validation pattern\S | Yes | Human-readable name for this resource. |
resolverKind | string · values: "static_headers" | "static_tls_client_certificate" | "static_username_password" | "static_ssh_private_key" | Yes | Credential material resolver. Its kind is immutable after creation and must match the material type. |
projection | one of the variants below | Yes | Projection variant applied at the network boundary. Choose the type matching the configured resolver. |
projection | object | Yestype = "http_headers" | — |
projection.type | string · values: "http_headers" | Yestype = "http_headers" | Discriminator selecting the configuration or secret-material variant. |
projection.headers | array · min 1 items; max 32 items | Yestype = "http_headers" | Header definitions or secret header values applied by this configuration. |
projection.headers[] | object | Yeseach array item | — |
projection.headers[].name | string · min length 1; max length 128Validation pattern^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ | Yeseach array item | Human-readable name for this resource. |
projection.headers[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
projection | object | Yestype = "placeholder_substitution" | — |
projection.type | string · values: "placeholder_substitution" | Yestype = "placeholder_substitution" | Discriminator selecting the configuration or secret-material variant. |
projection.replacements | array · min 1 items; max 32 items | Yestype = "placeholder_substitution" | Placeholder replacement rules applied at the network boundary. |
projection.replacements[] | object | Yeseach array item | — |
projection.replacements[].placeholder | string · min length 1; max length 512 | Yeseach array item | Literal placeholder to replace in the selected request locations. |
projection.replacements[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
projection.replacements[].locations | array · min 1 items; max 3 items | Yeseach array item | Request locations where placeholder replacement applies. |
projection.replacements[].locations[] | string · values: "header" | "query" | "body" | Yeseach array item | — |
projection | object | Yestype = "tls_client_certificate" | — |
projection.type | string · values: "tls_client_certificate" | Yestype = "tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
projection | object | Yestype = "username_password" | — |
projection.type | string · values: "username_password" | Yestype = "username_password" | Discriminator selecting the configuration or secret-material variant. |
projection | object | Yestype = "ssh_proxy" | — |
projection.type | string · values: "ssh_proxy" | Yestype = "ssh_proxy" | Discriminator selecting the configuration or secret-material variant. |
projection.upstreamUsername | string · min length 1; max length 255 | Yestype = "ssh_proxy" | Username used for the upstream SSH connection. |
projection.sandboxPublicKeys | array · min 1 items; max 16 items | Yestype = "ssh_proxy" | Public keys allowed to use this Sandbox-side SSH proxy binding. |
projection.sandboxPublicKeys[] | string · min length 1; max length 16384 | Yeseach array item | — |
projection.knownHosts | array · min 0 items; max 64 items | Notype = "ssh_proxy" | Known-host entries for upstream SSH host verification. |
projection.knownHosts[] | string · min length 1; max length 16384 | Yeseach array item | — |
rule | object | Yes | Matching outbound destinations and resolver failure policy. |
rule.protocol | string · values: "http" | "https" | "grpc" | "tls" | "ssh" | "socks5" | "mqtt" | "redis" | Yeswithin rule | Network protocol to which the binding applies. |
rule.domains | array · min 1 items; max 128 items | Yeswithin rule | Destination domain patterns matched by the credential rule. |
rule.domains[] | string · min length 1; max length 255 | Yeseach array item | Exact or wildcard domain, e.g. api.example.com or *.example.com; URLs, paths and ports are rejected. Domains are normalized and deduplicated. |
rule.ports | array · min 1 items; max 16 items | Yeswithin rule | Destination ports matched by the credential rule. |
rule.ports[] | object | Yeseach array item | — |
rule.ports[].port | integer · ≥ 1; ≤ 65535 | Yeseach array item | Port number matched by this destination rule. |
rule.ports[].protocol | string · values: "tcp"; default: "tcp" | Noeach array item | Network protocol to which the binding applies. |
rule.failurePolicy | string · values: "fail-closed" | "fail-open"; default: "fail-closed" | Nowithin rule | Behavior when the network-boundary credential cannot be resolved. |
enabled | boolean · default: true | No | Whether this configuration is enabled for future use. |
Example
{
"name": "GitHub API",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "Authorization",
"valueTemplate": "Bearer {{ .token }}"
}
]
},
"rule": {
"protocol": "https",
"domains": [
"api.github.com"
],
"ports": [
{
"port": 443
}
],
"failurePolicy": "fail-closed"
},
"enabled": true
}Responses
200 OK.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object · extra fields rejected | Yes | Secret-free configuration and observed source state. Contains neither material nor the internal Sandbox0 source reference. |
data.name | string · min length 1; max length 80Validation pattern\S | Yeswithin data | Human-readable name for this resource. |
data.resolverKind | string · values: "static_headers" | "static_tls_client_certificate" | "static_username_password" | "static_ssh_private_key" | Yeswithin data | Credential material resolver. Its kind is immutable after creation and must match the material type. |
data.projection | one of the variants below | Yeswithin data | Projection variant applied at the network boundary. Choose the type matching the configured resolver. |
data.projection | object | Yestype = "http_headers" | — |
data.projection.type | string · values: "http_headers" | Yestype = "http_headers" | Discriminator selecting the configuration or secret-material variant. |
data.projection.headers | array · min 1 items; max 32 items | Yestype = "http_headers" | Header definitions or secret header values applied by this configuration. |
data.projection.headers[] | object | Yeseach array item | — |
data.projection.headers[].name | string · min length 1; max length 128Validation pattern^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ | Yeseach array item | Human-readable name for this resource. |
data.projection.headers[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data.projection | object | Yestype = "placeholder_substitution" | — |
data.projection.type | string · values: "placeholder_substitution" | Yestype = "placeholder_substitution" | Discriminator selecting the configuration or secret-material variant. |
data.projection.replacements | array · min 1 items; max 32 items | Yestype = "placeholder_substitution" | Placeholder replacement rules applied at the network boundary. |
data.projection.replacements[] | object | Yeseach array item | — |
data.projection.replacements[].placeholder | string · min length 1; max length 512 | Yeseach array item | Literal placeholder to replace in the selected request locations. |
data.projection.replacements[].valueTemplate | string · min length 1; max length 2048 | Yeseach array item | Projection template referring to credential variables; do not embed a secret value here. |
data.projection.replacements[].locations | array · min 1 items; max 3 items | Yeseach array item | Request locations where placeholder replacement applies. |
data.projection.replacements[].locations[] | string · values: "header" | "query" | "body" | Yeseach array item | — |
data.projection | object | Yestype = "tls_client_certificate" | — |
data.projection.type | string · values: "tls_client_certificate" | Yestype = "tls_client_certificate" | Discriminator selecting the configuration or secret-material variant. |
data.projection | object | Yestype = "username_password" | — |
data.projection.type | string · values: "username_password" | Yestype = "username_password" | Discriminator selecting the configuration or secret-material variant. |
data.projection | object | Yestype = "ssh_proxy" | — |
data.projection.type | string · values: "ssh_proxy" | Yestype = "ssh_proxy" | Discriminator selecting the configuration or secret-material variant. |
data.projection.upstreamUsername | string · min length 1; max length 255 | Yestype = "ssh_proxy" | Username used for the upstream SSH connection. |
data.projection.sandboxPublicKeys | array · min 1 items; max 16 items | Yestype = "ssh_proxy" | Public keys allowed to use this Sandbox-side SSH proxy binding. |
data.projection.sandboxPublicKeys[] | string · min length 1; max length 16384 | Yeseach array item | — |
data.projection.knownHosts | array · min 0 items; max 64 items | Notype = "ssh_proxy" | Known-host entries for upstream SSH host verification. |
data.projection.knownHosts[] | string · min length 1; max length 16384 | Yeseach array item | — |
data.rule | object | Yeswithin data | Matching outbound destinations and resolver failure policy. |
data.rule.protocol | string · values: "http" | "https" | "grpc" | "tls" | "ssh" | "socks5" | "mqtt" | "redis" | Yeswithin data | Network protocol to which the binding applies. |
data.rule.domains | array · min 1 items; max 128 items | Yeswithin data | Destination domain patterns matched by the credential rule. |
data.rule.domains[] | string · min length 1; max length 255 | Yeseach array item | Exact or wildcard domain, e.g. api.example.com or *.example.com; URLs, paths and ports are rejected. Domains are normalized and deduplicated. |
data.rule.ports | array · min 1 items; max 16 items | Yeswithin data | Destination ports matched by the credential rule. |
data.rule.ports[] | object | Yeseach array item | — |
data.rule.ports[].port | integer · ≥ 1; ≤ 65535 | Yeseach array item | Port number matched by this destination rule. |
data.rule.ports[].protocol | string · values: "tcp"; default: "tcp" | Noeach array item | Network protocol to which the binding applies. |
data.rule.failurePolicy | string · values: "fail-closed" | "fail-open"; default: "fail-closed" | Nowithin data | Behavior when the network-boundary credential cannot be resolved. |
data.enabled | boolean · default: true | Yeswithin data | Whether this configuration is enabled for future use. |
data.id | string · min length 1 | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string · min length 1 | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.status | string · values: "provisioning" | "active" | "error" | "deleting" | Yeswithin data | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data.currentVersion | integer · ≥ 1 | Nowithin data | Observed current credential source version. |
data.sourceStatus | string · min length 1 | Nowithin data | Observed credential source state from Sandbox0. |
data.error | string · min length 1 | Nowithin data | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
data.createdAt | number | Yeswithin data | Creation time as a Unix timestamp in seconds. |
data.updatedAt | number | Yeswithin data | Last update time as a Unix timestamp in seconds. |
Example
{
"data": {
"name": "example",
"resolverKind": "static_headers",
"projection": {
"type": "http_headers",
"headers": [
{
"name": "example",
"valueTemplate": "example"
}
]
},
"rule": {
"protocol": "http",
"domains": [
"example"
],
"ports": [
{
"port": 1
}
]
},
"enabled": false,
"id": "example",
"environmentId": "example",
"status": "provisioning",
"createdAt": 0,
"updatedAt": 0
}
}Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}Delete a credential
Deletion removes the binding and its source. It does not reauthenticate already established connections.
Delete an Environment egress credential
/v1/environments/{environmentId}/egress-credentials/{credentialId}Requires a personal token for a personal Environment or a token scoped to the owning Project. Secret material is stored only in Sandbox0. Mutations use the Environment lifecycle lock and require a ready Environment; paused Environments are supported. Active work can delay mutations while holding the lifecycle lock. Applied changes affect subsequent outbound connections. Credentials are not inherited by forks and are not restored by Run rollback.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: credentialId | string · min length 1 | Yes | Egress credential identifier within this Environment. |
Request example
curl -X DELETE \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/egress-credentials/$CREDENTIAL_ID" \
-H "Authorization: Bearer $SANDPI_API_TOKEN"No request body.
Responses
204 Deleted.Empty response body.
Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}