---
title: "Create a new workload"
method: POST
path: "/api/v1beta/workloads"
tags: ["workloads"]
---

# Create a new workload

`POST /api/v1beta/workloads`

Create and start a new workload
runtime_config is only accepted for protocol-scheme images
(uvx://, npx://, go://); supplying it with an ordinary image
reference or a remote url is rejected with 400.

## Request body

- union
  - object
  - PkgApiV1CreateRequest — Request to create a new workload
    - `allow_docker_gateway` boolean — Whether to permit outbound connections to Docker gateway addresses (host.docker.internal, gateway.docker.internal, 172.17.0.1). These are blocked by default in the egress proxy even when network isolation is on. Only applicable to Docker deployments with network isolation enabled.
    - `authz_config` string — Authorization configuration
    - `cmd_arguments` string[] — Command arguments to pass to the container
    - `env_vars` object — Environment variables to set in the container
    - `group` string — Group name this workload belongs to
    - `header_forward` PkgApiV1HeaderForwardConfig — HeaderForward configures headers to inject into requests to remote MCP servers. Use this to add custom headers like X-Tenant-ID or correlation IDs.
      - `add_headers_from_secret` object — AddHeadersFromSecret maps header names to secret names in ToolHive's secrets manager. Key: HTTP header name, Value: secret name in the secrets manager
      - `add_plaintext_headers` object — AddPlaintextHeaders contains literal header values to inject. WARNING: These values are stored and transmitted in plaintext. Use AddHeadersFromSecret for sensitive data like API keys.
    - `headers` RegistryHeader[]
      - `choices` string[] — Choices provides a list of valid values for the header (optional)
      - `default` string — Default is the value to use if the header is not explicitly provided Only used for non-required headers
      - `description` string — Description is a human-readable explanation of the header's purpose
      - `name` string — Name is the header name (e.g., X-API-Key, Authorization)
      - `required` boolean — Required indicates whether this header must be provided If true and not provided via command line or secrets, the user will be prompted for a value
      - `secret` boolean — Secret indicates whether this header contains sensitive information If true, the value will be stored as a secret rather than as plain text
    - `host` string — Host to bind to
    - `image` string — Docker image to use
    - `name` string — Name of the workload
    - `network_isolation` boolean — Whether network isolation is turned on. This applies the rules in the permission profile. Pointer so that omitting the field defaults to network isolation ENABLED (matching the `thv run` CLI default); set it explicitly to false to disable network isolation. This also applies on update: a request that omits this field enables isolation, so clients that build update requests from scratch should send it explicitly to avoid unintentionally turning isolation on for a workload that had it off.
    - `oauth_config` PkgApiV1RemoteOAuthConfig — OAuth configuration for remote server authentication
      - `authorize_url` string — OAuth authorization endpoint URL (alternative to issuer for non-OIDC OAuth)
      - `bearer_token` SecretsSecretParameter — Bearer token for authentication (alternative to OAuth)
        - `name` string
        - `target` string
      - `callback_port` integer — Specific port for OAuth callback server
      - `client_id` string — OAuth client ID for authentication
      - `client_secret` SecretsSecretParameter — Bearer token for authentication (alternative to OAuth)
        - `name` string
        - `target` string
      - `issuer` string — OAuth/OIDC issuer URL (e.g., https://accounts.google.com)
      - `oauth_params` object — Additional OAuth parameters for server-specific customization
      - `resource` string — OAuth 2.0 resource indicator (RFC 8707)
      - `scopes` string[] — OAuth scopes to request
      - `skip_browser` boolean — Whether to skip opening browser for OAuth flow (defaults to false)
      - `token_url` string — OAuth token endpoint URL (alternative to issuer for non-OIDC OAuth)
      - `use_pkce` boolean — Whether to use PKCE for the OAuth flow
    - `oidc` PkgApiV1OidcOptions — OIDC configuration options
      - `audience` string — Expected audience
      - `client_id` string — OAuth2 client ID
      - `client_secret` string — OAuth2 client secret
      - `introspection_url` string — Token introspection URL for OIDC
      - `issuer` string — OIDC issuer URL
      - `jwks_url` string — JWKS URL for key verification
      - `scopes` string[] — OAuth scopes to advertise in well-known endpoint (RFC 9728)
    - `permission_profile` PermissionsProfile — Permission profile to apply
      - `name` string — Name is the name of the profile
      - `network` PermissionsNetworkPermissions — Network defines network permissions
        - `inbound` PermissionsInboundNetworkPermissions — Inbound defines inbound network permissions
          - `allow_host` string[] — AllowHost is a list of allowed hosts for inbound connections
        - `mode` string — Mode specifies the network mode for the container (e.g., "host", "bridge", "none") When empty, the default container runtime network mode is used
        - `outbound` PermissionsOutboundNetworkPermissions — Outbound defines outbound network permissions
          - `allow_host` string[] — AllowHost is a list of allowed hosts
          - `allow_port` integer[] — AllowPort is a list of allowed ports
          - `insecure_allow_all` boolean — InsecureAllowAll allows all outbound network connections
      - `privileged` boolean — Privileged indicates whether the container should run in privileged mode When true, the container has access to all host devices and capabilities Use with extreme caution as this removes most security isolation
      - `read` string[] — Read is a list of mount declarations that the container can read from These can be in the following formats: - A single path: The same path will be mounted from host to container - host-path:container-path: Different paths for host and container - resource-uri:container-path: Mount a resource identified by URI to a container path
      - `write` string[] — Write is a list of mount declarations that the container can write to These follow the same format as Read mounts but with write permissions
    - `proxy_mode` string — Proxy mode to use
    - `proxy_port` integer — Port for the HTTP proxy to listen on
    - `registry` string — Registry is the optional registry name to resolve the server from (e.g. "default").
    - `runtime_config` TemplatesRuntimeConfig — RuntimeConfig allows overriding the default runtime configuration for this specific workload (base images and packages)
      - `additional_packages` string[] — AdditionalPackages lists extra packages to install in the builder and runtime stages. Examples for Alpine: ["git", "make", "gcc"] Examples for Debian: ["git", "build-essential"]
      - `build_with` string[] — BuildWith lists build-time dependency constraints, interpreted per package ecosystem. For uvx:// builds these are PEP 508 requirement specifiers passed to `uv tool install --with`, used to constrain transitive dependencies the package itself leaves unbounded (e.g. "mcp<2"). Ecosystems without constraint support (npx://, go://) reject a non-empty BuildWith at build time.
      - `builder_image` string — BuilderImage is the full image reference for the builder stage. An empty string signals "use the default for this transport type" during config merging. Examples: "golang:1.26-alpine", "node:24-alpine", "python:3.14-slim"
      - `runtime_env` object — RuntimeEnv contains environment variables to inject into the Dockerfile's final runtime stage. Unlike BuildEnv (pkg/container/templates.TemplateData.BuildEnv), which only affects the builder stage, these variables are baked into the shipped image and are present in the running container's process environment at startup. Use this for values a packaged MCP server reads at process start (e.g. feature flags, cache backend selection), not for build-time package manager configuration. Keys must be uppercase with underscores, values are validated for safety.
    - `secrets` SecretsSecretParameter[] — Secret parameters to inject
      - `name` string
      - `target` string
    - `server` string — Server is the optional server name in the registry (e.g. "io.github.stacklok/fetch"). When both Registry and Server are set, thv resolves the server metadata server-side, filling in image, transport, env vars, permissions, etc. User-provided fields always override registry defaults.
    - `target_port` integer — Port to expose from the container
    - `tools` string[] — Tools filter
    - `tools_override` object — Tools override
    - `transport` string — Transport configuration
    - `trust_proxy_headers` boolean — Whether to trust X-Forwarded-* headers from reverse proxies
    - `url` string — Remote server specific fields
    - `volumes` string[] — Volume mounts

## Response `201`

Created

- PkgApiV1CreateWorkloadResponse — Response after successfully creating a workload
  - `name` string — Name of the created workload
  - `port` integer — Port the workload is listening on

## Other responses

- `400` — Bad Request
- `409` — Conflict

## Changes

> 49 revisions in range; 4 could not be searched.

- **2026-07-29** `3db2b10a01f6` — 1 info
  - added the new optional request property `oneOf[#/components/schemas/pkg_api_v1.createRequest]/runtime_config/build_with`
- **2026-07-16** `231570aa0bab` — 2 info
  - added the new optional request property `oneOf[#/components/schemas/pkg_api_v1.createRequest]/allow_docker_gateway`
  - added the new optional request property `oneOf[#/components/schemas/pkg_api_v1.createRequest]/runtime_config/runtime_env`
- **2026-04-21** `ead8d06eaeaa` — 2 info
  - added the new optional request property `oneOf[#/components/schemas/pkg_api_v1.createRequest]/registry`
  - added the new optional request property `oneOf[#/components/schemas/pkg_api_v1.createRequest]/server`
- **2026-04-13** `3b31034fd29e` — 1 info
  - added the new optional request property `oneOf[#/components/schemas/pkg_api_v1.createRequest]/runtime_config`
- **2026-03-17** `8ab2f5690c97` — 1 breaking, 1 info
  - removed `#/components/schemas/v1.createRequest` from the request body `oneOf` list
  - added `#/components/schemas/pkg_api_v1.createRequest` to the request body `oneOf` list

[Full history](https://skmtc.dev/stacklok/apis/toolhive-api/changes/api/v1beta/workloads/post.md)

---

[API](https://skmtc.dev/stacklok/apis/toolhive-api.md) · [All operations](https://skmtc.dev/stacklok/apis/toolhive-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/stacklok/toolhive-api/revisions/e9f942effcda/schema)
