API reference

Bearer-authenticated REST for Pro accounts. Versioned under /v1/.

Authentication

Issue a key from Settings under the API tab. The raw key is shown exactly once; copy it before closing the dialog. You can have up to 5 active keys per account, and revoking a key takes effect immediately.

Authorization: Bearer ss_live_<your-key>

Free-tier accounts can issue keys but cannot call the API. Upgrade to Pro.

Rate limits

100 requests per minute per key, sliding window. Exceeding the limit returns 429 RATE_LIMITED with Retry-After, X-RateLimit-Limit, and X-RateLimit-Remaining headers.

Response envelopes

Successful responses return:

{ "data": <payload>, "meta": { ... } }

Errors return:

{ "error": { "code": "STRING", "message": "human-readable" } }

Common error codes:

  • UNAUTHORIZED (401): missing or malformed bearer
  • INVALID_KEY (401): key not found or revoked
  • FORBIDDEN (403): non-Pro tier
  • NOT_FOUND (404): resource does not exist or is not yours
  • VALIDATION_ERROR (400): bad request body
  • RATE_LIMITED (429): over the per-key limit
  • STABLECOIN (400): analysis attempted on a pegged asset
  • DB_ERROR (500): backend persistence failure

Endpoints

Eleven routes across analysis, positions, alerts, portfolio, and market data. Every route requires a Pro key.

MethodPathTierDescription
POST/api/v1/analysisProRun a new analysis. Supported types: exit_plan, health_check, market_brief. Returns 201 with the persisted analysis, also retrievable via the GET route.
GET/api/v1/analysis/:idProFetch a previously stored analysis. Scoped to your own analyses.
GET/api/v1/positionsProList your positions ordered newest first.
POST/api/v1/positionsProCreate a position.
PATCH/api/v1/positions/:idProUpdate entry_price, quantity, entry_date, or notes. Send only the fields you want to change.
DELETE/api/v1/positions/:idProHard delete. Returns 204 on success.
GET/api/v1/alertsProList your price alerts, active and historical.
POST/api/v1/alertsProCreate an active price alert.
DELETE/api/v1/alerts/:idProSoft cancel. The alert row is kept (status "cancelled") so triggered history stays intact.
GET/api/v1/portfolioProAggregate snapshot. Returns per-holding cost basis, market value, and P&L, plus a portfolio-wide summary. The priceCoverage field reports how many of your symbols had a live price (0 to 1); when below 1, totals are null rather than misleadingly partial.
GET/api/v1/market/snapshot/:symbolProThe same data the dashboard uses: live price, 7, 30, 90, and 365 day price and volume history, 30-day OHLCV candles, on-chain top-holder concentration, global market metrics, the fear and greed index, DefiLlama protocol fundamentals, and CryptoCompare social sentiment. Cached server-side; safe to poll.

Example requests

Run an analysis

curl -X POST https://www.sellsignal.app/api/v1/analysis \
  -H "Authorization: Bearer $SS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "exit_plan",
    "symbol": "BTC",
    "position": { "entryPrice": 62000, "quantity": 1.0 },
    "riskProfile": "moderate"
  }'

Create a position

curl -X POST https://www.sellsignal.app/api/v1/positions \
  -H "Authorization: Bearer $SS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "symbol": "ETH", "entry_price": 3200, "quantity": 2.5 }'

Create an alert

curl -X POST https://www.sellsignal.app/api/v1/alerts \
  -H "Authorization: Bearer $SS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "symbol": "SOL", "target_price": 250, "direction": "above" }'

Quickstart: JavaScript

const SS_KEY = process.env.SS_KEY;

const res = await fetch("https://www.sellsignal.app/api/v1/portfolio", {
  headers: { Authorization: `Bearer ${SS_KEY}` },
});
if (!res.ok) {
  const { error } = await res.json();
  throw new Error(`${error.code}: ${error.message}`);
}
const { data } = await res.json();
console.log(data.summary);

Quickstart: Python

import os, requests

SS_KEY = os.environ["SS_KEY"]

r = requests.get(
    "https://www.sellsignal.app/api/v1/portfolio",
    headers={"Authorization": f"Bearer {SS_KEY}"},
)
r.raise_for_status()
print(r.json()["data"]["summary"])

Not in v1

  • Webhooks (will be its own version)
  • OpenAPI spec / SDK generation
  • Per-key scopes (read-only vs read-write)
  • Analysis types beyond exit_plan, health_check, and market_brief. Ask if you need comparison or scenario over the API.
API Reference | SellSignal