API & MCP

Read StockTipRatings research from your own code, or hand it to an AI agent. Ten read-only endpoints and five MCP tools over the same data the site runs on.

What the API is

A read-only HTTP API over StockTipRatings research: stocks and their analyst consensus, individual broker calls, analyst track records scored against what the stock actually did, semantic search over research commentary, and ranked lists.

It is versioned and frozen. Everything lives under https://stocktipratings.com/api/v1, answers JSON in snake_case, and never exposes your account data — a leaked key costs you quota, not your watchlist.

The OpenAPI 3.1 spec is the authoritative contract and needs no key to read.

Get a key

Create a key on your account page. It is shown once, at creation. Keys are part of the Ultra plan — see pricing.

Send it as a bearer token. Revoking a key stops it working within a minute.

Authorization: Bearer str_live_9fK2mQ7xR4tL8vB1nD6sW3zA5cE0gH2j

Quickstart

Check the key and see what your plan allows:

curl -H "Authorization: Bearer $STR_API_KEY" \
  https://stocktipratings.com/api/v1/me

Find a stock. Search takes a name, a ticker symbol or a Bursa number, and gives you back the code the rest of the API is addressed by:

curl -G -H "Authorization: Bearer $STR_API_KEY" \
  --data-urlencode "q=maybank" \
  https://stocktipratings.com/api/v1/stocks
# -> "code": "1155.KL", "symbol": "MAYBANK", "name": "MALAYAN BANKING BERHAD"

Then that stock in full — consensus, distribution and recent calls:

curl -H "Authorization: Bearer $STR_API_KEY" \
  https://stocktipratings.com/api/v1/stocks/1155.KL

Search the research semantically:

curl -G -H "Authorization: Bearer $STR_API_KEY" \
  --data-urlencode "q=banks with improving net interest margin" \
  https://stocktipratings.com/api/v1/news

The day's top-rated analyst calls:

curl -H "Authorization: Bearer $STR_API_KEY" \
  "https://stocktipratings.com/api/v1/rankings?type=top_calls&limit=10"

Endpoints

EndpointReturnsParameters
GET /meThe key's plan and its rate limit
GET /stocksList or search stocksq, sector, sort, order, page, limit
GET /stocks/{code}One stock: consensus, distribution, recent callsperiod
GET /stocks/{code}/callsCalls on one stockperiod, page, limit
GET /callsCalls across the marketanalyst_id, broker, date, period, rated, page, limit
GET /analystsList or search analystsq, broker, sector, sort, order, page, limit
GET /analysts/{id}One analyst: profile and track recordperiod
GET /newsSemantic search over broker researchq, stock, analyst_id, published_from, published_to, limit
GET /rankingsSeven ranked lists of calls and stockstype, limit, sector
GET /sectors/{name}One sector and its AI summary

List endpoints take page and limit and answer {data, page: {size, number, total_results, total_pages, has_next}}. Stocks are addressed by code — the Bursa number plus .KL, as in 1155.KL — which is not the ticker symbol; that is the symbol field. Codes are case-sensitive and the suffix is required. Analysts are addressed by an opaque id from /analysts.

Invalid parameters are rejected, never quietly adjusted: a limit over the cap is a 400, not a clamp, so a request for 1000 results never looks like a complete answer of 100.

MCP

An MCP server exposes five tools over the same API: search_stocks, get_stock_analysis, get_analyst_track_record, search_news and get_rankings. It holds no key of its own — your key travels on the request and is verified by the API, exactly as with curl.

Streamable HTTP, for clients that support remote MCP servers:

https://mcp.stocktipratings.com

Claude Desktop, using the remote server:

{
  "mcpServers": {
    "stocktipratings": {
      "url": "https://mcp.stocktipratings.com",
      "headers": {
        "Authorization": "Bearer str_live_…"
      }
    }
  }
}

Or run the binary locally over stdio, with the key in STR_API_KEY:

{
  "mcpServers": {
    "stocktipratings": {
      "command": "/usr/local/bin/str-mcp",
      "env": { "STR_API_KEY": "str_live_…" }
    }
  }
}

Listing the tools needs no key, so an agent can always see what is available and tell you a subscription would answer your question.

Errors

Every error is the same envelope. The hint is written for an agent to act on.

{
  "error": {
    "code": "subscription_required",
    "message": "This API key belongs to an account without an active subscription.",
    "hint": "Subscribe at https://stocktipratings.com/pricing, then retry."
  }
}
StatusCodeMeaning
400invalid_requestA parameter is missing, malformed, over a cap, or combined with one it excludes.
401invalid_keyThe key is missing, malformed, revoked or expired.
402subscription_requiredThe key is valid but the account is not on the Ultra plan.
404not_foundNo resource with that identifier.
429rate_limitedOver the plan quota. Retry-After says how long to wait.
500internal_errorSomething failed on our side. Retry with backoff.

A lapsed subscription is 402, not 401, so you never go hunting for a bad key when the problem is billing.

Rate limits

A key is capped at 300 requests per minute. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 adds Retry-After. Read them and back off.

One MCP tool call is not one API request. get_analyst_track_record costs up to three and get_stock_analysis up to two, so a key is roughly 100 track-record lookups a minute rather than 300.

/news is metered by a second, tighter limit of its own, because each search embeds your query. That limit is not reflected in the X-RateLimit-* headers.

The spec

Field-level detail for every response lives in the spec, and it is tested against the router so it cannot rot.

Open the OpenAPI spec