> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cryptoquant.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analyst Views

> What analysts are saying about an asset — narratives grouped by thesis and one quotable excerpt per analyst, with the bull / bear case and the post split. Public, no API key.

## What it returns

`/analyst-views?asset=&window=7d|30d` — what analysts are saying:

* **`narratives`** — viewpoints grouped by thesis with analyst counts.
* **`analyst_views`** — one quotable excerpt per analyst (the first ≤ 200 characters of one
  post, original language) with `source_url` and `profile_url`.
* The bull / bear case and the post split (`bullish_pct` / `bearish_pct` are post shares, neutral
  excluded).

`analyst_views` lists analysts with ≥ 3 directional posts on the asset in the window and a
≥ 60 % consistent side. The Analyst Consensus Index itself is on
[`/consensus`](/sentiment/consensus-index).

## Access

Public — no API key. 60 requests / minute per IP, cached 5 minutes.

## Notes

* Neither this endpoint nor [`/calls`](/sentiment/calls) carries the full post text — the original
  statement is provided under an Integration agreement only, per API key, on
  [`/consensus/breakdown`](/sentiment/consensus-breakdown) (contact
  [sales@cryptoquant.com](mailto:sales@cryptoquant.com)).
* Both carry `page_url`, `cite_as` and `data_by` — show the attribution with the numbers;
  `via=` tags the links.


## OpenAPI

````yaml openapi/sentiment.json GET /analyst-views
openapi: 3.1.0
info:
  title: Analyst Consensus API — CryptoQuant
  version: 2.2.0
  summary: >-
    What curated analysts say about crypto, stocks, indices and commodities, as
    numbers.
  description: >-
    What curated analysts on X, CryptoQuant, Seeking Alpha, TradingView and
    Substack (plus licensed sell-side ratings on equities) say about 1712 assets
    — crypto, US and KR equities, index ETFs, commodities — as numbers: the
    daily Analyst Consensus Index (−100 … +100, one series per asset), a
    per-asset consensus breakdown (bull / bear case, viewpoints grouped by
    thesis, source posts), per-analyst stance series, and each analyst's
    accuracy track record.


    **Two access levels.** Public, no key (per-IP rate limit, CDN-cached): `GET
    /assets` (the asset registry + every enum), `GET /consensus` without a key
    (the LATEST index point for any asset with the bull / bear case), `GET
    /analyst-views`, `GET /calls`, `GET /analysts/top`, `GET
    /analysts/{handle}`. Every public payload carries `page_url` (link it),
    `cite_as` and `data_by` ("Data by CryptoQuant Consensus" — show it with the
    numbers). With an API key (`X-API-Key` header or `api_key` query parameter):
    the index HISTORY (`GET /consensus` with `days`) and `GET
    /consensus/breakdown` on any plan; the per-analyst series `GET /sentiment`
    on the Premium and Enterprise plans only (`PLAN_REQUIRED` below). Keys are
    provisioned with the CryptoQuant Premium plan or an Enterprise agreement;
    there is no self-serve key endpoint on this host. **Raw source text** (the
    original post title / text) is provided under an Integration agreement only,
    per API key (`api_keys.raw_access`, never a plan): `GET
    /consensus/breakdown` sends `sources[].statement` on a cleared key and a ≤
    200-character `sources[].excerpt` + url on every other key — Premium,
    Enterprise and admin-owned keys included; the key-free `/analyst-views` and
    `/calls` excerpts follow the same rule. Integration use that needs the
    original text: contact sales@cryptoquant.com (`x-raw-source-text`). Thesis,
    narratives, index and labels are the same on every plan.


    **Conventions.** Dates: `date` = UTC calendar day `YYYY-MM-DD`; `date-time`
    = RFC 3339 / ISO 8601 with offset, UTC. Index and stance series are
    end-of-day: the current UTC day is excluded until complete, so values never
    change retroactively. No pagination anywhere: a series comes back whole
    (`days` is capped by the plan, 36,500 = everything; the full BTC history is
    ≈ 1,950 rows); lists are capped by `limit` (1–50). Sorting is fixed per
    endpoint and stated in its description. Filters combine with AND. Every
    error is the `Error` object: branch on `code`, read `message`, follow
    `docs_url`; `x-errors` lists every code with its recovery. Every operation
    carries `x-plan` (who may call it).


    **Agents.** Import this document as a ChatGPT GPT Action (Authentication:
    None for the public operations) or any OpenAPI tool loader; the Markdown
    version of these docs is `/llms.txt`; the same data is an MCP server at
    `/mcp` (Streamable HTTP, no auth). Pass `via=chatgpt|claude|…` so the links
    you show carry the right `utm_source`.


    **Freshness.** Index and stance series: end-of-day UTC. The breakdown is
    recomputed daily (English by 04:00 UTC, translations by 06:00 UTC); its
    opinion counts refresh every 4 hours. Public payloads are CDN-cached 5
    minutes (track record and assets: 1 hour).


    Human docs: https://consensus.cryptoquant.com/docs/api · how the numbers are
    made: https://consensus.cryptoquant.com/methodology · Markdown for agents:
    https://consensus.cryptoquant.com/llms.txt
  contact:
    name: CryptoQuant — API access and Enterprise data
    url: https://cryptoquant.com/get-in-touch
    email: support@cryptoquant.com
  termsOfService: https://consensus.cryptoquant.com/terms
  license:
    name: Proprietary — CryptoQuant Terms of Service
    url: https://consensus.cryptoquant.com/terms
servers:
  - url: https://consensus.cryptoquant.com/api/v1
    description: Analyst Consensus by CryptoQuant
security:
  - ApiKeyHeader: []
  - ApiKeyQuery: []
tags:
  - name: Registry
    description: Public, no API key. The assets the API covers and every enum it uses.
  - name: Consensus
    description: >-
      The Analyst Consensus Index: latest point public (no key); history and the
      per-asset breakdown with an API key.
  - name: Analyst views
    description: >-
      Public, no API key. What analysts are saying: narratives, per-analyst
      views, the newest calls.
  - name: Analyst track record
    description: >-
      Public, no API key. Who to trust: accuracy scores, ranks and badges per
      analyst.
  - name: Analyst stance
    description: Premium / Enterprise API key. One analyst's daily stance on an asset.
externalDocs:
  description: Sentiment Data documentation (the human rendering of this document)
  url: https://docs.cryptoquant.com/sentiment/overview
paths:
  /analyst-views:
    get:
      tags:
        - Analyst views
      summary: What analysts are saying about an asset (public, no API key)
      description: >-
        The asset page's Analyst Views as JSON: the bull / bear case, the
        `narratives` (viewpoints grouped by thesis, with analyst and post counts
        and a summary) and the `analyst_views` — each tracked analyst with ≥ 3
        directional posts and a ≥ 60 % consistent side in the window, with their
        thesis, ONE quotable `excerpt` (the first ≤ 200 characters of one post,
        original language — the full statement is provided under an Integration
        agreement only — per API key, contact sales@cryptoquant.com), its
        `source_url` and the analyst page (`profile_url`); most active first, at
        most 12 (`analyst_views_total` says how many qualified). Public, no API
        key. Per-IP limit 60 requests / minute (per function instance);
        CDN-cached 5 minutes (`Cache-Control: public, s-maxage=300,
        stale-while-revalidate=3600`). Backs the MCP tool get_analyst_views.
        Quote excerpts with their source link; show `data_by`.
      operationId: getAnalystViews
      parameters:
        - name: asset
          in: query
          required: false
          description: >-
            Any registered asset, case-insensitive: the symbol (`BTC`, `NVDA`,
            `005930`, `XAU`), the route key (`bitcoin`, `samsung-electronics`),
            the display name (`Bitcoin`), an alias ticker (`GLD` → XAU) or a
            retired ticker (`MATIC` → POL). The response reports the canonical
            symbol. The full list: `GET /assets`. A market aggregate
            (`crypto-market`) is not accepted. Unknown → 400 `UNKNOWN_ASSET`.
          schema:
            type: string
            default: BTC
          example: NVDA
        - name: window
          in: query
          required: false
          description: Window of the posts considered.
          schema:
            type: string
            enum:
              - 7d
              - 30d
            default: 30d
        - name: via
          in: query
          required: false
          description: >-
            The surface the agent runs on; sets `utm_source` on every link in
            the payload. Unknown values fall back to the default.
          schema:
            type: string
            enum:
              - chatgpt
              - claude
              - mcp
              - gemini
              - perplexity
              - api
            default: chatgpt
          example: claude
      responses:
        '200':
          description: Narratives and per-analyst views
          headers:
            X-RateLimit-Limit:
              description: Per-IP requests allowed per minute (60).
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests left in the current minute for this IP.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnalystViewsResponse'
              example:
                asset: BTC
                asset_name: Bitcoin
                window: 30d
                bullish_posts: 105
                bearish_posts: 62
                bullish_pct: 63
                bearish_pct: 37
                bull_case: Regulatory wins and dovish data fuel breakout
                bear_case: Macro pressure and resistance threaten deeper pullback
                narratives:
                  - theme: EXCHANGE HACK
                    headline: >-
                      Bitget drained for $387.5M as DPRK hackers spoof backend
                      approvals
                    stance: bearish
                    analyst_count: 8
                    post_count: 8
                    summary: >-
                      Bitget's breach was first reported at $351.6M and later
                      revised up by about $35M to $387.5M. Attackers used
                      spoofed transaction approvals from a compromised backend
                      rather than stolen keys. The $464M User Protection Fund
                      covers the loss but shrinks to about $76.5M.
                analyst_views:
                  - handle: CryptoMichNL
                    name: Michael van de Poppe
                    stance: bullish
                    thesis: >-
                      BTC run not over; momentum into October targets ~$90,000
                      resistance, followed by consolidation and a midterm-driven
                      correction that is a buying opportunity before a new
                      all-time high
                    excerpt: >-
                      What to expect from #Bitcoin?


                      Honestly, I don't think we're done with the run. Sure, we
                      can have some red weeks in between, but I'm eyeing the
                      $90,000 area as the coming resistance to be, after…
                    source_url: https://x.com/CryptoMichNL/status/2103900910501990879
                    source_type: tweet
                    published_at: '2026-09-26T17:34:00+00:00'
                    post_count: 14
                    consistency_pct: 100
                    profile_url: >-
                      https://consensus.cryptoquant.com/analyst/CryptoMichNL?utm_source=api&utm_medium=gpt-action&utm_campaign=analyst-views
                analyst_views_total: 14
                note: >-
                  analyst_views = analysts with ≥ 3 directional posts on the
                  asset in the window and a ≥ 60 % consistent side; excerpt =
                  the first ≤ 200 characters of one post (original language),
                  quote it with the source_url — the full statement is provided
                  under an Integration agreement only — contact
                  sales@cryptoquant.com. bullish_pct / bearish_pct are post
                  shares (neutral excluded); the Analyst Consensus Index is on
                  /api/v1/consensus.
                page_url: >-
                  https://consensus.cryptoquant.com/consensus/btc?utm_source=api&utm_medium=gpt-action&utm_campaign=analyst-views
                top_analysts_url: >-
                  https://consensus.cryptoquant.com/analysts?asset=btc&sort=accuracy&utm_source=api&utm_medium=gpt-action&utm_campaign=analyst-views
                methodology_url: >-
                  https://consensus.cryptoquant.com/methodology?utm_source=api&utm_medium=gpt-action&utm_campaign=analyst-views
                cite_as: >-
                  Data by CryptoQuant Consensus —
                  https://consensus.cryptoquant.com/consensus/btc
                data_by: Data by CryptoQuant Consensus
                as_of: '2026-10-06T07:48:25.102Z'
        '400':
          description: '`UNKNOWN_ASSET` or `INVALID_PARAMETER` (window)'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Unknown asset
                code: UNKNOWN_ASSET
                message: >-
                  "DOGE2" is not a registered asset. Use a ticker, route key or
                  name from https://consensus.cryptoquant.com/api/v1/assets
                  (symbol / key / name / aliases, case-insensitive). Market
                  aggregates are not assets.
                docs_url: https://consensus.cryptoquant.com/docs/api#errors
                param: asset
        '429':
          description: >-
            Per-IP limit on the key-free path (60 requests / minute per function
            instance). Wait `Retry-After` seconds, or use an API key for higher
            limits.
          headers:
            Retry-After:
              schema:
                type: integer
            X-RateLimit-Limit:
              schema:
                type: integer
            X-RateLimit-Remaining:
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Rate limit exceeded
                code: RATE_LIMIT_EXCEEDED
                message: >-
                  Public endpoint: per-IP limit reached. Wait 37 s
                  (Retry-After), or use an API key for higher limits.
                docs_url: https://consensus.cryptoquant.com/docs/api#errors
                retry_after: 37
        '500':
          description: '`INTERNAL_ERROR` — retry once after a few seconds.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Internal server error
                code: INTERNAL_ERROR
                message: >-
                  Something went wrong on our side. Retry once after a few
                  seconds; if it persists, report the URL to support.
                docs_url: https://consensus.cryptoquant.com/docs/api#errors
      security: []
      x-codeSamples:
        - lang: Shell
          source: >-
            curl -X GET
            "https://consensus.cryptoquant.com/api/v1/analyst-views?asset=BTC&window=30d"
        - lang: JavaScript
          source: >-
            fetch("https://consensus.cryptoquant.com/api/v1/analyst-views?asset=BTC&window=30d")
              .then(response => response.json())
              .then(data => console.log(data))
        - lang: NodeJS
          source: |-
            require('axios')
              .get("https://consensus.cryptoquant.com/api/v1/analyst-views?asset=BTC&window=30d")
              .then(response => console.log(response))
        - lang: Ruby
          source: >-
            require 'net/http'

            uri =
            URI("https://consensus.cryptoquant.com/api/v1/analyst-views?asset=BTC&window=30d")

            res = Net::HTTP.get_response(uri)

            puts res.body
        - lang: Python
          source: >-
            import requests

            url =
            "https://consensus.cryptoquant.com/api/v1/analyst-views?asset=BTC&window=30d"

            print(requests.get(url).json())
components:
  schemas:
    AnalystViewsResponse:
      type: object
      required:
        - asset
        - asset_name
        - window
        - narratives
        - analyst_views
        - analyst_views_total
        - page_url
        - cite_as
        - data_by
        - as_of
      properties:
        asset:
          type: string
        asset_name:
          type: string
        window:
          type: string
          enum:
            - 7d
            - 30d
        bullish_posts:
          type:
            - integer
            - 'null'
          minimum: 0
          description: >-
            Directional posts in the window, bullish (post share — the index is
            on /consensus).
        bearish_posts:
          type:
            - integer
            - 'null'
          minimum: 0
        bullish_pct:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 100
        bearish_pct:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 100
        bull_case:
          type:
            - string
            - 'null'
        bear_case:
          type:
            - string
            - 'null'
        narratives:
          type: array
          items:
            $ref: '#/components/schemas/AgentNarrative'
        analyst_views:
          type: array
          items:
            $ref: '#/components/schemas/AgentAnalystView'
          description: Most active first, at most 12.
        analyst_views_total:
          type: integer
          minimum: 0
          description: How many analysts qualified (the page lists them all).
        note:
          type: string
          description: What the fields mean — quote the caveat with the numbers.
        page_url:
          type: string
          format: uri
          description: >-
            The canonical page on the site for this answer, UTM-tagged for the
            calling surface (`via`). Link it in every answer.
        top_analysts_url:
          type: string
          format: uri
          description: The asset's analysts ranked by accuracy (site page).
        methodology_url:
          type: string
          format: uri
          description: How the numbers are made.
        cite_as:
          type: string
          description: >-
            Attribution line + the untagged canonical URL, e.g. "Data by
            CryptoQuant Consensus —
            https://consensus.cryptoquant.com/consensus/btc".
        data_by:
          type: string
          enum:
            - Data by CryptoQuant Consensus
          description: Show this next to the numbers.
        as_of:
          type: string
          format: date-time
          description: Generation time of the payload (UTC).
    Error:
      type: object
      description: >-
        Every non-2xx body. Branch on `code`; `error` is the legacy short reason
        kept for pre-2026-10-06 clients.
      required:
        - error
        - code
        - message
        - docs_url
      properties:
        error:
          type: string
          description: >-
            Legacy short reason ("Invalid asset", "API key required", "Rate
            limit exceeded" …), unchanged wording.
        code:
          type: string
          enum:
            - API_KEY_REQUIRED
            - INVALID_API_KEY
            - PLAN_REQUIRED
            - RAW_ACCESS_REQUIRED
            - DAILY_LIMIT_EXCEEDED
            - RATE_LIMIT_EXCEEDED
            - INVALID_PARAMETER
            - UNKNOWN_ASSET
            - ANALYST_NOT_FOUND
            - ANALYST_NOT_ELIGIBLE
            - NO_DATA
            - SERVICE_UNAVAILABLE
            - INTERNAL_ERROR
          description: >-
            Stable machine code. Status and recovery per code: see `x-errors` at
            the document root.
        message:
          type: string
          description: Human explanation, with the accepted values for a parameter error.
        docs_url:
          type: string
          format: uri
          description: >-
            Where the error is documented (/docs/api#errors, or #plans for
            PLAN_REQUIRED).
        param:
          type: string
          description: The offending query parameter (INVALID_PARAMETER, UNKNOWN_ASSET).
        required_plans:
          type: array
          items:
            type: string
            enum:
              - premium
              - enterprise
          description: Plans that may call the endpoint (PLAN_REQUIRED).
        plan:
          type: string
          description: The key's current plan label, upper-cased (PLAN_REQUIRED).
        upgrade_url:
          type: string
          format: uri
          description: Self-serve upgrade (PLAN_REQUIRED, DAILY_LIMIT_EXCEEDED).
        contact_url:
          type: string
          format: uri
          description: Enterprise / sales contact (PLAN_REQUIRED, DAILY_LIMIT_EXCEEDED).
        limit:
          type:
            - integer
            - 'null'
          description: Daily quota (DAILY_LIMIT_EXCEEDED).
        used:
          type:
            - integer
            - 'null'
          description: Requests used today (DAILY_LIMIT_EXCEEDED).
        reset:
          type: string
          description: When the quota resets ("Daily at midnight UTC").
        retry_after:
          type: integer
          minimum: 1
          description: Seconds to wait (RATE_LIMIT_EXCEEDED; also the Retry-After header).
        docs:
          type: string
          format: uri
          deprecated: true
          description: Legacy alias of docs_url on API_KEY_REQUIRED.
        upgradeUrl:
          type: string
          format: uri
          deprecated: true
          description: Legacy alias of upgrade_url on PLAN_REQUIRED.
    AgentNarrative:
      type: object
      required:
        - stance
        - analyst_count
        - post_count
      properties:
        theme:
          type:
            - string
            - 'null'
          description: Short thesis label (e.g. "ETF FLOWS").
        headline:
          type:
            - string
            - 'null'
        stance:
          type: string
          enum:
            - bullish
            - bearish
            - neutral
        analyst_count:
          type: integer
          minimum: 0
        post_count:
          type: integer
          minimum: 0
        summary:
          type:
            - string
            - 'null'
    AgentAnalystView:
      type: object
      required:
        - handle
        - stance
        - thesis
        - post_count
        - consistency_pct
        - profile_url
      properties:
        handle:
          type: string
        name:
          type:
            - string
            - 'null'
        stance:
          type: string
          enum:
            - bullish
            - bearish
        thesis:
          type: string
          description: The analyst's representative thesis in the window.
        excerpt:
          type:
            - string
            - 'null'
          maxLength: 200
          description: >-
            The first ≤ 200 characters of the representative post (sentence /
            word boundary, ellipsis when cut, original language). Quote with
            source_url; the full statement is provided under an Integration
            agreement only — per API key, contact ' + SALES_EMAIL + '.
        source_url:
          type:
            - string
            - 'null'
          format: uri
          description: The underlying post.
        source_type:
          type:
            - string
            - 'null'
          enum:
            - tweet
            - quicktake
            - research
            - news
            - seekingalpha
            - tradingview
            - substack
            - youtube
            - telegram
            - bluesky
            - null
          description: Stored source type of the post.
        published_at:
          type:
            - string
            - 'null'
          format: date-time
        post_count:
          type: integer
          minimum: 0
          description: Directional posts by the analyst on the asset in the window.
        consistency_pct:
          type: integer
          minimum: 0
          maximum: 100
          description: Share of those posts on the dominant side (≥ 60).
        profile_url:
          type: string
          format: uri
          description: The analyst page (cite this).
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        Provisioned with the CryptoQuant Premium plan or an Enterprise agreement
        (no self-serve). Keys start with `unbias_live_`.
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key
      description: Same key as a query parameter (avoid in logged URLs).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.