# Managed-Buy Flows Subscription & Events

Real-time progress and error updates for managed-account **buy** flows.

## URL


```
wss://api.sniperoo.app/managed-account-flows
```

## Subscription Method

#### `subscribe_managed_account_flows_api`

Subscribe to real-time flow updates for every managed-account buy/sell flow
belonging to your account, using your API key.

**Request:**


```javascript
{
  "apiKey": "your-api-key-here"
}
```

Updates are scoped to the user the API key belongs to — you receive events for
all flows triggered under that account.

## Managed Account Flow Events

| Event | Description |
|  --- | --- |
| `subscription_status` | Acknowledgement returned upon subscribing (delivered as the ack of the subscribe call) |
| `managed_account_flow_update` | Fires on every phase transition of a buy/sell flow, and on terminal failure |
| `please_refresh` | Sent if the subscription payload is invalid; the socket is then disconnected |
| `unsubscription_success` | Fires after `unsubscribe_managed_account_flows` |


#### Event Data Structures

**subscription_status:**

Returned as the acknowledgement of `subscribe_managed_account_flows_api`
(e.g. via `emitWithAck`):


```javascript
{
    "subscribed": true,
    "timestamp": 1778871800378
}
```

**managed_account_flow_update:**


```javascript
{
    "errorMessage": null,
    "flowType": "buy",
    "jobId": "40bd0f53-b3e4-4ccb-97aa-3981b5c46d06",
    "managedAccountBuySignalId": 54,
    "status": "SWAPPING",
    "timestamp": 1778871812052,
    "tokenAddress": "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm",
    "totalInputSolLamports": "1000000",
    "totalOutputTokenLamports": "429289",
    "userId": 12
}
```

| Field | Type | Description |
|  --- | --- | --- |
| `errorMessage` | `string | null` | Failure reason. Populated only when `status` is `FAILED`, otherwise `null`. |
| `flowType` | `"buy"` | Which flow this update belongs to. |
| `jobId` | `string | null` | Correlation/job id for the flow (same id returned by the buy endpoint). |
| `managedAccountBuySignalId` | `number` | Internal id of the flow record. Stable across the whole flow. |
| `status` | `string` | Current phase — see the status tables below. |
| `timestamp` | `number` | Unix epoch milliseconds the update was emitted. |
| `tokenAddress` | `string` | Mint address of the token being bought/sold. |
| `totalInputSolLamports` | `string | null` | Total SOL (lamports) transferred in for the buy. |
| `totalOutputTokenLamports` | `string | null` | Total token amount (lamports) received from the swap. |
| `userId` | `number` | Owner of the flow. |


**please_refresh:**


```javascript
{
    "message": string
}
```

**unsubscription_success:**


```javascript
{
    "timestamp": number
}
```

## Flow Status Lifecycle

Exactly one event is emitted per phase transition (replays and backward
transitions are de-duplicated server-side), so a successful flow yields a clean,
ordered sequence.

**Buy flow** (`flowType: "buy"`):

| Status | Meaning |
|  --- | --- |
| `TRANSFERRING_SOL` | Collecting SOL from managed wallets into the intermediary wallet |
| `SWAPPING` | Buying the token via Jupiter swap |
| `DISTRIBUTING` | Sending purchased tokens to managed wallets and opening positions |
| `COMPLETED` | Flow finished successfully |
| `FAILED` | Flow failed — see `errorMessage` |


Typical successful order:
`TRANSFERRING_SOL → SWAPPING → DISTRIBUTING → COMPLETED`

> `FAILED` is terminal and emitted exactly once, with `errorMessage` describing
the cause.


## Example Client


```javascript
const { io } = require('socket.io-client');

const API_KEY = 'your-api-key-here';
const SERVER_URL = 'wss://api.sniperoo.app';

const socket = io(`${SERVER_URL}/managed-account-flows`, {
    transports: ['websocket'],
});

socket.on('connect', async () => {
    console.log('✅ Connected');
    const status = await socket.emitWithAck('subscribe_managed_account_flows_api', {
        apiKey: API_KEY,
    });
    console.log('Subscription status:', status);
});

socket.on('managed_account_flow_update', (data) => {
    console.log(`📈 ${data.flowType} flow #${data.managedAccountBuySignalId}: ${data.status}`);
    if (data.status === 'FAILED') {
        console.log('   reason:', data.errorMessage);
    }
});

socket.on('connect_error', (err) => console.log('❌ connect_error:', err.message));
socket.on('disconnect', () => console.log('❌ Disconnected'));
```

> Note: this gateway is a pure relay — it streams updates as they happen. It does
not replay the state of flows that progressed before you subscribed. Subscribe
before (or immediately after) triggering a flow, and use the buy endpoint's
`jobId` to correlate updates.