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

# Sessions

> Learn about session management and request isolation.

## Ephemeral vs. Session mode

By default, each `fetch()` call runs in **ephemeral mode**. This is a good fit for one-off requests.

For multi-step flows (like login sequences), use **sessions** to persist state.

| Scenario                              | Recommended                  | Why                                  |
| ------------------------------------- | ---------------------------- | ------------------------------------ |
| One-off request, no cookie carryover  | Ephemeral (default)          | Request context is isolated per call |
| Multi-step login or reuse cookies     | Session                      | Shared session context               |
| Parallel jobs that must stay isolated | Ephemeral or per-job session | Avoid cross-talk between tasks       |

## Creating a session

```typescript theme={null}
import { createSession } from 'wreq-js';

const session = await createSession({ browser: 'chrome_142' });

// All requests share the same cookie jar
await session.fetch('https://example.com/login', {
  method: 'POST',
  body: new URLSearchParams({ user: 'name', pass: 'secret' }),
});

// Cookies from login are automatically included
const dashboard = await session.fetch('https://example.com/dashboard');
console.log(await dashboard.text());

// Always close when done
await session.close();
```

## Auto-disposing sessions

Use `withSession()` to automatically close the session when done:

```typescript theme={null}
import { withSession } from 'wreq-js';

await withSession(async (session) => {
  await session.fetch('https://example.com/login', {
    method: 'POST',
    body: 'credentials',
  });
  
  const data = await session.fetch('https://example.com/data');
  console.log(await data.json());
}); // Session is automatically closed here
```

## Session options

Sessions accept `browser`, `os`, `proxy`, `timeout`, `insecure`, and `defaultHeaders`:

```typescript theme={null}
const session = await createSession({
  browser: 'chrome_142',
  os: 'windows',
  proxy: 'http://proxy.example.com:8080',
  insecure: false,
});
```

## Per-request overrides

Within a session, `browser`, `os`, and `proxy` are fixed at creation time unless you pass an explicit `transport` for that request.

You can still override per-request values like `timeout`, `headers`, `redirect`, and `body`:

```typescript theme={null}
const session = await createSession({
  browser: 'chrome_142',
  timeout: 30_000,
});

// Override timeout for a single request
await session.fetch('https://example.com', {
  timeout: 5_000,
  headers: {
    'accept': 'text/html,application/xhtml+xml',
  },
});
```

## Cookie management

Sessions automatically handle cookies across requests, but you can also read and write cookies directly.

### Reading cookies

Use `getCookies(url)` to inspect which cookies would be sent to a URL:

```typescript theme={null}
await session.fetch('https://example.com/login', {
  method: 'POST',
  body: new URLSearchParams({ user: 'name', pass: 'secret' }),
});

const cookies = session.getCookies('https://example.com');
console.log(cookies);
// { "session_id": "abc123", "csrf": "xyz" }
```

Use `getAllCookies()` when you want to inspect the entire session jar without already knowing the matching domain/path:

```typescript theme={null}
const cookies = session.getAllCookies();
console.log(cookies);
// [
//   { name: "session_id", value: "abc123", secure: true, httpOnly: true, domain: "example.com", path: "/" }
// ]
```

If available, each entry also includes scope metadata such as `domain`, `path`, `sameSite`, and `expiresAtMs`.

### Setting cookies manually

Use `setCookie(name, value, url)` to inject a cookie into the session jar:

```typescript theme={null}
session.setCookie('auth_token', 'my-token', 'https://example.com');

// Subsequent requests to example.com will include the cookie
const resp = await session.fetch('https://example.com/api');
```

### Clearing cookies

Use `clearCookies()` to remove all cookies from the session:

```typescript theme={null}
await session.clearCookies();
```

## Session isolation

Each session maintains its own:

1. Cookie jar: cookies are not shared between sessions
2. Session identifier and defaults

If you want separate cookie jars but shared transport settings (for example, multiple sessions through the same proxy), use a shared **Transport** per request.

```typescript theme={null}
// These sessions are completely isolated
const session1 = await createSession({ browser: 'chrome_142' });
const session2 = await createSession({ browser: 'firefox_139' });

// Cookies set in session1 do not affect session2
await session1.fetch('https://example.com/set-cookie');
await session2.fetch('https://example.com/check-cookie'); // No cookie present
```

## Best practices

<CardGroup cols={2}>
  <Card title="Always close sessions" icon="door-closed">
    Call `session.close()` or use `withSession()` to prevent resource leaks.
  </Card>

  <Card title="One session per flow" icon="route">
    Use a dedicated session for each logical user flow or task.
  </Card>

  <Card title="Parallel isolation" icon="split">
    For parallel scraping, create separate sessions to avoid cookie cross-contamination.
  </Card>

  <Card title="Reuse for workflow consistency" icon="gauge">
    Sessions keep one context for multi-step flows.
  </Card>
</CardGroup>
