API Documentation
Everything you need to integrate the Summevo crypto signal API: real-time WebSocket streams, REST endpoints, and HMAC-signed webhook deliveries.
Authentication
Issue an API key from /dashboard/settings. Pass it as a Bearer token on REST requests and as the token query param on WebSocket connections.
WebSocket — subscribe to signals
Open a connection and subscribe to the symbols and minimum confluence threshold you care about. Signals are pushed as soon as they’re published.
// Real-time WebSocket crypto signals
const ws = new WebSocket(
"wss://api.summevo.com/ws/signals?token=YOUR_API_KEY"
);
ws.addEventListener("open", () => {
ws.send(JSON.stringify({
op: "subscribe",
symbols: ["BTCUSDT", "ETHUSDT"],
minConfluence: 7.0,
}));
});
ws.addEventListener("message", (event) => {
const signal = JSON.parse(event.data);
// { id, symbol, signalType, confluenceScore, price, indicators, timestamp }
console.log(signal.symbol, signal.signalType, signal.confluenceScore);
});REST — fetch signals
All REST endpoints are under https://api.summevo.com/api/v1. Responses are JSON.
# Fetch the latest signals for a symbol
curl -X GET "https://api.summevo.com/api/v1/signals/latest?symbol=BTCUSDT&limit=10" \
-H "Authorization: Bearer $SUMMEVO_API_KEY" \
-H "Accept: application/json"WebSocket — reconnection
Connections may drop on network changes, idle timeouts or deploys. Reconnect with jittered exponential backoff and resume with a since cursor so you don’t miss signals.
// Reconnect with exponential backoff and a resume cursor
function connectSignals({ apiKey, onSignal }) {
let attempt = 0;
let lastEventId = null;
function open() {
const url = new URL("wss://api.summevo.com/ws/signals");
url.searchParams.set("token", apiKey);
if (lastEventId) url.searchParams.set("since", lastEventId);
const ws = new WebSocket(url);
ws.addEventListener("open", () => {
attempt = 0;
ws.send(JSON.stringify({
op: "subscribe",
symbols: ["BTCUSDT", "ETHUSDT"],
minConfluence: 7.0,
}));
});
ws.addEventListener("message", (e) => {
const signal = JSON.parse(e.data);
lastEventId = signal.id;
onSignal(signal);
});
ws.addEventListener("close", () => {
// Jittered exponential backoff, capped at 30s
const delay = Math.min(30_000, 500 * 2 ** attempt++) +
Math.random() * 250;
setTimeout(open, delay);
});
ws.addEventListener("error", () => ws.close());
}
open();
}Python example
The REST API is plain JSON — any language with an HTTP client works. Here’s a typical Python fetch:
# Python: fetch the latest signals (requests)
import os, requests
API_KEY = os.environ["SUMMEVO_API_KEY"]
resp = requests.get(
"https://api.summevo.com/api/v1/signals/latest",
params={"symbol": "BTCUSDT", "limit": 10},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=5,
)
resp.raise_for_status()
for s in resp.json():
print(s["symbol"], s["signalType"], s["confluenceScore"])Webhook payload
Outbound webhooks deliver the same signal envelope as the WebSocket stream, with headers for event type, timestamp and signature.
POST /your/endpoint HTTP/1.1
Content-Type: application/json
X-Summevo-Event: signal.strong_buy
X-Summevo-Signature: sha256=9f2a...e1
X-Summevo-Timestamp: 1716470400
{
"id": "sig-01HQX...",
"symbol": "BTCUSDT",
"signalType": "STRONG_BUY",
"confluenceScore": 8.6,
"price": 67432.10,
"indicators": {
"rsi": 32.1,
"macd": 142.3,
"bb_position": "BELOW_LOWER",
"ema_trend": "BULLISH"
},
"timestamp": "2026-05-23T08:00:00Z",
"chainHash": "b14c...f7"
}Verify the HMAC signature
Use the signing secret from your webhook’s settings to verify each delivery. Always compare with a constant-time comparison.
// HMAC-SHA256 webhook signature verification (Node.js)
import crypto from "node:crypto";
export function verifySummevoSignature(req, secret) {
const signature = req.headers["x-summevo-signature"]; // "sha256=<hex>"
const timestamp = req.headers["x-summevo-timestamp"];
const rawBody = req.rawBody; // capture before JSON parsing
// Reject if older than 5 minutes (replay protection)
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected =
"sha256=" +
crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Verify webhook signatures (Java / Spring Boot)
Equivalent verification for JVM services. Use the same WEBHOOK_SECRET issued for the endpoint.
// HMAC-SHA256 webhook verification (Java / Spring Boot)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
public final class SummevoSignature {
public static boolean verify(
String signatureHeader, // "sha256=<hex>"
String timestampHeader,
byte[] rawBody,
String secret
) throws Exception {
long ts = Long.parseLong(timestampHeader);
long now = System.currentTimeMillis() / 1000L;
if (Math.abs(now - ts) > 300) return false; // replay window
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(
secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
mac.update((ts + ".").getBytes(StandardCharsets.UTF_8));
byte[] digest = mac.doFinal(rawBody);
StringBuilder hex = new StringBuilder("sha256=");
for (byte b : digest) hex.append(String.format("%02x", b));
return MessageDigest.isEqual(
hex.toString().getBytes(StandardCharsets.UTF_8),
signatureHeader.getBytes(StandardCharsets.UTF_8));
}
}Errors
All endpoints return a consistent JSON error envelope. Treat 4xx codes as caller errors and 5xx codes as transient — retry 5xx with exponential backoff.
// Error response shape (all error codes use the same envelope)
{
"error": "rate_limited",
"message": "Too many requests — retry after 12s.",
"requestId": "req_01HQX..."
}| Status | When you see it |
|---|---|
| 401 Unauthorized | Invalid, missing or expired API key. |
| 403 Forbidden | Your plan does not include this feature. Upgrade required. |
| 404 Not Found | Resource not found — check the symbol or signal ID. |
| 422 Unprocessable Entity | Validation failed for one or more request parameters. |
| 429 Too Many Requests | Per-tier rate limit exceeded. Honor the Retry-After header. |
| 500 Internal Server Error | Unexpected server error. Safe to retry with backoff. |
Rate limits
Per-tier limits on the REST API. WebSocket connections have a separate concurrent-connection cap published in your account settings.
| Tier | Requests / minute | WebSocket | History retention |
|---|---|---|---|
| Free | 60 | — | Last 5 signals |
| Pro | 300 | Real-time | 30 days |
| Quant | 1,000 | Real-time | 365 days |