# Open WebSocket connection

**This is a WebSocket endpoint, not a regular HTTP GET.** A plain `GET` against this path returns `404`. The client must perform the WebSocket opening handshake (`Upgrade: websocket`, `Connection: Upgrade`, `Sec-WebSocket-Version: 13`, `Sec-WebSocket-Key`). On success the server responds with `101 Switching Protocols` and the connection is upgraded.
Use this endpoint to receive live updates (for example on orders, transactions, or journeys) without polling the REST API.
Use the `wss://` scheme (TLS is required). The full URL is `wss://{host}/v2/partner/client/{clientId}/subscribe` — for example `wss://api.sandbox.fondo.se/...` in sandbox.
### Authentication
Authenticate the upgrade with the same OAuth2 bearer token used for REST requests, sent as the `Authorization: Bearer <token>` header. Browsers cannot set this header on the WebSocket handshake — partners should connect from a backend.
### Events
Once connected, the server pushes JSON-encoded events. Every event has an `eventType`; events that carry data also have an `eventId` and a `payload`:
- `.create` — `payload.current` is the newly created object.
- `.update` — `payload.current` is the new state, `payload.previous` is the prior state.
- `.delete` — `payload.previous` is the removed object.
- `hello` — sent once when the connection opens. Includes an `instanceId` identifying the server instance handling this connection; a different value on reconnect means you've been routed to a different instance.
- `heartbeat` — sent at regular intervals to keep the connection alive.
- `server_closing` — sent shortly before the server initiates a graceful close (for example during a deploy), typically ~2 seconds ahead. Use this signal to open a parallel connection and switch over before the close. Not emitted for unplanned disconnects or the load balancer's hourly connection cap.

### `eventId` and deduplication
Every data event (`.create`, `.update`, `.delete`) carries an `eventId` — an opaque UUID string that is unique per WebSocket message and deterministic across server instances. Use it to deduplicate when running parallel connections during reconnect: the same logical event delivered on both connections shares the same `eventId`, even when the connections are routed to different server instances. `eventId` is not set on `hello`, `heartbeat`, or `server_closing`, which are per-connection control signals.
### Connection lifetime
The upstream load balancer enforces a maximum lifetime of approximately one hour per connection. Expect a clean close at roughly `connectTime + 3600s` and reconnect on your side. The hourly cap has no heads-up — `server_closing` is only emitted for planned server shutdowns (for example deploys), not for the LB timer. To avoid missing events on the cap, open a parallel connection shortly before the hour expires, deduplicate using `eventId`, then close the original.
See the [Real-Time Events guide](/guides/api-guide/subscriptions) for the event-type catalogue, code samples, and reconnection guidance.

Endpoint: GET /v2/partner/client/{clientId}/subscribe
Version: 2.0.0
Security: oAuth

## Description:

  - `Authentication` ()
    Authenticate the upgrade with the same OAuth2 bearer token used for REST requests, sent as the Authorization: Bearer <token> header. Browsers cannot set this header on the WebSocket handshake — partners should connect from a backend.

  - `Events` ()
    Once connected, the server pushes JSON-encoded events. Every event has an eventType; events that carry data also have an eventId and a payload: .create — payload.current is the newly created object..update — payload.current is the new state, payload.previous is the prior state..delete — payload.previous is the removed object.hello — sent once when the connection opens. Includes an instanceId identifying the server instance handling this connection; a different value on reconnect means you've been routed to a different instance.heartbeat — sent at regular intervals to keep the connection alive.server_closing — sent shortly before the server initiates a graceful close (for example during a deploy), typically ~2 seconds ahead. Use this signal to open a parallel connection and switch over before the close. Not emitted for unplanned disconnects or the load balancer's hourly connection cap.

  - `eventId and deduplication` ()
    Every data event (.create, .update, .delete) carries an eventId — an opaque UUID string that is unique per WebSocket message and deterministic across server instances. Use it to deduplicate when running parallel connections during reconnect: the same logical event delivered on both connections shares the same eventId, even when the connections are routed to different server instances. eventId is not set on hello, heartbeat, or server_closing, which are per-connection control signals.

  - `Connection lifetime` ()
    The upstream load balancer enforces a maximum lifetime of approximately one hour per connection. Expect a clean close at roughly connectTime + 3600s and reconnect on your side. The hourly cap has no heads-up — server_closing is only emitted for planned server shutdowns (for example deploys), not for the LB timer. To avoid missing events on the cap, open a parallel connection shortly before the hour expires, deduplicate using eventId, then close the original. See the Real-Time Events guide for the event-type catalogue, code samples, and reconnection guidance.

## Security:

  - `oAuth` (unknown)
    oauth2

## Path parameters:

  - `clientId` (any, required)
    The ID of requested client.

## Response 101:

  - `101` (unknown)
    WebSocket handshake accepted. The connection is upgraded and the server begins streaming JSON-encoded events. The schema below describes the **frame payload** sent over the established WebSocket — not an HTTP response body.

## Response 101 fields (application/json):

  - `eventType` (string)
    Sent by the server when a connection is established
    Enum: "hello"

  - `instanceId` (string)
    Identifier for the server instance handling this connection. A different value on reconnect means the partner has been routed to a different instance.

  - `eventType` (string)
    Heartbeat to keep connection alive
    Enum: "heartbeat"

  - `eventType` (string)
    Heads-up that the server will close this connection shortly (typically ~2 seconds ahead), for example during a deploy. Open a parallel WebSocket connection immediately and switch over before the close arrives. Not emitted for unplanned disconnects (crashes, network faults) or the load balancer's hourly connection cap.
    Enum: "server_closing"

  - `eventType` (string)
    Account created
    Enum: "account.create"

  - `eventId` (string)
    Opaque UUID identifier unique per WebSocket message, deterministic across server instances. Use for deduplication when running overlapping connections during reconnect.

  - `payload` (object)

  - `payload.current` (object)

  - `payload.current.id` (string)
    ID (UUID) of object
    Example: 49ad7378-121c-4a53-9894-dfd14a7b4877

  - `payload.current.sortedId` (string)
    ULID (Universally Unique Lexicographically Sortable Identifier)
    Example: 01ARZ3NDEKTSV4RRFFQ69G5FAV

  - `payload.current.ref` (string)
    ref is a unique account number, based on
epoch, length and Luhn. OCR length digit compliant.
    Example: 160367146695159

  - `payload.current.name` (string, required)
    Name of account
    Example: Spar

  - `payload.current.accountType` (string, required)
    - `isk` — ISK, investeringssparkonto
- `depot` — Depot, fonddepå
- `insurance` — Endowment insurance, kapitalförsäkring. Requires the user to sign separately with the insurance provider.
    Enum: "isk", "depot", "insurance"

  - `payload.current.status` (string)
    - `pending` — Account created, waiting for approval
- `active` — Account is open and operational
- `rejected` — Account application was rejected
- `confirm` — Account is awaiting confirmation from the end customer
- `closing` — Account is being closed; new orders, payments and withdrawals are not accepted
    Enum: "pending", "active", "rejected", "confirm", "closing"

  - `payload.current.serviceType` (string, required)
    - `portfolioManagement` — Portfolio management
- `investmentAdvise` — Investment advice
- `executionOnly` — Execution only
    Enum: "portfolioManagement", "investmentAdvise", "executionOnly"

  - `payload.current.owner` (any)

  - `payload.current.owner.ownerType` (string, required)
    Enum: "natural_person"

  - `payload.current.owner.firstName` (string, required)
    First name of account holder
    Example: Ben

  - `payload.current.owner.lastName` (string, required)
    Last name of account holder
    Example: Rangel

  - `payload.current.owner.fullName` (string, required)
    Full name of account holder
    Example: Ben Rangel

  - `payload.current.owner.ssn` (string, required)
    Example: 197001010003

  - `payload.current.owner.name` (string, required)
    Legal name of entity
    Example: Acme Corp AB

  - `payload.current.owner.crn` (string, required)
    Example: 5011121421

  - `payload.current.owner.type` (string)
    Type of legal entity
    Example: aktiebolag

  - `payload.current.owner.registrationCountry` (string | null)
    Country of registration (ISO 3166-1 alpha-2)
    Example: SE

  - `payload.current.owner.countriesOfTaxation` (array | null)
    Countries where the entity is tax resident
    Example: ["SE"]

  - `payload.current.owner.address` (object | null)
    Registered address

  - `payload.current.owner.address.streetAddress` (string)

  - `payload.current.owner.address.zipCode` (string)

  - `payload.current.owner.address.city` (string)

  - `payload.current.owner.address.country` (string)

  - `payload.current.owner.contactPerson` (object | null)
    Primary contact person for the entity

  - `payload.current.owner.contactPerson.name` (string)

  - `payload.current.owner.contactPerson.phone` (string)

  - `payload.current.owner.contactPerson.email` (string)

  - `payload.current.owner.signatoryGroups` (array)
    Signatory group combinations for the legal entity

  - `payload.current.owner.signatoryGroups.name` (string)
    Name of signatory

  - `payload.current.owner.signatoryGroups.ssn` (string)
    Social security number of signatory

  - `payload.current.owner.signatoryGroups.email` (string | null)
    Email of signatory

  - `payload.current.balance` (number)
    Snapshot of cash amount on account
    Example: 100

  - `payload.current.amounts` (object)
    Amounts on account

  - `payload.current.amounts.deposited` (number)
    Amount deposited to account
    Example: 123.45

  - `payload.current.amounts.withdrawn` (number)
    Amount withdrawn from account
    Example: 123.45

  - `payload.current.positions` (array)
    List of positions held

  - `payload.current.positions.instrument` (string)
    Instrument identifier

  - `payload.current.positions.units` (number)
    Number of units, including unsettled.

  - `payload.current.positions.unitsSettled` (number)
    Number of units settled

  - `payload.current.positions.value` (number | null)
    The total value of the position (units * closePrice)

  - `payload.current.positions.closePrice` (number | null)
    Last published NAV (closing price) for the fund

  - `payload.current.positions.gav` (number)
    Average acquisition value (Genomsnittligt Anskaffningsvärde)

  - `payload.current.category` (string)
    MiFID II investor classification.
- `pro` — Professional investor (MiFID II)
- `retail` — Retail investor, protected by consumer protection regulations (MiFID II)
    Enum: "pro", "retail"

  - `payload.current.deleted` (boolean, required)
    Is account deleted?

  - `payload.current.clientId` (string, required)
    Example: 49ad7378-121c-4a53-9894-dfd14a7b4877

  - `payload.current.bankAccounts` (array)

  - `payload.current.bankAccounts.iban` (string, required)
    IBAN (ISO 13616, International Bank Account Number)
    Example: SE7280000810340009783242

  - `payload.current.bankAccounts.bban` (string)
    Local bank account number
    Example: 666 666 666

  - `payload.current.bankAccounts.bank` (string, required)
    Bank name
    Example: Buy n' Large

  - `payload.current.bankAccounts.name` (string | null, required)
    Name of account
    Example: Lönekonto

  - `payload.current.bankAccounts.createdDate` (string)
    Date when acocunt was created
    Example: 2018-12-13T23:59:00.001Z

  - `payload.current.bankAccounts.modifiedDate` (string)
    Date when last modified
    Example: 2018-12-13T23:59:00.001Z

  - `payload.current.bankAccounts.deletedDate` (string)
    Date when and if deleted
    Example: 2018-12-13T23:59:00.001Z

  - `payload.current.bankAccounts.validated` (boolean)
    Whether the bank account is validated by account check service.
Required for withdrawals
    Example: true

  - `payload.current.bankAccounts.mandateStatus` (string)
    Status of the autogiro mandate for this account
    Enum: "missing", "invalid", "pending", "active"

  - `payload.current.currency` (string, required)
    Three letter ISO currency code
    Example: SEK

  - `payload.current.createdDate` (string)
    Date when acocunt was created
    Example: 2018-12-13T23:59:00.001Z

  - `payload.current.modifiedDate` (string)
    Date when last modified
    Example: 2018-12-13T23:59:00.001Z

  - `payload.current.deletedDate` (string)
    Date when flagged as deleted
    Example: 2018-12-13T23:59:00.001Z

  - `eventType` (string)
    Account updated
    Enum: "account.update"

  - `eventType` (string)
    Account deleted
    Enum: "account.delete"

  - `eventType` (string)
    client updated
    Enum: "client.update"

  - `eventType` (string)
    client deleted
    Enum: "client.delete"

  - `eventType` (string)
    Cash transaction created
    Enum: "cashTransaction.create"

  - `eventType` (string)
    Cash transaction updated
    Enum: "cashTransaction.update"

  - `eventType` (string)
    Cash transaction deleted
    Enum: "cashTransaction.delete"

  - `eventType` (string)
    Fund transaction created
    Enum: "fundTransaction.create"

  - `eventType` (string)
    Fund transaction updated
    Enum: "fundTransaction.update"

  - `eventType` (string)
    Fund transaction deleted
    Enum: "fundTransaction.delete"

  - `eventType` (string)
    order created
    Enum: "order.create"

  - `eventType` (string)
    order updated
    Enum: "order.update"

  - `eventType` (string)
    order canceled (order status set to `canceled`)
    Enum: "order.delete"

  - `eventType` (string)
    Funds updated
    Enum: "instrument.reloaded"

  - `eventType` (string)
    journey deleted
    Enum: "journey.delete"

  - `eventType` (string)
    journey updated
    Enum: "journey.update"

## Response 400:

  - `400` (unknown)
    Invalid request or paramaters

## Response 400 fields (application/json):

  - `error` (string, required)
    Error code
    Enum: "invalid_request"

  - `error_description` (string)
    Description of error

## Response 401:

  - `401` (unknown)
    Unauthorized Error

## Response 401 fields (application/json):

  - `error` (string, required)
    Error code
    Enum: "unauthorized"

  - `error_description` (string)
    Description of error

## Response 403:

  - `403` (unknown)
    Forbidden Error (Not in scope)

## Response 403 fields (application/json):

  - `error` (string, required)
    Error code
    Enum: "forbidden"

  - `error_description` (string)
    Description of error

## Response 404:

  - `404` (unknown)
    Returned when the path is requested without WebSocket upgrade headers. To open the channel, perform a WebSocket handshake instead of a plain HTTP `GET`.

## Response 500:

  - `500` (unknown)
    Server Error

## Response 500 fields (application/json):

  - `error` (string, required)
    Error code
    Enum: "server_error"

  - `error_description` (string)
    Description of error

## Response 503:

  - `503` (unknown)
    Service Unavailable Error

## Response 503 fields (application/json):

  - `error` (string, required)
    Error code
    Enum: "service_unavailable"

  - `error_description` (string)
    Description of error

