> For the complete documentation index, see [llms.txt](https://docs.helodata.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.helodata.com/api-reference/sessions.md).

# Sessions

Inspect active sticky sessions on gateway products. Useful for monitoring long-running scrapes and for cleaning up sessions that shouldn't be using more bandwidth.

> ISP doesn't have a sessions API — every ISP IP is itself permanent, so there's no transient session state.

## Endpoints

| Method   | Path                       | Purpose                                 |
| -------- | -------------------------- | --------------------------------------- |
| `GET`    | `/residential/sessions`    | List active residential sticky sessions |
| `GET`    | `/mobile/sessions`         | List active mobile sticky sessions      |
| `GET`    | `/{product}/sessions/{id}` | Details for one session                 |
| `DELETE` | `/{product}/sessions/{id}` | Terminate a session early               |

## List

```bash
curl -H "Authorization: Bearer API_KEY" \
     "https://api.helodata.com/v1/residential/sessions?subuser=sub_01HX2K3PQ4M5"
```

Response:

```json
{
  "data": [
    {
      "id":               "ses_01HX2K3PQ4M5",
      "subuser":          "sub_01HX2K3PQ4M5",
      "session_id":       "job1",
      "region":           "us",
      "state":            "ca",
      "city":             "la",
      "asn":              7922,
      "exit_ip":          "198.51.100.42",
      "started_at":       "2026-05-28T07:00:00Z",
      "expires_at":       "2026-05-28T07:30:00Z",
      "bytes_used":       3145728,
      "requests":         42,
      "repinned":         false
    }
  ],
  "next_cursor": null
}
```

Filter parameters: `subuser`, `session_id`, `region`, `asn`, `repinned=true|false`.

### Fields

* `session_id` is the user-chosen part of the username (e.g. `job1` from `-session-job1-sesstime-30`).
* `repinned` flips to `true` if the upstream IP was reassigned mid-session.
* `expires_at` = `started_at + sesstime`.

## Get one

```bash
curl -H "Authorization: Bearer API_KEY" \
     "https://api.helodata.com/v1/residential/sessions/ses_01HX2K3PQ4M5"
```

Same fields as the list plus per-request samples (last 10 requests).

## Terminate

```bash
curl -X DELETE -H "Authorization: Bearer API_KEY" \
     "https://api.helodata.com/v1/residential/sessions/ses_01HX2K3PQ4M5"
```

Future requests with that exact username get a **new** exit IP, as if `sesstime` had elapsed. The session record is kept for 24h for audit; the entry's `status` becomes `terminated`.

Why terminate?

* A worker crashed and you want to ensure no stale state — minor effect since helodata will expire it anyway at `expires_at`
* You changed your mind about which geo to scrape — easier to drop than wait
* Cleanup as part of incident response

## Concurrency note

`session_id` reuse is allowed; the same `session_id` under different geo/sub-user counts as a **different** session. The full username is the session key.

## Errors

| Status | Code                     | Meaning                                           |
| ------ | ------------------------ | ------------------------------------------------- |
| `404`  | `session_not_found`      | Session expired or never existed                  |
| `403`  | `subuser_scope_mismatch` | Token scope doesn't cover this sub-user's product |
