Arthalekh Docs

Build production-grade return forensics without rebuilding the finance logic stack.

The SDK and API are designed for teams that need raw prices, corporate actions, IPO assumptions, and value simulation to stay consistent across dashboards, workflows, and internal tooling.

Quick facts
SDK package
@arthalekh/sdk
REST base URL
https://arthalekh.com/api/v1
MCP endpoint
https://arthalekh.com/mcp
Contract
/api/v1/openapi.json
Auth
Bearer API key
Guide

Quickstart

Install the SDK, create a client, and run your first return-forensics request in minutes.

Install

Use the official npm package and keep your API key server-side for production apps.

bash
npm install @arthalekh/sdk

Create a client

The SDK talks to the hosted Arthalekh API and returns typed envelopes with data, source, warning, and requestId.

ts
import { createArthalekhClient } from '@arthalekh/sdk';

const client = createArthalekhClient({
  apiKey: process.env.ARTHALEKH_API_KEY!,
});

Run analysis

This returns the same core workflow your users see in the Arthalekh app: prices, actions, resolved IPO inputs, latest quote, and simulated portfolio output.

ts
const result = await client.analysis.run({
  symbol: 'WIPRO.NSE',
  initialInvestment: 10000,
  includeDividends: true,
});

console.log(result.data.simulation.finalValue);
console.log(result.data.actions.bonuses);

Build a chart-ready bundle

If your frontend needs summary labels and precomputed markers immediately, use analysis.bundle(...) instead of composing that layer yourself.

ts
const bundle = await client.analysis.bundle({
  symbol: 'RELIANCE.NSE',
  initialInvestment: 50000,
});

console.log(bundle.data.summary.finalValueLabel);
console.log(bundle.data.markers.price.dividends);

Clean peer comparisons

Set includeStoredBonuses: false when you want comparisons to ignore manually stored bonus overrides and use only Arthalekh defaults plus any request-scoped manual bonuses.

ts
const result = await client.analysis.run({
  symbol: 'INFY.NSE',
  initialInvestment: 10000,
  includeStoredBonuses: false,
});

console.log(result.data.actions.bonuses);
Guide

MCP Access

Expose Arthalekh content and live return-forensics through a public read-only MCP server.

Endpoint

Arthalekh publishes a remote MCP server at https://arthalekh.com/mcp.

It is intentionally read-only and designed for external clients that can speak MCP over HTTP.

Available tools

Use search to find relevant Arthalekh pages, guides, blog posts, developer docs, and stock methodology pages.

Use fetch to retrieve a full document body for a search result with its canonical URL for citations.

Use analyze_stock to run live action-aware stock analysis from the same underlying Arthalekh workflow used in the app.

Connection example

Use this server URL when connecting Arthalekh to any MCP-capable client.

json
{
  "type": "url",
  "name": "arthalekh",
  "url": "https://arthalekh.com/mcp"
}
Guide

Authentication

Authenticate with an Arthalekh API key and understand free vs pro behavior.

API keys

Send your key as Authorization: Bearer <key> or let the SDK do it for you.

Free keys are rate-limited more aggressively than Pro keys. Every successful response includes a requestId for support and debugging.

Raw REST example

You can call the HTTP API directly if you prefer your own client stack.

bash
curl -X GET 'https://arthalekh.com/api/v1/prices?symbol=INFY.NSE' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Guide

JavaScript SDK

Understand the SDK client methods, helper utilities, and chart-marker helpers.

Core methods

client.prices.get, client.actions.get, client.quote.get, client.metadata.get, client.metadata.upsert, client.bonuses.get, client.bonuses.replace, client.analysis.run, client.analysis.bundle, client.analysis.runMany, client.health.get, and client.openapi.get are all available from a single client instance.

client.openapi.get returns the raw OpenAPI document because the contract route is intentionally public and unwrapped.

Marker helpers for charts

Use the local chart-marker helpers when you want to plot dividends, splits, and bonuses on your own charting library.

ts
import { buildPriceChartMarkers } from '@arthalekh/sdk';

const markers = buildPriceChartMarkers({
  prices: result.data.prices,
  dividends: result.data.actions.dividends,
  splits: result.data.actions.splits,
  bonuses: result.data.actions.bonuses,
});

Batch analysis

Use runMany for portfolio screens, comparison tables, or internal research jobs that need multiple symbols in one pass.

ts
const rows = await client.analysis.runMany(
  [
    { symbol: 'INFY.NSE', initialInvestment: 10000 },
    { symbol: 'TCS.NSE', initialInvestment: 10000 },
    { symbol: 'WIPRO.NSE', initialInvestment: 10000 },
  ],
  { concurrency: 2 },
);

const successful = rows.filter((row) => row.ok);

Infrastructure checks

Use the health surface in CI or internal tooling to verify that the API is up and cache-backed before a batch job starts.

ts
const health = await client.health.get();

console.log(health.data.status);
console.log(health.data.cacheSymbols);
Guide

REST API

Use the versioned HTTP API directly when you do not want a package dependency.

Base URL

All SDK-backed public endpoints live under https://arthalekh.com/api/v1.

OpenAPI

Use the live OpenAPI document for internal tooling, generated clients, or contract verification in CI.

bash
curl -X GET 'https://arthalekh.com/api/v1/openapi.json'

Health endpoint

Call the authenticated health endpoint to verify API availability, key validity, and cache readiness.

bash
curl -X GET 'https://arthalekh.com/api/v1/health' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Guide

Analysis Workflow

Understand how Arthalekh resolves IPO assumptions and computes value over time.

Resolution order

Explicit request inputs win first. If omitted, Arthalekh uses saved metadata, then internal IPO hints for known symbols, then the earliest available trading day in the loaded price series.

Bonus events are merged from stored manual bonuses, internal assumptions, and any manual bonuses passed in the request.

Simulation model

Shares begin as initialInvestment / ipoPrice.

Splits and bonuses change share count. Dividends add cash. Portfolio value is shares * close + cash on each trading day.

Server-assisted integration

For frontend apps, call your own backend route, invoke client.analysis.bundle there, and send only the minimal payload to the browser.

This is the same pattern Arthalekh uses for /app so the browser never needs a developer API key.

ts
import { createArthalekhClient } from '@arthalekh/sdk';

const client = createArthalekhClient({
  apiKey: process.env.ARTHALEKH_API_KEY!,
  baseUrl: 'https://arthalekh.com/api/v1',
});

export async function POST(req: Request) {
  const body = await req.json();
  const bundle = await client.analysis.bundle({
    symbol: body.symbol,
    initialInvestment: body.initialInvestment,
    includeDividends: body.includeDividends ?? true,
    includeStoredBonuses: body.includeStoredBonuses ?? true,
  });

  return Response.json({
    data: { bundle: bundle.data },
    source: bundle.source,
    warning: bundle.warning,
  });
}
Guide

Errors and Limits

Handle rate limits, demo fallbacks, and typed SDK errors safely.

Error model

The SDK throws ArthalekhApiError for non-2xx responses. It includes status, code, requestId, and retryable.

The source field in successful responses tells you whether results came from live API, cache, stale cache, demo fallback, or system metadata.

Handling failures

Treat source: demo and warning as product signals, not just transport details. They let you keep UX graceful when live providers are degraded.

ts
import { ArthalekhApiError } from '@arthalekh/sdk';

try {
  const result = await client.analysis.run({
    symbol: 'INFY.NSE',
    initialInvestment: 10000,
  });

  if (result.warning) {
    console.warn(result.warning);
  }
} catch (error) {
  if (error instanceof ArthalekhApiError) {
    console.error(error.code, error.status, error.requestId);
  }
}

OpenAPI access

The contract document is public and raw. You can fetch it through the SDK or hit the route directly in CI and codegen pipelines.

ts
const openapi = await client.openapi.get();

console.log(openapi.openapi);
console.log(Object.keys(openapi.paths ?? {}));
Guide

Changelog

Track the public SDK and API contract over time.

0.3.0

Fixes client.openapi.get so it returns the raw OpenAPI document instead of treating it like an envelope.

Adds includeStoredBonuses to the analysis input so app-style peer comparisons can intentionally ignore stored manual bonus overrides.

Documents the same server-side SDK bridge pattern used by Arthalekh /app.

0.2.0

Adds analysis.bundle and analysis.runMany for app-ready UI output and batch workflows.

Adds authenticated health checks, richer OpenAPI coverage, and upgraded developer docs.

0.1.0

Initial public release.

Includes core prices, actions, quote, metadata, bonuses, and analysis workflows.

Includes local helpers for simulation, symbol normalization, formatting, and chart markers.

Reference

SDK Reference

These are the main client methods teams reach for when they need app-parity analysis, UI-ready bundles, or operational checks.

MethodReturnsWhy it matters
client.prices.get(symbol)ApiResult<{ prices: PricePoint[] }>Unadjusted daily closes from the first available trading date to the latest cached or live date.
client.actions.get(symbol)ApiResult<MappedEvents>Dividend and split events normalized to the same contract used by the Arthalekh app.
client.quote.get(symbol)ApiResult<{ symbol: string; quote: PricePoint | null }>Latest available close from the underlying price series.
client.metadata.get(symbol)ApiResult<{ metadata: IpoMetadata | null }>Saved IPO metadata or Arthalekh defaults for known symbols.
client.metadata.upsert(symbol, metadata)ApiResult<{ ok: boolean; metadata: ... }>Write IPO anchor metadata for your workflows.
client.bonuses.get(symbol)ApiResult<{ bonuses: BonusEvent[] }>Stored manual bonuses merged with Arthalekh assumptions.
client.bonuses.replace(symbol, bonuses)ApiResult<{ ok: boolean; bonuses: BonusEvent[] }>Replace the manual bonus set used for a symbol.
client.analysis.run(input)ApiResult<AnalysisResult>One-call workflow for prices, actions, IPO resolution, and portfolio simulation.
client.analysis.bundle(input)ApiResult<AnalysisBundle>Same as run, plus chart-ready markers and formatted summary strings for UI use.
client.analysis.runMany(inputs, { concurrency })Promise<BatchAnalysisResult[]>Batch analysis with bounded concurrency and per-input success or error output.
client.health.get()ApiResult<HealthSnapshot>Check Arthalekh API availability, environment, and cache footprint with your current key.
client.openapi.get()Promise<OpenApiDocument>Fetch the raw live OpenAPI document that describes the public API contract.
Reference

REST API Reference

Use the versioned HTTP surface directly when you want full control over transport, caching, or generated client code.

MethodPathAuthDescription
GET/api/v1/prices?symbol=INFY.NSEAPI keyFetch unadjusted daily prices.
GET/api/v1/actions?symbol=INFY.NSEAPI keyFetch dividends and splits.
GET/api/v1/quote?symbol=INFY.NSEAPI keyFetch latest available close.
GET/api/v1/metadata?symbol=INFY.NSEAPI keyFetch IPO metadata.
POST/api/v1/metadataAPI keyUpsert IPO metadata.
GET/api/v1/bonuses?symbol=INFY.NSEAPI keyFetch merged manual bonuses.
POST/api/v1/bonusesAPI keyReplace manual bonuses.
POST/api/v1/analysisAPI keyRun the full return-forensics workflow.
GET/api/v1/healthAPI keyCheck API health and cache readiness with your key.
GET/api/v1/openapi.jsonPublicFetch the machine-readable contract.
Reference

Stable Response Shape

Authenticated API methods follow the same envelope. That makes it easier to centralize logging, retries, UX copy, and support workflows. The public OpenAPI contract route is the one raw-document exception.

json
{
  "data": {
    "symbol": "WIPRO.NSE",
    "resolvedInputs": {
      "ipoDate": "1980-01-02",
      "ipoPrice": 100,
      "initialInvestment": 10000,
      "includeDividends": true
    }
  },
  "source": "api",
  "warning": "Optional warning when Arthalekh falls back to stale cache or demo data.",
  "requestId": "req_01HXYZ..."
}
source

Tells you whether the result came from live API, cache, stale cache, demo fallback, or system defaults.

warning

Use this for user-visible messaging when provider limits or degraded data paths are involved.

requestId

Attach this to support tickets and logs so API issues can be traced quickly.

Reference

Errors and Recovery

These are the main public error codes to plan for in apps, CRON jobs, and support tooling.

CodeStatusDescriptionRecovery
UNAUTHORIZED401Missing, invalid, or inactive API key.Send Authorization: Bearer <key> or x-api-key with an active key.
RATE_LIMITED429Per-minute plan quota exceeded for the API key.Respect retry delays, reduce burst size, or upgrade the key plan.
BAD_JSON400The request body could not be parsed as valid JSON.Send application/json with a syntactically valid body.
INVALID_INPUT400A required field such as symbol or initialInvestment was invalid.Validate inputs client-side before sending the request.
UNSUPPORTED_MEDIA_TYPE415A JSON endpoint was called without application/json.Set the content-type header to application/json for POST requests.
ANALYSIS_FAILED400The analysis workflow could not resolve or compute a valid result.Check the symbol, IPO assumptions, and any manual bonus payload you supplied.