Coins.ph Coins Pro — User Data Stream

Coins Pro — User Data Stream API (TRADING v1.0.0) — part of the Coins.ph developer platform.

OpenAPI Specification

coinsph-listenkey-openapi.json Raw ↑
{
  "openapi": "3.0.0",
  "info": {
    "title": "TRADING",
    "version": "1.0.0",
    "description": "API reference for listenKey"
  },
  "servers": [
    {
      "url": "https://api.pro.coins.ph",
      "description": "Production"
    },
    {
      "url": "https://api.9001.pl-qa.coinsxyz.me",
      "description": "Sandbox"
    }
  ],
  "x-readme": {
    "proxy-enabled": false
  },
  "tags": [
    {
      "name": "Listens",
      "description": "Manage user data stream listenKeys for WebSocket connections. A listenKey is required to establish a private WebSocket connection for receiving real-time account updates (orders, balances, positions)."
    }
  ],
  "x-tagGroups": [
    {
      "name": "TRADING",
      "tags": [
        "Listens"
      ]
    }
  ],
  "paths": {
    "/openapi/v1/userDataStream": {
      "post": {
        "tags": [
          "Listens"
        ],
        "summary": "Create a listenKey (USER_STREAM)",
        "description": "Start a new user data stream. The returned `listenKey` is used to establish a WebSocket\nconnection for receiving real-time account updates including order status changes,\nbalance updates, and position changes.\n\n**Key Notes**\n\n- The `listenKey` is valid for **60 minutes** from creation.\n- After creation, connect to: `wss://stream.coins.ph/openapi/ws/<listenKey>`\n- A single WebSocket connection is valid for a maximum of **24 hours**.\n- Use the keepalive endpoint (PUT) every 30 minutes to maintain the stream.\n- No request body or query parameters are required — only the API key header.\n\n**Stream Connection**\n\nAfter obtaining a `listenKey`, connect via WebSocket:\n```\nwss://stream.coins.ph/openapi/ws/<listenKey>\n```\n\n**Stream Events**\n\nOnce connected, you will receive real-time events:\n- `outboundAccountPosition` — Account balance changes\n- `balanceUpdate` — Non-trading fund activities (deposits, withdrawals, transfers)\n- `executionReport` — Order status updates\n\n---\n\n## Additional Info\n\n**Rate Limit** [📖 Learn More](https://api.docs.coins.ph/reference/general#api-limit-introduction)\n\nWeight: 1\n\n**Use Cases** [🧩 SDK](https://api.docs.coins.ph/reference/general#sdk)\n\n- **Real-Time Order Tracking** — Receive instant notifications when orders are filled, cancelled, or rejected\n- **Balance Monitoring** — Get immediate updates on deposits, withdrawals, and trade settlements\n- **Trading Bot Integration** — Feed live account data into automated trading strategies\n\n**Best Practices**\n\n- Create a new `listenKey` at application startup and maintain it with keepalive requests every 30 minutes\n- Implement reconnection logic that creates a new `listenKey` if the WebSocket disconnects\n- Close the `listenKey` during graceful application shutdown to release server resources\n",
        "operationId": "create_listen_key",
        "parameters": [
          {
            "in": "header",
            "name": "X-COINS-APIKEY",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "API key for authentication."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Create listenKey",
            "source": "curl -X POST 'https://api.pro.coins.ph/openapi/v1/userDataStream' \\\n-H 'X-COINS-APIKEY: <your api key>'\n"
          }
        ],
        "responses": {
          "200": {
            "description": "listenKey created successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "listenKey": {
                      "type": "string",
                      "description": "The key used to establish a WebSocket connection for user data stream updates. Valid for 60 minutes.",
                      "example": "iA9LWJjuMwKWYP4QQPw34GRmBgz3x5AephXSuqcDef1RnzoBVhEcEG63Co5lSg"
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "listenKey created",
                    "value": {
                      "listenKey": "iA9LWJjuMwKWYP4QQPw34GRmBgz3x5AephXSuqcDef1RnzoBVhEcEG63Co5lSg"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "API error response. The `code` field contains the internal API error code (not an HTTP status code).\n\n| Code | Description |\n|---|---|\n| -1022 | Signature for this request is not valid |\n| -2015 | Invalid API-key, IP, or permissions for action |\n\nFor the full list of error codes, see [Error Codes](https://api.docs.coins.ph/reference/error-codes).\n"
          }
        }
      },
      "put": {
        "tags": [
          "Listens"
        ],
        "summary": "Ping / Keep-alive a listenKey (USER_STREAM)",
        "description": "Keep a user data stream alive to prevent timeout. User data streams automatically close\nafter **60 minutes** of inactivity. A keepalive request extends the `listenKey` validity\nby another 60 minutes from the time the request is received.\n\n**Key Notes**\n\n- Each successful keepalive resets the 60-minute expiration timer.\n- The 24-hour maximum WebSocket connection limit still applies regardless of keepalives.\n- Returns an empty object `{}` on success.\n- Returns error code `-1125` if the `listenKey` does not exist or has already expired.\n\n**Keepalive Strategy**\n\n- Send keepalive requests every **30 minutes** to maintain a safety margin before the 60-minute expiration.\n- If a keepalive fails, create a new `listenKey` and re-establish the WebSocket connection.\n\n---\n\n## Additional Info\n\n**Rate Limit** [📖 Learn More](https://api.docs.coins.ph/reference/general#api-limit-introduction)\n\nWeight: 1\n\n**Use Cases** [🧩 SDK](https://api.docs.coins.ph/reference/general#sdk)\n\n- **Stream Keepalive** — Send periodic keepalive requests to prevent the listenKey from expiring during a long-running session\n- **Health Check** — Verify that a `listenKey` is still valid before relying on the stream\n\n**Best Practices**\n\n- Schedule keepalive requests at fixed intervals (every 30 minutes) using a timer or cron job\n- Implement error handling: if keepalive returns `-1125`, the stream has expired — create a new `listenKey`\n- Log keepalive failures for monitoring and alerting purposes\n",
        "operationId": "keepalive_listen_key",
        "parameters": [
          {
            "in": "header",
            "name": "X-COINS-APIKEY",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "API key for authentication."
          },
          {
            "in": "query",
            "name": "listenKey",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The listenKey to keep alive.",
            "example": "iA9LWJjuMwKWYP4QQPw34GRmBgz3x5AephXSuqcDef1RnzoBVhEcEG63Co5lSg"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Keep-alive listenKey",
            "source": "curl -X PUT 'https://api.pro.coins.ph/openapi/v1/userDataStream?listenKey=iA9LWJjuMwKWYP4QQPw34GRmBgz3x5AephXSuqcDef1RnzoBVhEcEG63Co5lSg' \\\n-H 'X-COINS-APIKEY: <your api key>'\n"
          }
        ],
        "responses": {
          "200": {
            "description": "listenKey keepalive successful. Validity extended by 60 minutes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "success": {
                    "summary": "Keepalive successful",
                    "value": {}
                  }
                }
              }
            }
          },
          "default": {
            "description": "API error response. The `code` field contains the internal API error code (not an HTTP status code).\n\n| Code | Description |\n|---|---|\n| -1125 | This listenKey does not exist |\n| -2015 | Invalid API-key, IP, or permissions for action |\n\nFor the full list of error codes, see [Error Codes](https://api.docs.coins.ph/reference/error-codes).\n"
          }
        }
      },
      "delete": {
        "tags": [
          "Listens"
        ],
        "summary": "Close a listenKey (USER_STREAM)",
        "description": "Explicitly close a user data stream. Once closed, the `listenKey` becomes invalid and\nthe associated WebSocket connection is immediately disconnected. A closed `listenKey`\n**cannot be reused** — you must create a new one.\n\n**Key Notes**\n\n- The WebSocket connection associated with this `listenKey` is immediately terminated.\n- Returns an empty object `{}` on success.\n- Returns error code `-1125` if the `listenKey` does not exist or has already been closed.\n- A closed `listenKey` cannot be revived — use the Create endpoint to generate a new one.\n\n---\n\n## Additional Info\n\n**Rate Limit** [📖 Learn More](https://api.docs.coins.ph/reference/general#api-limit-introduction)\n\nWeight: 1\n\n**Use Cases** [🧩 SDK](https://api.docs.coins.ph/reference/general#sdk)\n\n- **Graceful Shutdown** — Close the listenKey explicitly on exit to release server-side resources immediately rather than waiting for the 60-minute timeout\n- **Stream Reset** — Terminate and recreate a stream if it enters an inconsistent state\n- **Security** — Invalidate a `listenKey` immediately if the associated API key is compromised\n\n**Best Practices**\n\n- Always close listenKeys during application shutdown to release server-side resources\n- Implement a shutdown hook that calls this endpoint before process termination\n- After closing, clean up local references to the old `listenKey` and WebSocket connection\n",
        "operationId": "close_listen_key",
        "parameters": [
          {
            "in": "header",
            "name": "X-COINS-APIKEY",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "API key for authentication."
          },
          {
            "in": "query",
            "name": "listenKey",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The listenKey to close.",
            "example": "iA9LWJjuMwKWYP4QQPw34GRmBgz3x5AephXSuqcDef1RnzoBVhEcEG63Co5lSg"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Close listenKey",
            "source": "curl -X DELETE 'https://api.pro.coins.ph/openapi/v1/userDataStream?listenKey=iA9LWJjuMwKWYP4QQPw34GRmBgz3x5AephXSuqcDef1RnzoBVhEcEG63Co5lSg' \\\n-H 'X-COINS-APIKEY: <your api key>'\n"
          }
        ],
        "responses": {
          "200": {
            "description": "listenKey closed successfully. The associated WebSocket connection is terminated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "success": {
                    "summary": "listenKey closed",
                    "value": {}
                  }
                }
              }
            }
          },
          "default": {
            "description": "API error response. The `code` field contains the internal API error code (not an HTTP status code).\n\n| Code | Description |\n|---|---|\n| -1125 | This listenKey does not exist |\n| -2015 | Invalid API-key, IP, or permissions for action |\n\nFor the full list of error codes, see [Error Codes](https://api.docs.coins.ph/reference/error-codes).\n"
          }
        }
      }
    }
  }
}