Skip to main content
This page describes how public endpoints work, how to declare one when you create a sandbox, and how to connect to it. A public endpoint gives a service running inside a sandbox an address that clients can reach from the internet. You request one when you create the sandbox, and the platform provisions the routing, DNS, and network access for it. The address belongs to the sandbox for as long as the sandbox runs. Endpoints come in two kinds, which differ in where TLS terminates:
  • HTTPS: The platform terminates TLS at its edge with a certificate it provisions and renews, then forwards the request to your port as cleartext HTTP.
  • TLS passthrough: The platform routes the connection to your port by Server Name Indication (SNI) without decrypting it. Your workload terminates TLS and owns its own certificates.
Choose TLS passthrough when the workload must hold the private key itself: mutual TLS, a client that pins a certificate, or a protocol that isn’t HTTP.

Choose authentication

These examples run on serverless capacity unless a section specifies CoreWeave Kubernetes Service (CKS). Choose the credential for the account that owns your sandboxes. See Choose and get credentials to obtain a key or token. Save the configuration for your language beside the scripts you run from this page. Python examples import AUTH from sandbox_auth.py. TypeScript examples import client from sandbox-client.mts. These files select authentication without storing your credential. For Python, use an active virtual environment. For TypeScript, first install the client with npm install @coreweave/cwsandbox.
Use your Forge API key with the SDK’s wandb integration. Replace [WANDB-API-KEY] with your API key:
sandbox_auth.py
For CKS placement, choose the CoreWeave token, enable a runner, and set placement_mode="cks" on sandbox creation or in SandboxDefaults. In TypeScript, choose the CoreWeave token and set a nonempty runnerIds array to select CKS. Creating a Python session with auth=AUTH also authenticates the sandboxes it owns. Keep the same credential when reconnecting, listing, or cleaning up sandboxes. The Python share-token example requires cwsandbox 1.16.0 or later and a deployment with HTTPS share-token support. The credential you configure in this section authenticates SDK operations such as creating and deleting sandboxes. It’s separate from the endpoint share token that callers use to access a protected HTTPS URL.

Compare the two kinds

Both kinds are reachable from the internet. HTTPS with OPEN and TLS passthrough have no platform caller authentication. The workload must enforce any access control you need. HTTPS with SHARE_TOKEN requires the issued token on each request. Anyone with that token can access the protected endpoint.

Declare an endpoint

Declare endpoints in the services list when you create the sandbox. Ports are fixed for the sandbox’s lifetime, and no call exposes a port on a sandbox that is already running. To give a service a public endpoint, set visibility=ServiceVisibility.PUBLIC and an endpoint value on it. A plain service has no endpoint value. For example, Service(port=8080, name="web") leaves visibility and endpoint unset: It declares a container-local port without requesting external exposure. Visibility on a plain service controls reachability through the deployment’s service networking. It doesn’t request a public HTTPS URL or TLS passthrough address. To require a token, use EndpointAuth.SHARE_TOKEN as shown in Connect with a share token. For an HTTPS endpoint without platform caller authentication, set kind=EndpointKind.HTTPS and auth=EndpointAuth.OPEN:
For a TLS passthrough endpoint, set kind=EndpointKind.TLS_PASSTHROUGH and leave auth unset. The command you run must terminate TLS on the port itself, because the platform forwards the connection without decrypting it:
One sandbox can mix both endpoint kinds, including OPEN and SHARE_TOKEN HTTPS endpoints. The following rules apply:
  • Ports and names must be unique across all services entries, including names generated for unnamed ports.
  • Entries with an endpoint require visibility=PUBLIC. Set protocol=TCP or leave protocol unset. The platform rejects UDP and SCTP endpoints.
  • Plain entries without an endpoint can leave visibility unset or use PRIVATE, PUBLIC, or CUSTOM. They can declare TCP, UDP, or SCTP. An unset protocol defaults to TCP. Actual exposure depends on deployment capabilities and policy. These fields don’t create a public endpoint.
  • Don’t mix exposed plain services with endpoint entries. In a sandbox with endpoints, leave visibility unset on any plain service. Without endpoints, use at most one exposed visibility value across plain services.
  • Omit auth and request_timeout_seconds for TLS passthrough. In Python, pass None rather than 0. The SDK rejects a set timeout, including 0.
  • A platform limit caps how many services one sandbox declares. Operators configure the cap for their deployment.

Connect with a share token

To require platform authentication for an HTTPS endpoint, set auth=EndpointAuth.SHARE_TOKEN. Read sandbox.endpoint_share_token from the handle that creates the sandbox, and send its as_headers() result with each request. This helper sets the X-Sandbox-Share-Token header. The platform checks the token before forwarding the request to your HTTP service. In TypeScript, set auth: "share_token" and send sandbox.endpointShareToken in the X-Sandbox-Share-Token request header. The token is returned at creation. Get, list, and Sandbox.from_id() don’t return it. The original handle retains it across wait() and get_status(). If the initial response omits it, sandbox.start().result() retries recovery on the same create handle. If recovery still returns no token, stop the sandbox and create another. Keep the token secret: The dictionary returned by as_headers() contains the credential. Don’t log this dictionary. The following Python example starts a 5-minute HTTP service behind a protected HTTPS endpoint. It waits for URL assignment and retries authenticated requests while the application and route become ready. After a successful request, it verifies that an anonymous request is rejected. The context manager stops the sandbox when the example exits.
For the same HTTP service with auth=EndpointAuth.OPEN, an anonymous request succeeds once the service is ready. No share token is required. To change the auth mode, create a new sandbox. One sandbox can contain both modes, and the token protects only its SHARE_TOKEN endpoints. The generated Endpoint reference describes Python SDK version 1.14.2, which supports OPEN but predates SHARE_TOKEN.

Read the assigned address

The platform assigns the address. You can’t choose the hostname or supply your own domain. Read it back from the sandbox rather than constructing it, because the DNS zone differs per cluster and isn’t part of the API contract. TLS passthrough addresses arrive on service_addresses as host:port, and HTTPS URLs arrive on service_urls. The two lists stay separate: A TLS endpoint never appears in service_urls.
You should see output similar to the following:
The advertised port is the platform’s TLS listener port, not the port your process binds inside the sandbox. In this example, the workload listens on 8443 and clients connect to 443. The two kinds become readable at different points in the sandbox’s startup:
  • A TLS passthrough address is assigned when the sandbox is created, so it is on the create response and stays available while the sandbox is creating or running.
  • An HTTPS URL is available once its route has a hostname, while the sandbox is creating or running. Call get_status() in Python or inspect() in TypeScript in a loop until the URL appears or your own deadline passes.
  • Neither one means the application is serving. The platform doesn’t wait for your process to bind the port before reporting the sandbox as running, so retry your first connection.
The platform reports endpoints while a sandbox is creating or running, and clears them in every other state. A paused or completed sandbox has no reachable endpoint.

Connect to a TLS passthrough endpoint

Because the platform doesn’t decrypt the connection, the certificate a client receives is the one your workload presents. Two things follow for the client:
  • Send the endpoint host as the SNI server name. The platform routes on SNI alone, so a connection that omits it, or sends a different name, doesn’t reach your sandbox.
  • Trust the workload’s certificate. The endpoint hostname is platform-assigned, so a certificate you issue yourself doesn’t match it unless you issue it for that hostname. Configure the client to trust your own certificate authority, or pin the certificate.
The following client sends the endpoint host as SNI while connecting to the advertised address. Replace [ENDPOINT-ADDRESS] with the address you read from service_addresses, and [PATH-TO-CA-CERT] with the path to the certificate authority that signed your workload’s certificate:

Endpoint lifetime

An endpoint lives as long as the sandbox that owns it:
  • It’s keyed to the sandbox, not to a Pod. If the underlying Pod restarts, the address stays the same.
  • Deleting the sandbox removes the endpoint. The address doesn’t move to another sandbox, and a new sandbox gets a new address.
  • Nothing is reserved between sandboxes. You can’t hold a hostname for reuse.

Troubleshoot create failures

If no runner in your fleet supports the endpoint kind you requested, the create call fails rather than starting a sandbox with the endpoint silently dropped.
Last modified on October 24, 2026