---
title: "Create stateful sessions"
method: POST
path: "/v1/proxy/packages/{package_id}/stateful-sessions"
tags: ["Stateful Sessions"]
---

# Create stateful sessions

`POST /v1/proxy/packages/{package_id}/stateful-sessions`

## Request

- Base URL: `https://api.platform.soax.com`
- URL: `https://api.platform.soax.com/v1/proxy/packages/{package_id}/stateful-sessions`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/soax/apis/soax-api/docs/v1/proxy/packages/:package_id/stateful-sessions/post.ts> (a function with typed inputs; its response is checked against the schema)

Create one or more stateful sessions on a package. Each session is bound to a matching exit node before the response returns, so you get its exit IP and connection string straight away.

The `ruleset` is optional: omit it or send `{}` to use the defaults (`lookalike: false`, `rotation_trigger: "timed:300"`, `error_handling: "replace"`). With `count` > 1, each session gets the base `name` plus a number (`job` gives `job1`, `job2`, …).

Node assignment is per session. A session that cannot be bound is discarded, so the response can hold fewer sessions than you asked for: check `failed` and `reason`. If none could be bound, the request fails with `503` and a `Retry-After` header.

Creates for the same package run one at a time; an overlapping create may get `429`.

Requires the `proxy:packages:write` scope.

## Path parameters

- `package_id` string, required: The ID of the proxy package (UUID format)

## Request body

- StatefulSessionCreateRequest
  - `name` string, nullable: Session name, `^[a-z0-9]{1,16}$`, unique within the package. With `count` > 1 it is the base name and each session gets a number appended, which counts toward the 16 characters. Omit it and a name is generated.
  - `ruleset` StatefulSessionRequestRulesetSchema
    - `network_type` 'wifi' | 'mobile' | 'any', nullable: `wifi` (residential), `mobile`, or `any`. Must be enabled on the package.
    - `country` string, nullable: Two-letter country code, or `any`. Must be available on the package. Required when any of `region`, `city`, `isp`, `asn` or `zip` is set.
    - `region` string, nullable: Region code from the package location endpoints. Must belong to `country`.
    - `city` string, nullable: City code from the package location endpoints. Must belong to `region`, or to `country` when no region is set.
    - `isp` string, nullable: ISP code from the package location endpoints, valid for the chosen country, region and city.
    - `asn` string, nullable: ASN from the package location endpoints. Requires ASN targeting on your plan.
    - `zip` string, nullable: ZIP code from the package location endpoints. Requires ZIP targeting on your plan.
    - `lookalike` boolean, nullable: `true` or `false`: whether a replacement node should resemble the previous one (same ISP and location where possible). Defaults to `false` on create. Cannot be `true` with `rotation_trigger: "bind"`. On update, omit it to keep the stored value; `null` is rejected (422).
    - `rotation_trigger` string, nullable: When the exit node changes: `timed:<seconds>` (minimum 10), `request-count:<requests>`, `on-error` (only when the node fails) or `bind` (pin the node). Defaults to `timed:300` on create. `bind` cannot be combined with `error_handling: "replace"` or `lookalike: true`. On update, omit it to keep the stored value; `null` is rejected (422).
    - `error_handling` string, nullable: What happens when the bound node fails: `replace` (switch to a new node), `retry_<attempts>` (retry on the same node first) or `fail` (return the error). Defaults to `replace` on create, or `retry_3` when `rotation_trigger` is `bind`. On update, omit it to keep the stored value; `null` is rejected (422).
  - `count` integer: Number of sessions to create, 1 to 1000.

## Response `201`

Successful Response

- StatefulSessionCreateResponse
  - `data` StatefulSessionResponse[], required
    - `id` string, required
    - `proxy_id` string, required
    - `name` string, required
    - `status` 'enabled' | 'disabled', required
    - `ruleset` StatefulSessionRulesetSchema, required
      - `network_type` 'wifi' | 'mobile' | 'any', nullable: `wifi` (residential), `mobile`, or `any`. Must be enabled on the package.
      - `country` string, nullable: Two-letter country code, or `any`. Must be available on the package. Required when any of `region`, `city`, `isp`, `asn` or `zip` is set.
      - `region` string, nullable: Region code from the package location endpoints. Must belong to `country`.
      - `city` string, nullable: City code from the package location endpoints. Must belong to `region`, or to `country` when no region is set.
      - `isp` string, nullable: ISP code from the package location endpoints, valid for the chosen country, region and city.
      - `asn` string, nullable: ASN from the package location endpoints. Requires ASN targeting on your plan.
      - `zip` string, nullable: ZIP code from the package location endpoints. Requires ZIP targeting on your plan.
      - `lookalike` boolean, nullable: Whether a replacement node should resemble the previous one.
      - `rotation_trigger` string, nullable: `bind`, `on-error`, `timed:<seconds>` (minimum 10) or `request-count:<requests>`.
      - `error_handling` string, nullable: `replace`, `fail` or `retry_<attempts>`.
    - `exit_ip` string, required: IP address of the exit node the session is bound to now.
    - `network_type` string, required: Network of the bound node. The top-level geo and network fields describe where the session is bound now; `ruleset` holds what you asked for.
    - `country` string, required
    - `region` string, nullable
    - `city` string, nullable
    - `isp` string, nullable
    - `asn` string, nullable
    - `zip` string, nullable
    - `bound_since` string, date-time, nullable: When the session was bound to its current node.
    - `port` integer, nullable: Gateway port to connect to. IP allowlist packages get a dedicated port per session; credential packages share the gateway port.
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
    - `connection_string` ConnectionStringSchema
      - `uri` string, required
      - `username` string, required
      - `password` string, nullable
      - `host` string, required
      - `port` integer, required
  - `failed` integer, required
  - `reason` string, nullable

## Other responses

- `400`: Invalid name or ruleset, session limit reached, stateful sessions disabled on the package, or the package is suspended.
- `401`: Missing, invalid, or revoked API key.
- `403`: The API key does not carry the scope this endpoint requires.
- `404`: The resource does not exist, belongs to another organization, or is outside the API key's package restriction.
- `422`: Validation Error
- `429`: Another create for this package is still in progress, or the API key's rate limit was exceeded (5 requests/second per API key, 500 requests/minute per IP). Wait `Retry-After` seconds where present and retry.
- `502`: Every requested session failed with an unexpected error. Nothing was created.
- `503`: No exit node matched the ruleset for any requested session. Nothing was created. Retry after the `Retry-After` delay, or broaden the ruleset.

---

[API](https://skmtc.dev/soax/apis/soax-api.md) - [All operations](https://skmtc.dev/soax/apis/soax-api/llms.txt) - [OpenAPI document](https://skmtc.dev/soax/apis/soax-api/revisions/2abdaa934277?raw)
