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

# Making requests

> Use Tinfoil's SecureClient SDKs or the CLI to make attested requests to your container.

Tinfoil's `SecureClient` verifies the enclave before sending any data — same attestation flow as Tinfoil's inference API. Every request is authenticated against the container's attestation report and TLS certificate.

You need two values to connect:

* **`<CONTAINER_URL>`** — your container's hostname (e.g. `myapp.myorg.containers.tinfoil.dev`)
* **`<CONFIG_REPO>`** — the GitHub repo linked to your container, in `org/repo` format

<Note>
  The Rust `SecureClient` constructor retains an API-key argument for inference API compatibility, but raw requests through `http_client()` do not use it. Pass an empty string for custom containers, then add application authentication to individual requests if your service requires it.
</Note>

## GET requests

<CodeGroup>
  ```python Python theme={"dark"}
  from tinfoil import SecureClient

  client = SecureClient(
      enclave="<CONTAINER_URL>",
      repo="<CONFIG_REPO>",
  )

  # Attestation is verified automatically
  response = client.get("https://<CONTAINER_URL>/<YOUR_ENDPOINT>")
  print(response.status_code)
  ```

  ```go Go theme={"dark"}
  import tinfoil "github.com/tinfoilsh/tinfoil-go"

  client, err := tinfoil.NewSecureClient(
      "<CONTAINER_URL>",
      "<CONFIG_REPO>",
  )
  if err != nil {
      panic(err)
  }

  // Attestation is verified automatically
  resp, err := client.Get("https://<CONTAINER_URL>/<YOUR_ENDPOINT>")
  ```

  ```typescript JavaScript theme={"dark"}
  import { SecureClient } from "tinfoil";

  const client = new SecureClient({
      enclaveURL: "https://<CONTAINER_URL>",
      configRepo: "<CONFIG_REPO>",
  });

  await client.ready();

  // Attestation is verified automatically
  const response = await client.fetch(
      "https://<CONTAINER_URL>/<YOUR_ENDPOINT>"
  );
  ```

  ```rust Rust theme={"dark"}
  use tinfoil::SecureClient;

  #[tokio::main]
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let mut client = SecureClient::new(
          "<CONTAINER_URL>",
          "<CONFIG_REPO>",
          "",
      );
      client.verify().await?;

      // http_client() returns a verified, attestation-pinned reqwest::Client
      let response = client.http_client()?
          .get(format!("https://{}/<YOUR_ENDPOINT>", "<CONTAINER_URL>"))
          .send()
          .await?;
      println!("{}", response.status());
      Ok(())
  }
  ```
</CodeGroup>

## POST requests

<CodeGroup>
  ```python Python theme={"dark"}
  import json
  from tinfoil import SecureClient

  client = SecureClient(
      enclave="<CONTAINER_URL>",
      repo="<CONFIG_REPO>",
  )

  response = client.post(
      "https://<CONTAINER_URL>/<YOUR_ENDPOINT>",
      headers={"Content-Type": "application/json"},
      body=json.dumps({"key": "value"}).encode(),
  )
  print(response.status_code)
  print(response.body.decode())
  ```

  ```go Go theme={"dark"}
  import (
      "strings"

      tinfoil "github.com/tinfoilsh/tinfoil-go"
  )

  client, err := tinfoil.NewSecureClient(
      "<CONTAINER_URL>",
      "<CONFIG_REPO>",
  )
  if err != nil {
      panic(err)
  }

  resp, err := client.Post(
      "https://<CONTAINER_URL>/<YOUR_ENDPOINT>",
      "application/json",
      strings.NewReader(`{"key": "value"}`),
  )
  ```

  ```typescript JavaScript theme={"dark"}
  import { SecureClient } from "tinfoil";

  const client = new SecureClient({
      enclaveURL: "https://<CONTAINER_URL>",
      configRepo: "<CONFIG_REPO>",
  });

  await client.ready();

  const response = await client.fetch(
      "https://<CONTAINER_URL>/<YOUR_ENDPOINT>",
      {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ key: "value" }),
      }
  );
  const data = await response.json();
  ```

  ```rust Rust theme={"dark"}
  use serde_json::json;
  use tinfoil::SecureClient;

  #[tokio::main]
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let mut client = SecureClient::new(
          "<CONTAINER_URL>",
          "<CONFIG_REPO>",
          "",
      );
      client.verify().await?;

      let response = client.http_client()?
          .post(format!("https://{}/<YOUR_ENDPOINT>", "<CONTAINER_URL>"))
          .json(&json!({ "key": "value" }))
          .send()
          .await?
          .error_for_status()?
          .json::<serde_json::Value>()
          .await?;
      println!("{}", response);
      Ok(())
  }
  ```
</CodeGroup>

The client verifies the enclave is running the expected code from the pinned repo, then pins the TLS certificate for all subsequent requests. If anything doesn't match, the connection fails.

## Using the local proxy

You can also connect to your container with the standalone [Tinfoil Proxy CLI](/local-proxy/cli) (`tinfoil-proxy`), which runs a local reverse proxy that verifies attestation and forwards requests:

```bash theme={"dark"}
tinfoil-proxy \
  -e <CONTAINER_URL> \
  -r <CONFIG_REPO> \
  -p 3301
```

Then send requests to `http://localhost:3301` as if it were your container:

```bash theme={"dark"}
curl http://localhost:3301/<YOUR_ENDPOINT> \
  -H "Content-Type: application/json" \
  -d '{"key": "value"}'
```

## Using the CLI

For one-off verified requests without running a proxy, use `tinfoil http`:

```bash theme={"dark"}
tinfoil http post https://<CONTAINER_URL>/<YOUR_ENDPOINT> \
  -e <CONTAINER_URL> \
  -r <CONFIG_REPO> \
  -H "Content-Type: application/json" \
  -b '{"key": "value"}'
```

Add any other request headers with repeatable `-H, --header` flags, such as `-H "Authorization: Bearer <TOKEN>"`.

If you've logged in with `tinfoil login`, use `tinfoil container connect <name>` to skip looking up the container URL and config repo by hand — the CLI resolves both from the container name and starts the same verified proxy:

```bash theme={"dark"}
tinfoil container connect my-api -p 3301
```

The proxy binds to `127.0.0.1` by default. Use `--bind <ADDRESS>` to choose another interface, for example when connecting from another container:

```bash theme={"dark"}
tinfoil container connect my-api --port 3301 --bind 0.0.0.0
```

Only bind beyond localhost on a trusted network because other hosts may then send requests through the proxy.

See [Managing containers from the CLI](/containers/cli) for the rest of the management surface.

<Warning>
  Debug mode containers do not pass attestation. This is by design — debug enclaves trade confidentiality for inspectability.
</Warning>
