Back to API overview

API v1 · Public demo live · Paid API live

Detection API documentation

Everything required to consume real-time and historical crypto chart-pattern detections: runnable examples, exact event semantics, filters, costs, errors, and machine-readable contracts.

The no-key public demo and authenticated production API are live. Sign in, verify a card, create a PAYG API account, and receive a production key immediately. There is no base fee or monthly minimum.

AI agent bootstrap

An agent does not need to scrape this page. Give it the three machine documents below in order. OpenAPI is authoritative if prose and schema ever disagree.

Prompt to give a coding agent

Integrate the ChartScout Detection API.

Read these URLs before writing code:
1. https://api.chartscout.io/.well-known/chartscout.json
2. https://api.chartscout.io/llms.txt
3. https://api.chartscout.io/openapi.yaml

Treat OpenAPI as authoritative. Do not invent endpoints, enum values, fields,
pagination cursors, or rate limits. Read catalogs instead of hard-coding them.
Use the anonymous demo only for a delayed sample. For production data, use a
cs_live_ Bearer key, narrow subscription filters, cursor pagination, SSE resume
with Last-Event-ID, event-id deduplication, and RFC 9457 error handling.
Never log the API key. Show the planned filters and cost implications before
starting consumption.

First request in under 60 seconds

This calls the real production data path without signup or a key. The preset is fixed, the response contains at most five events, and every event is delayed by at least 24 hours.

curl "https://api.chartscout.io/v1/demo/detections?preset=binance-5m-channel-down"

The demo has no custom filters, cursor, SSE, billing, or usage ledger. For real-time delivery, an approved private-preview account uses the authenticated workflow below.

Authentication and environments

Send the complete key in the Authorization header. Production and staging credentials are environment-bound and cannot be used interchangeably. Keys are displayed only once. Production keys are currently issued only to approved private-preview accounts.

# Production
export CHARTSCOUT_API_BASE="https://api.chartscout.io"
export CHARTSCOUT_API_KEY="cs_live_..."

# Staging uses https://api.staging.chartscout.io and cs_test_ keys
curl "$CHARTSCOUT_API_BASE/v1/exchanges"   -H "Authorization: Bearer $CHARTSCOUT_API_KEY"   -H "Accept: application/json"
Keep keys in a secret manager or environment variable. Never place them in browser code, URLs, logs, screenshots, source control, or an AI prompt.

Recommended integration workflow

  1. 1

    Discover

    Fetch exchanges, timeframes, patterns, and markets. Store stable market.id values; do not use exchange_symbol as a key.

  2. 2

    Filter

    Create one or more narrow server-side subscriptions matching the exchange, markets, timeframes, and patterns you actually consume.

  3. 3

    Consume

    After private-preview access is enabled, open the SSE stream for real-time events and persist the last processed evt_ id.

  4. 4

    Recover

    Resume SSE with Last-Event-ID and use filtered history for bounded backfill. Deduplicate every channel by event id.

  5. 5

    Control cost

    Read /v1/usage, enforce your own spend cap, and alert on billing_state.hold before delivery stops.

Create a narrow subscription

curl -X POST "$CHARTSCOUT_API_BASE/v1/subscriptions"   -H "Authorization: Bearer $CHARTSCOUT_API_KEY"   -H "Content-Type: application/json"   -H "Idempotency-Key: strategy-binance-30m-rising-wedge-v1"   --data '{
    "name": "Binance 30m rising wedges",
    "enabled": true,
    "filters": {
      "exchanges": ["binance"],
      "market_types": ["linear_future"],
      "market_ids": [],
      "timeframes": ["30m"],
      "patterns": ["rising_wedge"],
      "directions": ["bearish"],
      "maximum_synthetic_ratio": 0.05
    }
  }'

Empty arrays mean all entitled values for that dimension, not “match none.” Subscription mutations change routing state only; they never start a dedicated detector workload.

Try the API

Demo mode calls the real API without a key. Full mode sends your key directly from this tab.

curl "https://api.chartscout.io/v1/demo/detections?preset=binance-5m-channel-down"

Historical detections and filters

History requires at least one explicit timeframe and pattern. Omit market_id for an exchange-wide request, or repeat it for exact markets. Query processing is free, but a detection first delivered to your account through history is billed once at its timeframe price.

curl --get "$CHARTSCOUT_API_BASE/v1/detections"   -H "Authorization: Bearer $CHARTSCOUT_API_KEY"   --data-urlencode "exchange=binance"   --data-urlencode "timeframe=30m"   --data-urlencode "pattern=rising_wedge"   --data-urlencode "published_after=2026-08-01T00:00:00Z"   --data-urlencode "limit=100"

Stable filter values

Use codes returned by catalog endpoints. market.id is stable; symbol and exchange_symbol are display data.

Repeated parameters

Use timeframe=5m&timeframe=15m and pattern=channel_down&pattern=rising_wedge for OR within a dimension.

Time and retention

Timestamps are RFC 3339 UTC. One synchronous query spans at most 30 days and must fit inside account retention.

Bounded work

Overly broad requests fail before database work. Narrow exchange, market, timeframe, pattern, or time range.

Canonical event model

REST and SSE deliver the same CloudEvents 1.0 envelope. Persist and deduplicate by the top-level id. detection_id identifies the detection resource; the event id identifies this lifecycle event.

{
  "specversion": "1.0",
  "id": "evt_019...",
  "source": "https://api.chartscout.io/detectors/patterns",
  "type": "io.chartscout.pattern.detected.v1",
  "subject": "markets/mkt_binance_linear_future_btc_usdt/timeframes/30m",
  "time": "2026-08-03T12:30:04.120Z",
  "datacontenttype": "application/json",
  "data": {
    "detection_id": "det_019...",
    "market": {
      "id": "mkt_binance_linear_future_btc_usdt",
      "exchange": "binance",
      "market_type": "linear_future",
      "symbol": "BTC/USDT",
      "exchange_symbol": "BTC/USDT:USDT",
      "base": "BTC",
      "quote": "USDT",
      "settle": "USDT"
    },
    "timeframe": "30m",
    "pattern": {
      "code": "rising_wedge",
      "name": "Rising Wedge",
      "version": "1",
      "direction": "bearish"
    },
    "trigger_candle": {
      "open_at": "2026-08-03T12:00:00.000Z",
      "closed_at": "2026-08-03T12:30:00.000Z"
    },
    "quality": {
      "grade": "unknown",
      "synthetic_candle_count": 0,
      "synthetic_candle_ratio": 0,
      "revised_candle_count": 0,
      "warnings": []
    },
    "asset": {
      "status": "ready",
      "url": "https://api.chartscout.io/v1/detections/det_019.../chart"
    },
    "latency": {
      "detected_at": "2026-08-03T12:30:03.200Z",
      "published_at": "2026-08-03T12:30:04.120Z"
    }
  }
}
Consumers must ignore unknown additive fields. Handle detected, asset-ready, corrected, and retracted event types. A retraction is an explicit event, never a silent deletion. Do not block signal processing while an optional chart asset is pending.

Real-time SSE streaming

curl -N "$CHARTSCOUT_API_BASE/v1/stream"   -H "Authorization: Bearer $CHARTSCOUT_API_KEY"   -H "Last-Event-ID: evt_019..."
  • • Delivery is at least once. Deduplicate by the CloudEvent id.
  • • Persist the id only after your processing transaction succeeds.
  • • Reconnect with Last-Event-ID; do not put it in a query string.
  • • Comment heartbeats arrive every 15 seconds and are not events.
  • • Catch-all subscriptions are live-only; explicit market, timeframe, and pattern filters enable bounded replay.
  • • Use a server-side SSE client. Browser EventSource cannot set the Authorization header.

Cursor pagination and backfill

{
  "data": [/* newest events first */],
  "next_cursor": "eyJ..."
}

Pass next_cursor back unchanged as cursor while keeping every other filter identical. A null cursor means the listing is complete. Cursors are endpoint-specific, authenticated, opaque, and expire after 24 hours. Restart the listing after cursor_invalid or cursor_expired.

Billing semantics

There is no API base fee. Only the first delivery of a canonical detection to an account is billable. Re-reads, duplicate delivery across overlapping filters, pagination, catalog calls, empty results, usage reads, and history-query processing cost USD 0.

TimeframesCreditsPrice/event
1m1$0.01
3m2$0.02
5m3$0.03
15m5$0.05
30m8$0.08
1h, 2h, 4h12$0.12
6h, 8h, 12h, 1d20$0.20
3d, 1w, 1M30$0.30
Charge blocks are independent, not lifetime tiers: after USD 5 of new usage is settled, the next block permits USD 20 of new usage; after that settles, each later block permits USD 50 of new usage. Reaching a block atomically pauses new billable delivery. Only confirmed settlement clears the hold and resumes the same key.

Errors, retries, and idempotency

Errors use RFC 9457 Problem Details with application/problem+json. Branch on the stable code, not title or detail. Include X-Request-Id when contacting support.

{
  "type": "https://api.chartscout.io/problems/validation-failed",
  "title": "Validation failed",
  "status": 422,
  "code": "validation_failed",
  "detail": "One or more request values are invalid.",
  "request_id": "req_019...",
  "violations": [
    { "pointer": "/query/timeframe", "message": "At least one timeframe is required." }
  ]
}
authentication_required / invalid_api_keyFix or replace the Bearer key; never retry with the same invalid credential.
insufficient_scopeRequest a key with the documented operation scope.
resource_not_foundTreat missing, expired, and unentitled resources identically.
validation_failed / query_too_broadRead violations, narrow filters or time range, then send a corrected request.
cursor_invalid / cursor_expiredRestart the listing; never construct or decode cursors.
rate_limit_exceededWait Retry-After seconds and retry with jitter.
billing_threshold_reached / payment_requiredStop delivery retries until settlement clears the account hold.
service_temporarily_unavailableRetry safe reads with exponential backoff; reuse Idempotency-Key for mutations.

Send Idempotency-Key on POST, PATCH, and DELETE subscription requests. Retrying the same request with the same key is safe; reusing it for different content returns idempotency_conflict.

Rate and request limits

  • • RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset response headers are authoritative.
  • • HTTP 429 includes Retry-After. Wait that duration and add randomized jitter.
  • • Page size defaults to 100 and is capped at 500.
  • • One history request spans at most 30 days, 100 market ids, 24 timeframes, and 24 patterns.
  • • SSE connections and control-plane mutations have separate secondary buckets.
  • • Public demo: 10 requests/minute/IP, 1,000/minute globally, five events, 32 KiB response cap.

Endpoint reference

This is the navigation map. Parameter and schema details are authoritative in OpenAPI.

Discovery and demo

No authentication
GET/.well-known/chartscout.jsonMachine discovery and pricing metadata
GET/openapi.yamlAuthoritative OpenAPI 3.1 contract
GET/llms.txtAI-agent integration guide
GET/v1/demo/detectionsFixed public presets; max 5 events; 60-minute delay

Catalog

catalog:read
GET/v1/exchangesSupported exchanges and market types
GET/v1/timeframesStable timeframe codes
GET/v1/patternsEnabled pattern catalog
GET/v1/marketsAvailable and entitled markets
GET/v1/markets/{market_id}One market and its availability state

Detections

detections:read / detections:stream
GET/v1/detectionsCursor-paginated historical detections
GET/v1/detections/{detection_id}One canonical detection
GET/v1/detections/{detection_id}/chartAuthenticated private PNG
GET/v1/streamResumable real-time SSE stream

Filters and usage

subscriptions:* / usage:read
POST/v1/subscriptionsCreate a named server-side filter
GET/v1/subscriptionsList account filters
GET/v1/subscriptions/{id}Read one filter
PATCH/v1/subscriptions/{id}Atomically update one filter
DELETE/v1/subscriptions/{id}Disable one filter
GET/v1/usageUsage, accrued cost, threshold, and billing hold
GET/v1/rate-limit-statusCoarse rate-limit snapshot

Production readiness checklist

Catalog values are discovered, not hard-coded
API key is stored outside source and logs
Filters match only the markets and strategies required
CloudEvent ids are durably deduplicated
Last-Event-ID is persisted after successful processing
Cursor filters remain identical across pages
429 and 503 retries use Retry-After/backoff with jitter
Subscription mutations reuse an Idempotency-Key
Corrections and retractions are handled explicitly
Usage, spend cap, and billing hold are monitored
Unknown additive JSON fields are ignored
Staging keys and URLs are never used in production

Support: [email protected]. Include the request id, environment, endpoint, UTC time, and sanitized request parameters. Never send the API key.

We use cookies