πŸ’‘API

The API is currently in beta, which means that breaking changes may be introduced

1. Overview

The WebSocket API provides real-time updates for various trading account data, including account information, historical activity, and open positions. Clients can subscribe to one or more accounts and automatically receive updates as new data becomes available.

The API uses the STOMP (Simple Text Oriented Messaging Protocol) over a standard WebSocket connection. Any STOMP-compliant client library that supports WebSockets can be used, such as @stomp/stompjs in JavaScript or Node.js.

This API sends the complete dataset (history) from the last 24 hours with each update, and all DTOs are complete - no deltas are sent. This ensures that no information is lost, even in the event of a brief network interruption.

A single WebSocket connection is sufficient to receive data for all accounts. If new accounts are added, their data will be automatically included in the same connection without the need to reconnect or resubscribe.


2. Connection & Authentication

  • Endpoint: wss://api.metacopier.io/ws/api/v1

  • Authentication:

    • Each client must provide an api-key in the STOMP CONNECT headers.

    • Example STOMP connect header:

      "api-key": "YOUR_API_KEY"
    • If the api-key is missing or invalid, the connection will be rejected.


3. Subscribe Flow

After a successful STOMP CONNECT:

  1. SUBSCRIBE to a private queue destination such as:

    • This tells the server: β€œSend updates for my session to me at this address.”

  2. SEND a JSON body to "/app/subscribe" that indicates which accounts you want:

    • If you send an empty list, it means β€œsubscribe me to all accounts that my api-key can access.”

    • If you send a non-empty list (["uuid1", "uuid2"]), you only receive updates for those specific accounts.

Example Subscription Request

(Empty array => all accounts)

STOMP Frame


4. Messages & Destinations

  • Receiving Updates:

    • You will receive messages on your private user queue (e.g. "/user/queue/accounts/changes").

    • The server sends a copy of each relevant update (based on your subscription) to only your session.

  • Message Types:

    1. UpdateAccountInformationDTO

    2. UpdateHistoryDTO (contains a list of PositionDTO)

    3. UpdateOpenPositionsDTO (contains a list of PositionDTO)

(See REST API for DTO format REST API)


5. Data Format (DTOs)

The server wraps each outgoing message in a MessageWrapper object with two fields:

  1. type – This is the simple name of the DTO class. For example:

    • "UpdateAccountInformationDTO"

    • "UpdateOpenPositionsDTO"

    • "UpdateHistoryDTO"

  2. data – The actual DTO (serialized as JSON).

Example JSON Messages

  1. UpdateAccountInformationDTO

  2. UpdateHistoryDTO (history positions only for the last 24h)

  3. UpdateOpenPositionsDTO

Identifying the DTO

Since "type" is now the class simple name, you can simply check:

  • "UpdateAccountInformationDTO" => The "data" field is an UpdateAccountInformationDTO

  • "UpdateHistoryDTO" => The "data" field is an UpdateHistoryDTO

  • "UpdateOpenPositionsDTO" => The "data" field is an UpdateOpenPositionsDTO

For example (in JavaScript/Node):

This ensures you always know which DTO you’re handling without guessing based on field names.


6. Example Client Code

  • Node.js

  • Pyhton

  • Java - Springboot

  • C# (.NET)

  • Javascript - Browser

  • Typescript - Angular

Node.js

Here is a simplified Node.js example using @stomp/stompjs and ws:

  1. brokerURL: Points to the WebSocket/STOMP endpoint.

  2. connectHeaders: Replace 'REPLACE_WITH_YOUR_API_KEY' with your own API key.

  3. subscribe: We subscribe to "/user/queue/accounts/changes", which is a private user queue (messages are sent only to your session).

  4. publish: We send a JSON body to "/app/subscribe" specifying which account IDs we want ([] means all).

  5. message handling: We parse the JSON body. Because the server sends a MessageWrapper with a type field, we switch on data.type to see whether it’s an UpdateAccountInformationDTO, UpdateHistoryDTO, or UpdateOpenPositionsDTO.

That’s all you need to connect, authenticate, subscribe, and receive real-time data!

Python

Here is a simplified Python example using websocket-client and stomper

Java - Springboot

C# (.NET)

Javascript - Browser

Typescript - Angular


7. Error Handling & Disconnects

  1. Invalid API Key: If your api-key is wrong or expired, the server will send a STOMP ERROR frame or close the socket. Check logs for the cause.

  2. Connection Loss: If the server or network goes down, your client might attempt to reconnect (reconnectDelay=5000 means it tries every 5 seconds).

  3. Disconnect: The client can call client.deactivate() (in @stomp/stompjs) or close the WebSocket to end the session.

  4. Server may forcibly close the connection if you exceed concurrency limits or do not have permission for certain accounts.


8. Connection Limits

  1. Global or Per-API-Key Limits: We may enforce a maximum number of concurrent WebSocket sessions per API key (or a global total). If you try to exceed these limits, the server will reject additional connections.

  2. Disconnect on Excess: If your API key opens more than the allowed sessions, the newest or oldest connection might be forcibly disconnected, or the server might send an ERROR frame.

  3. IP-Based Limits: We may also optionally limit the number of connections from a single IP address to prevent abuse.

  4. What This Means for You: If you encounter frequent disconnects or ERROR frames mentioning concurrency, verify how many clients are simultaneously connecting with your API key/IP.

  5. Contact Support: If you need higher concurrency or have special requirements, reach out to the support team.


Conclusion

This WebSocket STOMP API allows real-time account updates. Once connected (with a valid api-key), you send a subscription message specifying which account(s) you want, and you receive JSON-encoded DTOs for relevant updates.

If you have any further questions or need more details, please contact our support team. Enjoy building real-time solutions with the WebSocket API!

Last updated

Was this helpful?