# ctx.http and ctx.auth()

> Reference for ctx.http, the ky HTTP client, the authed() proxy rewrite that injects credentials server side, and ctx.auth() for non-sensitive variables.

`ctx.http` is a [ky](https://github.com/sindresorhus/ky) instance for outbound HTTP. Call it directly for plain requests, or call `ctx.http.authed(alias)` to route the request through the Helix proxy service, which injects credentials server side so secrets never reach your code. `ctx.auth(alias)` returns the non-sensitive variables of a credential record.

## ctx.http: a ky instance

Everything ky supports works on `ctx.http`: `get`, `post`, `put`, `patch`, `delete`, `head`, the `json:` request option, `.json<T>()` on responses, retries, timeouts, `extend()`, and the `beforeRequest`/`afterResponse`/`beforeRetry` hooks.

```typescript
const data = await ctx.http
  .get('https://api.open-meteo.com/v1/forecast', {
    searchParams: { latitude: 51.5, longitude: -0.1 },
    retry: { limit: 3, backoffLimit: 3000 },
    timeout: 10_000,
  })
  .json();
```

Unauthenticated calls go directly to the target but are still logged and traced.

## ctx.http.authed(alias)

```typescript
authed(alias: string): KyInstance
```

| Parameter | Type | Description |
|---|---|---|
| `alias` | `string` | A key from `authentications` in `helix.config.ts`, mapping to a credential UUID. An unknown alias throws an error listing the available aliases. |

The returned instance is standard ky with a `beforeRequest` hook that rewrites every request to the Helix proxy service. Because it's plain ky, you can `extend()` it with a `prefixUrl` or default headers.

URLs may contain `{{variable}}` placeholders (for example `{{instance_url}}`); the proxy resolves them from non-sensitive credential fields before forwarding.

### What the proxy rewrite does

For this call:

```typescript
ctx.http.authed('salesforce_prod').get('{{instance_url}}/services/data/v59.0/query', {
  searchParams: { q: 'SELECT Id FROM Contact' },
});
```

the hook rewrites the request into a proxy request carrying the original target in headers:

```http
GET https://proxy.helix.tray.ai/proxy
x-helix-target-url: {{instance_url}}/services/data/v59.0/query?q=SELECT+Id+FROM+Contact
x-helix-auth-id: 1a0fbf5c-2c9e-4aa1-ada3-ccbba65019ab
x-helix-project-id: a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d
x-helix-execution-id: exec_789xyz
```

| Header | Contents |
|---|---|
| `x-helix-target-url` | The original URL, templates unresolved, query string included |
| `x-helix-auth-id` | The credential UUID the alias maps to |
| `x-helix-project-id` | The calling project |
| `x-helix-execution-id` | The current execution, for log correlation |

The proxy then fetches the credential record, resolves `{{instance_url}}`, applies the signing strategy defined by the connector type (Bearer, API key, Basic, OAuth 1.0a, AWS SigV4, HMAC, or custom), forwards the request, and returns the response. If an OAuth token has expired or the target returns 401, the proxy refreshes the token and retries once. Every request and response is logged with credentials redacted. Signing strategies and the credential model are covered in [the connected services guide](/documentation/guides/connected-services/).

## ctx.auth(alias)

```typescript
auth(alias: string): Promise<Record<string, string>>
```

Returns only the non-sensitive variables of the credential record, for use in logging, conditional logic, or constructing non-HTTP resources. Tokens, API keys, and other secrets are never returned; the proxy service decides which fields are safe based on the credential record's configuration.

```typescript
const vars = await ctx.auth('salesforce_prod');
// { instance_url: 'https://mycompany.my.salesforce.com', subdomain: 'mycompany' }
```

## Example

```typescript
// functions/api/v1/contacts.get.ts
import { defineFunction } from '@trayai/helix-sdk';

export default defineFunction(async (ctx) => {
  const sf = ctx.http.authed('salesforce_prod').extend({
    prefixUrl: '{{instance_url}}/services/data/v59.0',
  });

  const result = await sf
    .get('query', { searchParams: { q: 'SELECT Id, Name, Email FROM Contact' } })
    .json<{ records: Array<{ Id: string; Name: string; Email: string }> }>();

  return result.records;
});
```

---

Canonical: https://helix.tray.ai/documentation/reference/context/http/
Any link on this page is available as markdown by appending .md to its URL.
Full corpus: https://helix.tray.ai/documentation/llms-full.txt