> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyberun.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Call a container service

> Three ways to reach a running container service — transparent proxy, structured invoke, and discovery.

A **container service** is a long-running container hosted on your
team's agents (see [Container services](/cloud/concepts/containers)
for the concept and
[Deploy a container service](/cloud/guides/deploy-container) for the
setup walkthrough).

Once a service is `running`, three runtime endpoints let you reach
it. All accept JWT, `sk-`, or `dk-` Bearer auth.

## Discover services

List the services visible to your team:

```http theme={null}
GET /api/v1/r/containers HTTP/1.1
Authorization: Bearer sk-...
```

Or look up a single service by its slug:

```http theme={null}
GET /api/v1/r/containers/{serviceSlug} HTTP/1.1
Authorization: Bearer sk-...
```

Key fields in the response:

| Field            | Meaning                                                                                                                  |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `service_slug`   | URL-safe identifier. Used in the proxy and invoke paths.                                                                 |
| `service_status` | One of `created`, `deploying`, `running`, `stopping`, `stopped`, `failed`.                                               |
| `exposed_port`   | The in-container port the service listens on.                                                                            |
| `service_type`   | `deployed` (runs on a team agent) or `external` (egress to an external URL).                                             |
| `usage_prompt`   | Optional natural-language description for AI agents. Public to anyone who can list the service — never put secrets here. |
| `openapi_url`    | Optional path on the container that serves an OpenAPI document. AI clients can fetch this for schemas before invoking.   |

## Transparent proxy

For shell scripts, raw HTTP clients, and anything that already
speaks the container's protocol natively, use the catch-all proxy:

```
ANY /api/v1/r/containers/{serviceSlug}/*
```

The path after the slug is forwarded to the container as-is, and the
container's response is relayed back unchanged.

```bash theme={null}
# vLLM exposes the OpenAI-compatible API
curl -H "Authorization: Bearer sk-..." \
  https://core.cyberun.cloud/api/v1/r/containers/my-llm/v1/models

curl -X POST \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{"model":"llama3","messages":[{"role":"user","content":"hi"}]}' \
  https://core.cyberun.cloud/api/v1/r/containers/my-llm/v1/chat/completions
```

Because the proxy preserves OpenAI's request and response shape, you
can point any OpenAI-compatible SDK at the proxy by overriding its
`baseURL`:

```ts theme={null}
import OpenAI from 'openai';

const client = new OpenAI({
	apiKey: process.env.CYBERUN_KEY,
	baseURL: 'https://core.cyberun.cloud/api/v1/r/containers/my-llm'
});

const reply = await client.chat.completions.create({
	model: 'llama3',
	messages: [{ role: 'user', content: 'hi' }]
});
```

The same trick works for any vendor SDK whose underlying HTTP shape
matches what the container exposes.

## Structured invoke (MCP-friendly)

For programmatic and MCP callers that want a single fixed request
shape rather than a catch-all path:

```http theme={null}
POST /api/v1/r/invoke/{serviceSlug} HTTP/1.1
Authorization: Bearer sk-...
Content-Type: application/json

{
  "method": "POST",
  "path": "/v1/chat/completions",
  "headers": { "Content-Type": "application/json" },
  "body_base64": "eyJtb2RlbCI6Imxsb..."
}
```

Body fields:

| Field         | Required | Meaning                                                                                                                                  |
| ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `method`      | yes      | HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS`).                                                                |
| `path`        | yes      | Path on the container including leading `/`. Query strings allowed. Absolute or protocol-relative URLs are rejected.                     |
| `body_base64` | no       | Request body, base64-encoded so binary payloads survive JSON transport. Omit for `GET` / `DELETE`.                                       |
| `headers`     | no       | Headers to forward. Hop-by-hop headers (`Host`, `Connection`, `Upgrade`, `Transfer-Encoding`, `TE`, `Trailer`) are stripped server-side. |

Response:

```json theme={null}
{
  "status_code": 200,
  "headers": { "Content-Type": "application/json" },
  "body_base64": "eyJjaG9pY2VzIjpbey4uLn1dfQ=="
}
```

`/r/invoke/{slug}` lives at its own path rather than
`/r/containers/{slug}/invoke` so that a container that itself exposes
a `/invoke` endpoint stays reachable via the catch-all proxy.

### When to use which

| If you're …                                            | Use the …               |
| ------------------------------------------------------ | ----------------------- |
| writing shell scripts, `curl`, or an OpenAI-SDK pivot  | transparent proxy       |
| wiring a service into an MCP tool with a fixed shape   | structured `/r/invoke/` |
| forwarding binary payloads from a non-streaming caller | structured `/r/invoke/` |

## Status codes

Both endpoints surface gateway-level failures with these codes
before the container is reached:

| Code  | Meaning                                                                                                   |
| ----- | --------------------------------------------------------------------------------------------------------- |
| `400` | The service is not in `running` state (still `created`, `deploying`, `stopping`, `stopped`, or `failed`). |
| `404` | Service slug not found in this team.                                                                      |
| `502` | The agent or gateway tunnel returned an error talking to the container.                                   |
| `503` | The service is running but unavailable — no healthy instance, or no online agent can reach it.            |

Any other status code is what the container itself returned.

## Related

* [Container services](/cloud/concepts/containers) — the data model.
* [Deploy a container service](/cloud/guides/deploy-container) —
  create and deploy a service.
* [API reference](/api-reference/introduction) — full endpoint list.
