Integrasi AI & Agent

Pelajari cara menghubungkan Large Language Model, AI Agent, dan Coding Assistant ke Index Alpha API.

Selamat datang di panduan Integrasi AI & Agent. Large Language Model (LLM) dan AI agent otonom adalah para developer baru. Index Alpha API dirancang sejak awal agar sepenuhnya ramah AI.

Baik Anda membangun AI agent kustom dengan framework seperti LangChain, menjalankan coding assistant desktop lokal seperti Cursor dan GitHub Copilot, atau mengonfigurasi ChatGPT Actions / Claude Projects kustom, kami menyediakan tools dan skema kelas satu agar integrasi berjalan mulus.

Baru: Anda sekarang dapat menghubungkan Claude Desktop, Cursor, atau klien MCP lainnya langsung ke endpoint remote kami — tanpa perlu mengatur server lokal. Lihat panduan Koneksi MCP Remote untuk detail.


1. Dokumentasi LLM Bawaan (llms.txt)

Kami mendukung standar llms.txt yang sedang berkembang, menyediakan endpoint dokumentasi yang bersih, teroptimasi konteks, dan ramah LLM. Jika Anda menginstruksikan AI agent atau tool pencarian untuk mempelajari API kami, cukup arahkan mereka ke URL berikut:


2. Spesifikasi OpenAPI 3.0 yang Dapat Disalin

Untuk mengintegrasikan Index Alpha dengan platform agentic modern seperti ChatGPT Actions, Claude Projects Custom Tools, atau framework agent (seperti CrewAI, AutoGen, dan Vercel AI SDK), salin skema OpenAPI 3.0 ini:

openapi: 3.0.3
info:
  title: Index Alpha API
  description: Premium Indonesian Stock Exchange (IDX) broker summary analytics API.
  version: 1.0.0
servers:
  - url: https://api.indexalpha.id/
paths:
  /stocks/broker-summary:
    get:
      summary: Retrieve Broker Summary
      description: Retrieve aggregated daily activity for brokers on a specific stock ticker. Records are updated every trading day at 12:00 GMT (19:00 Jakarta time). Historical data is available starting from 2025-01-01.
      parameters:
        - name: ticker
          in: query
          required: true
          description: Stock ticker symbol (e.g., BBCA, TLKM)
          schema:
            type: string
        - name: from
          in: query
          required: true
          description: Start date in YYYY-MM-DD format (2025-01-01 or later)
          schema:
            type: string
            format: date
        - name: to
          in: query
          required: true
          description: End date in YYYY-MM-DD format
          schema:
            type: string
            format: date
        - name: investor
          in: query
          required: true
          description: Type of investor to aggregate.
          schema:
            type: string
            enum: [all, f, d]
      responses:
        '200':
          description: Successful response containing broker summary data.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        code:
                          type: string
                          description: Broker code (e.g., SQ, AK, CC)
                        buy_freq:
                          type: integer
                          description: Number of buy transactions
                        buy_volume:
                          type: integer
                          description: Total share volume purchased
                        buy_value:
                          type: number
                          description: Total transaction value of purchases (in IDR)
                        sell_freq:
                          type: integer
                          description: Number of sell transactions
                        sell_volume:
                          type: integer
                          description: Total share volume sold
                        sell_value:
                          type: number
                          description: Total transaction value of sales (in IDR)
                        buy_avg:
                          type: number
                          description: Weighted average buy price
                        sell_avg:
                          type: number
                          description: Weighted average sell price
                  error:
                    type: string
                    nullable: true
        '400':
          description: Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days).
        '401':
          description: Unauthorized. Missing or invalid Bearer token.
        '403':
          description: Forbidden. Monthly or daily quota exhausted.
        '422':
          description: Validation error on the request parameters.
        '429':
          description: Too Many Requests. Rate limit exceeded.
        '500':
          description: Internal server error.
  /stocks/broker-summary/batch:
    post:
      summary: Batch Broker Summary
      description: Retrieve aggregated broker activity for multiple stock tickers in a single request.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                tickers:
                  type: array
                  items:
                    type: string
                  description: List of stock tickers (e.g., ["BBCA", "TLKM"]). Min 1, Max 50.
                from:
                  type: string
                  format: date
                  description: Start date in YYYY-MM-DD format
                to:
                  type: string
                  format: date
                  description: End date in YYYY-MM-DD format
                investor:
                  type: string
                  enum: [all, f, d]
                  description: Investor type (default all)
                market:
                  type: string
                  enum: [RG, NG, ALL]
                  description: Market segment (default RG)
              required: [tickers, from, to]
      responses:
        '200':
          description: Successful response containing broker summary data for each ticker.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        type: object
                        properties:
                          code:
                            type: string
                          buy_freq:
                            type: integer
                          buy_volume:
                            type: integer
                          buy_value:
                            type: number
                          sell_freq:
                            type: integer
                          sell_volume:
                            type: integer
                          sell_value:
                            type: number
                          buy_avg:
                            type: number
                          sell_avg:
                            type: number
                  error:
                    type: string
                    nullable: true
        '400':
          description: Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days).
        '401':
          description: Unauthorized. Missing or invalid Bearer token.
        '403':
          description: Forbidden. Monthly or daily quota exhausted.
        '422':
          description: Validation error on the request parameters.
        '429':
          description: Too Many Requests. Rate limit exceeded.
        '500':
          description: Internal server error.
  /foreign-flow:
    get:
      summary: Get Foreign Flow
      description: Returns aggregated foreign buy, sell, and net trading activity for a stock ticker over a date range. Aggregated across all foreign brokers.
      parameters:
        - name: ticker
          in: query
          required: true
          description: Stock ticker symbol (e.g., BBCA, TLKM)
          schema:
            type: string
        - name: from
          in: query
          required: true
          description: Start date in YYYY-MM-DD format
          schema:
            type: string
            format: date
        - name: to
          in: query
          required: true
          description: End date in YYYY-MM-DD format
          schema:
            type: string
            format: date
        - name: market
          in: query
          required: false
          description: Market segment (RG, NG, ALL). Default ALL.
          schema:
            type: string
            enum: [ALL, RG, NG]
      responses:
        '200':
          description: Successful response containing foreign flow data.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      foreign_buy:
                        type: integer
                        description: Total foreign buy transaction value (IDR)
                      foreign_sell:
                        type: integer
                        description: Total foreign sell transaction value (IDR)
                      net_foreign:
                        type: integer
                        description: Net foreign flow (foreign_buy - foreign_sell)
                  error:
                    type: string
                    nullable: true
        '400':
          description: Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days).
        '401':
          description: Unauthorized. Missing or invalid Bearer token.
        '403':
          description: Forbidden. Monthly or daily quota exhausted.
        '422':
          description: Validation error on the request parameters.
        '429':
          description: Too Many Requests. Rate limit exceeded.
        '500':
          description: Internal server error.
  /foreign-flow/batch:
    post:
      summary: Batch Foreign Flow
      description: Retrieve aggregated foreign flow for multiple stock tickers in a single request.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                tickers:
                  type: array
                  items:
                    type: string
                  description: List of stock tickers (e.g., ["BBCA", "TLKM"]). Min 1, Max 50.
                from:
                  type: string
                  format: date
                  description: Start date in YYYY-MM-DD format
                to:
                  type: string
                  format: date
                  description: End date in YYYY-MM-DD format
                market:
                  type: string
                  enum: [ALL, RG, NG]
                  description: Market segment (default ALL)
              required: [tickers, from, to]
      responses:
        '200':
          description: Successful response containing foreign flow data for each ticker.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    additionalProperties:
                      type: object
                      properties:
                        foreign_buy:
                          type: integer
                        foreign_sell:
                          type: integer
                        net_foreign:
                          type: integer
                  error:
                    type: string
                    nullable: true
        '400':
          description: Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days).
        '401':
          description: Unauthorized. Missing or invalid Bearer token.
        '403':
          description: Forbidden. Monthly or daily quota exhausted.
        '422':
          description: Validation error on the request parameters.
        '429':
          description: Too Many Requests. Rate limit exceeded.
        '500':
          description: Internal server error.
  /usage:
    get:
      summary: Check Usage & Limits
      description: Monitor your active monthly call usage, current remaining quota, and reset date.
      responses:
        '200':
          description: Successful response containing usage metrics.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      api_key:
                        type: string
                        description: Masked version of the active API key
                      monthly_limit:
                        type: integer
                        description: Total monthly quota allowed
                      current_usage:
                        type: integer
                        description: Number of API calls consumed this period
                      remaining:
                        type: integer
                        description: Number of API calls remaining in active quota
                      reset_date:
                        type: string
                        format: date-time
                        description: The timestamp when the quota resets
                  error:
                    type: string
                    nullable: true
        '400':
          description: Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days).
        '401':
          description: Unauthorized. Missing or invalid Bearer token.
        '403':
          description: Forbidden. Monthly or daily quota exhausted.
        '422':
          description: Validation error on the request parameters.
        '429':
          description: Too Many Requests. Rate limit exceeded.
        '500':
          description: Internal server error.
  /news:
    get:
      summary: Get Market News
      description: Fetches the latest articles from Indonesian market news RSS feeds and returns them grouped by source, newest first within each source. Articles are fetched live from the publisher feeds with a short 30s cache; a temporarily unreachable source is skipped.
      responses:
        '200':
          description: Successful response containing per-source news articles.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        type: object
                        properties:
                          source:
                            type: string
                          title:
                            type: string
                          description:
                            type: string
                          link:
                            type: string
                          image_url:
                            type: string
                          guid:
                            type: string
                            nullable: true
                          published_date:
                            type: string
                            format: date-time
                            nullable: true
                  error:
                    type: string
                    nullable: true
        '401':
          description: Unauthorized. Missing or invalid Bearer token.
        '403':
          description: Forbidden. Monthly or daily quota exhausted.
        '429':
          description: Too Many Requests. Rate limit exceeded.
        '500':
          description: Internal server error.
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
security:
  - bearerAuth: []
{
  "openapi": "3.0.3",
  "info": {
    "title": "Index Alpha API",
    "description": "Premium Indonesian Stock Exchange (IDX) broker summary analytics API.",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.indexalpha.id/"
    }
  ],
  "paths": {
    "/stocks/broker-summary": {
      "get": {
        "summary": "Retrieve Broker Summary",
        "description": "Retrieve aggregated daily activity for brokers on a specific stock ticker. Records are updated every trading day at 12:00 GMT (19:00 Jakarta time). Historical data is available starting from 2025-01-01.",
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": true,
            "description": "Stock ticker symbol (e.g., BBCA, TLKM)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Start date in YYYY-MM-DD format (2025-01-01 or later)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "End date in YYYY-MM-DD format",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "investor",
            "in": "query",
            "required": true,
            "description": "Type of investor to aggregate.",
            "schema": {
              "type": "string",
              "enum": ["all", "f", "d"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response containing broker summary data.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "description": "Broker code (e.g., SQ, AK, CC)"
                          },
                          "buy_freq": {
                            "type": "integer",
                            "description": "Number of buy transactions"
                          },
                          "buy_volume": {
                            "type": "integer",
                            "description": "Total share volume purchased"
                          },
                          "buy_value": {
                            "type": "number",
                            "description": "Total transaction value of purchases (in IDR)"
                          },
                          "sell_freq": {
                            "type": "integer",
                            "description": "Number of sell transactions"
                          },
                          "sell_volume": {
                            "type": "integer",
                            "description": "Total share volume sold"
                          },
                          "sell_value": {
                            "type": "number",
                            "description": "Total transaction value of sales (in IDR)"
                          },
                          "buy_avg": {
                            "type": "number",
                            "description": "Weighted average buy price"
                          },
                          "sell_avg": {
                            "type": "number",
                            "description": "Weighted average sell price"
                          }
                        }
                      }
                    },
                    "error": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days)." },
          "401": {
            "description": "Unauthorized. Missing or invalid Bearer token."
          },
          "403": { "description": "Forbidden. Monthly or daily quota exhausted." },
          "422": { "description": "Validation error on the request parameters." },
          "429": {
            "description": "Too Many Requests. Rate limit exceeded."
          },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/stocks/broker-summary/batch": {
      "post": {
        "summary": "Batch Broker Summary",
        "description": "Retrieve aggregated broker activity for multiple stock tickers in a single request.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tickers": {
                    "type": "array",
                    "items": { "type": "string" },
                    "description": "List of stock tickers (e.g. [\"BBCA\", \"TLKM\"]). Min 1, Max 50."
                  },
                  "from": { "type": "string", "format": "date", "description": "Start date in YYYY-MM-DD format" },
                  "to": { "type": "string", "format": "date", "description": "End date in YYYY-MM-DD format" },
                  "investor": { "type": "string", "enum": ["all", "f", "d"], "description": "Investor type (default all)" },
                  "market": { "type": "string", "enum": ["RG", "NG", "ALL"], "description": "Market segment (default RG)" }
                },
                "required": ["tickers", "from", "to"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response containing broker summary data for each ticker.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "code": { "type": "string" },
                            "buy_freq": { "type": "integer" },
                            "buy_volume": { "type": "integer" },
                            "buy_value": { "type": "number" },
                            "sell_freq": { "type": "integer" },
                            "sell_volume": { "type": "integer" },
                            "sell_value": { "type": "number" },
                            "buy_avg": { "type": "number" },
                            "sell_avg": { "type": "number" }
                          }
                        }
                      }
                    },
                    "error": { "type": "string", "nullable": true }
                  }
                }
              }
            }
          },
          "400": { "description": "Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days)." },
          "401": { "description": "Unauthorized. Missing or invalid Bearer token." },
          "403": { "description": "Forbidden. Monthly or daily quota exhausted." },
          "422": { "description": "Validation error on the request parameters." },
          "429": { "description": "Too Many Requests. Rate limit exceeded." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/foreign-flow": {
      "get": {
        "summary": "Get Foreign Flow",
        "description": "Returns aggregated foreign buy, sell, and net trading activity for a stock ticker over a date range. Aggregated across all foreign brokers.",
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": true,
            "description": "Stock ticker symbol (e.g., BBCA, TLKM)",
            "schema": { "type": "string" }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Start date in YYYY-MM-DD format",
            "schema": { "type": "string", "format": "date" }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "End date in YYYY-MM-DD format",
            "schema": { "type": "string", "format": "date" }
          },
          {
            "name": "market",
            "in": "query",
            "required": false,
            "description": "Market segment (RG, NG, ALL). Default ALL.",
            "schema": { "type": "string", "enum": ["ALL", "RG", "NG"] }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response containing foreign flow data.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "foreign_buy": { "type": "integer", "description": "Total foreign buy transaction value (IDR)" },
                        "foreign_sell": { "type": "integer", "description": "Total foreign sell transaction value (IDR)" },
                        "net_foreign": { "type": "integer", "description": "Net foreign flow (foreign_buy - foreign_sell)" }
                      }
                    },
                    "error": { "type": "string", "nullable": true }
                  }
                }
              }
            }
          },
          "400": { "description": "Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days)." },
          "401": { "description": "Unauthorized. Missing or invalid Bearer token." },
          "403": { "description": "Forbidden. Monthly or daily quota exhausted." },
          "422": { "description": "Validation error on the request parameters." },
          "429": { "description": "Too Many Requests. Rate limit exceeded." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/foreign-flow/batch": {
      "post": {
        "summary": "Batch Foreign Flow",
        "description": "Retrieve aggregated foreign flow for multiple stock tickers in a single request.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tickers": {
                    "type": "array",
                    "items": { "type": "string" },
                    "description": "List of stock tickers (e.g. [\"BBCA\", \"TLKM\"]). Min 1, Max 50."
                  },
                  "from": { "type": "string", "format": "date", "description": "Start date in YYYY-MM-DD format" },
                  "to": { "type": "string", "format": "date", "description": "End date in YYYY-MM-DD format" },
                  "market": { "type": "string", "enum": ["ALL", "RG", "NG"], "description": "Market segment (default ALL)" }
                },
                "required": ["tickers", "from", "to"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response containing foreign flow data for each ticker.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "foreign_buy": { "type": "integer" },
                          "foreign_sell": { "type": "integer" },
                          "net_foreign": { "type": "integer" }
                        }
                      }
                    },
                    "error": { "type": "string", "nullable": true }
                  }
                }
              }
            }
          },
          "400": { "description": "Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days)." },
          "401": { "description": "Unauthorized. Missing or invalid Bearer token." },
          "403": { "description": "Forbidden. Monthly or daily quota exhausted." },
          "422": { "description": "Validation error on the request parameters." },
          "429": { "description": "Too Many Requests. Rate limit exceeded." },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/usage": {
      "get": {
        "summary": "Check Usage & Limits",
        "description": "Monitor your active monthly call usage, current remaining quota, and reset date.",
        "responses": {
          "200": {
            "description": "Successful response containing usage metrics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "api_key": {
                          "type": "string",
                          "description": "Masked version of the active API key"
                        },
                        "monthly_limit": {
                          "type": "integer",
                          "description": "Total monthly quota allowed"
                        },
                        "current_usage": {
                          "type": "integer",
                          "description": "Number of API calls consumed this period"
                        },
                        "remaining": {
                          "type": "integer",
                          "description": "Number of API calls remaining in active quota"
                        },
                        "reset_date": {
                          "type": "string",
                          "format": "date-time",
                          "description": "The timestamp when the quota resets"
                        }
                      }
                    },
                    "error": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "Bad Request. Invalid parameters (e.g., dates before coverage start or a range longer than 366 days)." },
          "401": {
            "description": "Unauthorized. Missing or invalid Bearer token."
          },
          "403": { "description": "Forbidden. Monthly or daily quota exhausted." },
          "422": { "description": "Validation error on the request parameters." },
          "429": {
            "description": "Too Many Requests. Rate limit exceeded."
          },
          "500": { "description": "Internal server error." }
        }
      }
    },
    "/news": {
      "get": {
        "summary": "Get Market News",
        "description": "Fetches the latest articles from Indonesian market news RSS feeds and returns them grouped by source, newest first within each source. Articles are fetched live from the publisher feeds with a short 30s cache; a temporarily unreachable source is skipped.",
        "responses": {
          "200": {
            "description": "Successful response containing per-source news articles.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "source": { "type": "string" },
                            "title": { "type": "string" },
                            "description": { "type": "string" },
                            "link": { "type": "string" },
                            "image_url": { "type": "string" },
                            "guid": { "type": "string", "nullable": true },
                            "published_date": { "type": "string", "format": "date-time", "nullable": true }
                          }
                        }
                      }
                    },
                    "error": { "type": "string", "nullable": true }
                  }
                }
              }
            }
          },
          "401": { "description": "Unauthorized. Missing or invalid Bearer token." },
          "403": { "description": "Forbidden. Monthly or daily quota exhausted." },
          "429": { "description": "Too Many Requests. Rate limit exceeded." },
          "500": { "description": "Internal server error." }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ]
}

3. Cursor Rules & Copilot Instructions

Jika Anda menggunakan IDE berbasis AI seperti Cursor, Windsurf, atau VS Code Copilot, salin ruleset berikut dan simpan sebagai .cursorrules atau .github/copilot-instructions.md di root proyek Anda.

Ini memastikan bahwa setiap kali Anda meminta AI untuk membuat komponen pelacakan saham, analisis perdagangan, atau akumulasi broker, ia menulis kode yang rapi dan type-safe yang kompatibel dengan Index Alpha:

# Index Alpha API Integration Guidelines

You are an expert developer building an integration with the Index Alpha API, which provides premium Indonesian Stock Exchange (IDX) broker summary analytics.

## API Architecture Reference
- Base URL: `https://api.indexalpha.id/`
- Authorization: Bearer Token required on all requests in the header: `Authorization: Bearer <token>`

## Available Endpoints

### 1. Retrieve Broker Summary (`GET /stocks/broker-summary`)
Returns daily broker transaction summaries for a stock ticker.
- **Parameters:**
  - `ticker` (string, required): Stock ticker symbol (e.g., `BBCA`, `TLKM`)
  - `from` (string, required, YYYY-MM-DD): Start date (2025-01-01 or later)
  - `to` (string, required, YYYY-MM-DD): End date
  - `investor` (string, required): One of `all`, `f` (foreign), `d` (domestic)
- **Output:** Returns an array of broker records with:
  - `code` (broker initials), `buy_freq`, `buy_volume`, `buy_value`, `sell_freq`, `sell_volume`, `sell_value`, `buy_avg` (weighted price), `sell_avg`

### 2. Batch Broker Summary (`POST /stocks/broker-summary/batch`)
Returns aggregated broker activity for multiple stock tickers.
- **Body:**
  - `tickers` (array[string], required): Stock tickers (e.g., `["BBCA", "TLKM"]`)
  - `from` (string, required, YYYY-MM-DD): Start date
  - `to` (string, required, YYYY-MM-DD): End date
  - `investor` (string, optional): One of `all`, `f`, `d`
  - `market` (string, optional): One of `RG`, `NG`, `ALL`

### 3. Foreign Flow (`GET /foreign-flow`)
Returns aggregated foreign buy, sell, and net trading activity for a stock ticker.
- **Parameters:**
  - `ticker` (string, required): Stock ticker symbol (e.g., `BBCA`, `TLKM`)
  - `from` (string, required, YYYY-MM-DD): Start date
  - `to` (string, required, YYYY-MM-DD): End date
  - `market` (string, optional): One of `ALL`, `RG`, `NG` (default `ALL`)

### 4. Batch Foreign Flow (`POST /foreign-flow/batch`)
Returns aggregated foreign flow for multiple stock tickers.
- **Body:**
  - `tickers` (array[string], required): Stock tickers (e.g., `["BBCA", "TLKM"]`)
  - `from` (string, required, YYYY-MM-DD): Start date
  - `to` (string, required, YYYY-MM-DD): End date
  - `market` (string, optional): One of `ALL`, `RG`, `NG`

### 5. Check Usage and Quotas (`GET /usage`)
Returns API quota status. Highly recommended to run periodically to avoid rate limits or exhaustion.
- **Output:** Returns `monthly_limit`, `current_usage`, `remaining`, `reset_date`.

### 6. Market News (`GET /news`)
Fetches the latest articles from Indonesian market news RSS feeds, grouped by source.
- **Parameters:** none
- **Output:** Returns an object mapping each source name to a newest-first array of articles with `source`, `title`, `description`, `link`, `image_url`, `guid`, `published_date`.

## Code Conventions (TypeScript)

Use the following strict types when building integrations:

```typescript
export interface BrokerSummaryRecord {
  code: string;
  buy_freq: number;
  buy_volume: number;
  buy_value: number;
  sell_freq: number;
  sell_volume: number;
  sell_value: number;
  buy_avg: number;
  sell_avg: number;
}

export interface ApiResponse<T> {
  success: boolean;
  data: T;
  error: string | null;
}

export interface UsageData {
  api_key: string;
  monthly_limit: number;
  current_usage: number;
  remaining: number;
  reset_date: string;
}

export interface BatchBrokerSummaryRequest {
  tickers: string[];
  from: string;
  to: string;
  investor?: string;
  market?: string;
}

export interface ForeignFlowData {
  foreign_buy: number;
  foreign_sell: number;
  net_foreign: number;
}

export interface BatchForeignFlowRequest {
  tickers: string[];
  from: string;
  to: string;
  market?: string;
}
```

## Critical Integration Tips
- **Trading Schedule**: Broker summaries only provide Regular Market records. The metrics are refreshed once daily at 12:00 GMT (19:00 Jakarta / WIB time) on active trading days.
- **Error & Quota Handling**:
  - Catch `401 Unauthorized` for key validation issues.
  - Catch `429 Too Many Requests` when limits are reached. Free tier is strictly limited to 10 requests per minute and 5 per day. Check remaining quota via `/usage`.
- **Performance**: Cache broker summary results for a specific ticker + date range. The data is historical and static after the daily refresh, meaning there is no need to make repeated API calls for the same parameters.

4. Format Tool Call LLM Standar (JSON Schema)

Saat mengintegrasikan Index Alpha langsung ke codebase menggunakan OpenAI Node/Python SDKs, LangChain, atau Vercel AI SDK, Anda dapat meneruskan definisi tool berikut langsung ke model:

[
  {
    "type": "function",
    "function": {
      "name": "get_broker_summary",
      "description": "Retrieves the aggregated daily activity and transaction summaries for stock brokers on a specific Indonesian Stock Exchange (IDX) stock ticker for a date range.",
      "parameters": {
        "type": "object",
        "properties": {
          "ticker": {
            "type": "string",
            "description": "The stock ticker symbol (e.g., BBCA, TLKM, ASII)."
          },
          "from": {
            "type": "string",
            "description": "Start date in YYYY-MM-DD format. Data begins 2025-01-01."
          },
          "to": {
            "type": "string",
            "description": "End date in YYYY-MM-DD format."
          },
          "investor": {
            "type": "string",
            "enum": ["all", "f", "d"],
            "description": "Filter by investor type: 'all', 'f' (foreign), 'd' (domestic)."
          }
        },
        "required": ["ticker", "from", "to", "investor"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "get_api_usage",
      "description": "Checks the active API key monthly call limits, current usage, and remaining quota for the Index Alpha API.",
      "parameters": {
        "type": "object",
        "properties": {}
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "get_foreign_flow",
      "description": "Returns aggregated foreign buy, sell, and net trading activity for a stock ticker over a date range.",
      "parameters": {
        "type": "object",
        "properties": {
          "ticker": {
            "type": "string",
            "description": "The stock ticker symbol (e.g., BBCA, TLKM)."
          },
          "from": {
            "type": "string",
            "description": "Start date in YYYY-MM-DD format."
          },
          "to": {
            "type": "string",
            "description": "End date in YYYY-MM-DD format."
          },
          "market": {
            "type": "string",
            "enum": ["ALL", "RG", "NG"],
            "description": "Market segment: RG, NG, or ALL (default)."
          }
        },
        "required": ["ticker", "from", "to"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "get_broker_summary_batch",
      "description": "Retrieve aggregated broker activity for multiple stock tickers in a single request.",
      "parameters": {
        "type": "object",
        "properties": {
          "tickers": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Array of stock tickers (e.g., [\"BBCA\", \"TLKM\"]). Min 1, Max 50."
          },
          "from": { "type": "string", "description": "Start date in YYYY-MM-DD format." },
          "to": { "type": "string", "description": "End date in YYYY-MM-DD format." },
          "investor": {
            "type": "string",
            "enum": ["all", "f", "d"],
            "description": "Investor type: all (default), f (foreign), d (domestic)."
          },
          "market": {
            "type": "string",
            "enum": ["RG", "NG", "ALL"],
            "description": "Market segment: RG (default), NG, or ALL."
          }
        },
        "required": ["tickers", "from", "to"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "get_foreign_flow_batch",
      "description": "Retrieve aggregated foreign flow for multiple stock tickers in a single request.",
      "parameters": {
        "type": "object",
        "properties": {
          "tickers": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Array of stock tickers (e.g., [\"BBCA\", \"TLKM\"]). Min 1, Max 50."
          },
          "from": { "type": "string", "description": "Start date in YYYY-MM-DD format." },
          "to": { "type": "string", "description": "End date in YYYY-MM-DD format." },
          "market": {
            "type": "string",
            "enum": ["ALL", "RG", "NG"],
            "description": "Market segment: ALL (default), RG, or NG."
          }
        },
        "required": ["tickers", "from", "to"]
      }
    }
  }
]

Berikut cara mengeksekusi tools tersebut di backend Anda saat model memicu function call:

import axios from 'axios';

const INDEX_ALPHA_API_KEY = process.env.INDEX_ALPHA_API_KEY;
const client = axios.create({
  baseURL: 'https://api.indexalpha.id',
  headers: {
    'Authorization': `Bearer ${INDEX_ALPHA_API_KEY}`,
    'Accept': 'application/json',
  }
});

export async function handleToolCall(name: string, args: any) {
  switch (name) {
    case 'get_broker_summary':
      const { ticker, from, to, investor } = args;
      const summaryRes = await client.get('/stocks/broker-summary', {
        params: { ticker, from, to, investor }
      });
      return summaryRes.data;

    case 'get_api_usage':
      const usageRes = await client.get('/usage');
      return usageRes.data;

    case 'get_foreign_flow':
      const { ticker: ffTicker, from: ffFrom, to: ffTo, market: ffMarket } = args;
      const ffRes = await client.get('/foreign-flow', {
        params: { ticker: ffTicker, from: ffFrom, to: ffTo, market: ffMarket || 'ALL' }
      });
      return ffRes.data;

    case 'get_broker_summary_batch':
      const bsRes = await client.post('/stocks/broker-summary/batch', args);
      return bsRes.data;

    case 'get_foreign_flow_batch':
      const ffbRes = await client.post('/foreign-flow/batch', args);
      return ffbRes.data;

    default:
      throw new Error(`Unknown tool: ${name}`);
  }
}

5. Ekspos sebagai Model Context Protocol (MCP) Server

Model Context Protocol (MCP) adalah standar terbuka yang dirancang oleh Anthropic untuk mengekspos tools dan resources langsung ke klien LLM (seperti Claude Desktop, Cursor, atau ekstensi IDE).

Dengan menjalankan MCP server lokal, asisten AI dapat melakukan query ringkasan broker IDX secara real time dengan mulus untuk menjawab prompt analitis dari pengguna.

Lebih suka tidak menjalankan server lokal? Hubungkan langsung ke endpoint hosted kami. Lihat panduan Koneksi MCP Remote.

Berikut adalah implementasi MCP Server Node.js siap jalankan dalam satu file menggunakan SDK resmi.

Langkah 1: Buat File Server

Buat file bernama index-alpha-mcp.js dan instal dependensinya:

npm install @modelcontextprotocol/sdk

Simpan kode berikut di dalam index-alpha-mcp.js:

#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import fetch from "node-fetch";

const API_KEY = process.env.INDEX_ALPHA_API_KEY;
if (!API_KEY) {
  console.error("Error: INDEX_ALPHA_API_KEY environment variable is required.");
  process.exit(1);
}

const server = new Server(
  {
    name: "index-alpha-mcp-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// Register Tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "get_broker_summary",
        description: "Fetch Indonesian Stock Exchange (IDX) broker daily accumulations and transaction activity for a ticker.",
        inputSchema: {
          type: "object",
          properties: {
            ticker: { type: "string", description: "Stock symbol (e.g. BBCA, TLKM)" },
            from: { type: "string", description: "Start date YYYY-MM-DD (historical starting 2025-01-01)" },
            to: { type: "string", description: "End date YYYY-MM-DD" },
            investor: { type: "string", enum: ["all", "f", "d"], description: "Investor group filter" },
          },
          required: ["ticker", "from", "to", "investor"],
        },
      },
      {
        name: "get_usage_limits",
        description: "Check active Index Alpha API quota usage and remaining limits.",
        inputSchema: { type: "object", properties: {} },
      },
      {
        name: "get_foreign_flow",
        description: "Get aggregated foreign buy, sell, and net trading activity for a stock ticker over a date range.",
        inputSchema: {
          type: "object",
          properties: {
            ticker: { type: "string", description: "Stock symbol (e.g. BBCA, TLKM)" },
            from: { type: "string", description: "Start date YYYY-MM-DD" },
            to: { type: "string", description: "End date YYYY-MM-DD" },
            market: { type: "string", enum: ["ALL", "RG", "NG"], description: "Market segment (default ALL)" },
          },
          required: ["ticker", "from", "to"],
        },
      },
      {
        name: "get_broker_summary_batch",
        description: "Retrieve aggregated broker activity for multiple stock tickers in a single request.",
        inputSchema: {
          type: "object",
          properties: {
            tickers: { type: "array", items: { type: "string" }, description: "Array of stock tickers (e.g. [\"BBCA\", \"TLKM\"]). Min 1, Max 50." },
            from: { type: "string", description: "Start date YYYY-MM-DD" },
            to: { type: "string", description: "End date YYYY-MM-DD" },
            investor: { type: "string", enum: ["all", "f", "d"], description: "Investor type (default all)" },
            market: { type: "string", enum: ["RG", "NG", "ALL"], description: "Market segment (default RG)" },
          },
          required: ["tickers", "from", "to"],
        },
      },
      {
        name: "get_foreign_flow_batch",
        description: "Retrieve aggregated foreign flow for multiple stock tickers in a single request.",
        inputSchema: {
          type: "object",
          properties: {
            tickers: { type: "array", items: { type: "string" }, description: "Array of stock tickers (e.g. [\"BBCA\", \"TLKM\"]). Min 1, Max 50." },
            from: { type: "string", description: "Start date YYYY-MM-DD" },
            to: { type: "string", description: "End date YYYY-MM-DD" },
            market: { type: "string", enum: ["ALL", "RG", "NG"], description: "Market segment (default ALL)" },
          },
          required: ["tickers", "from", "to"],
        },
      },
    ],
  };
});

// Handle Tool Calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  try {
    if (name === "get_broker_summary") {
      const url = `https://api.indexalpha.id/stocks/broker-summary?ticker=${args.ticker}&from=${args.from}&to=${args.to}&investor=${args.investor}`;
      const response = await fetch(url, {
        headers: {
          "Authorization": `Bearer ${API_KEY}`,
          "Accept": "application/json"
        }
      });
      const data = await response.json();
      return {
        content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
      };
    } else if (name === "get_usage_limits") {
      const response = await fetch("https://api.indexalpha.id/usage", {
        headers: {
          "Authorization": `Bearer ${API_KEY}`,
          "Accept": "application/json"
        }
      });
      const data = await response.json();
      return {
        content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
      };
    } else if (name === "get_foreign_flow") {
      const params = new URLSearchParams({
        ticker: args.ticker,
        from: args.from,
        to: args.to,
      });
      if (args.market) params.append("market", args.market);
      const response = await fetch(`https://api.indexalpha.id/foreign-flow?${params}`, {
        headers: {
          "Authorization": `Bearer ${API_KEY}`,
          "Accept": "application/json"
        }
      });
      const data = await response.json();
      return {
        content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
      };
    } else if (name === "get_broker_summary_batch") {
      const response = await fetch("https://api.indexalpha.id/stocks/broker-summary/batch", {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${API_KEY}`,
          "Content-Type": "application/json",
          "Accept": "application/json"
        },
        body: JSON.stringify(args)
      });
      const data = await response.json();
      return {
        content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
      };
    } else if (name === "get_foreign_flow_batch") {
      const response = await fetch("https://api.indexalpha.id/foreign-flow/batch", {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${API_KEY}`,
          "Content-Type": "application/json",
          "Accept": "application/json"
        },
        body: JSON.stringify(args)
      });
      const data = await response.json();
      return {
        content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
      };
    } else {
      throw new Error(`Tool not found: ${name}`);
    }
  } catch (error) {
    return {
      isError: true,
      content: [{ type: "text", text: error.message }],
    };
  }
});

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Index Alpha MCP Server running on stdio");
}

main().catch((err) => {
  console.error("Fatal error:", err);
  process.exit(1);
});

Langkah 2: Konfigurasikan Klien LLM Anda (misalnya Claude Desktop)

Untuk menggunakan server dengan Claude Desktop, tambahkan ke file konfigurasi Anda (biasanya di AppData\Roaming\Claude\claude_desktop_config.json di Windows atau ~/Library/Application Support/Claude/claude_desktop_config.json di macOS):

{
  "mcpServers": {
    "index-alpha": {
      "command": "node",
      "args": ["/path/to/index-alpha-mcp.js"],
      "env": {
        "INDEX_ALPHA_API_KEY": "YOUR_ACTUAL_API_KEY"
      }
    }
  }
}

Restart Claude Desktop, dan asisten Anda akan dapat melakukan query data broker summary secara langsung dalam percakapan!

Di halaman ini