Developer API

HSN / SAC Lookup API

A free public API for looking up HSN and SAC codes against the CBIC GST schedule. No API key. No signup. CORS-enabled. Best-effort uptime on Cloudflare Workers.

Quickstart

Three curls

Forward lookup, reverse lookup, and dataset metadata. Open a terminal and try them.

# Forward lookup — description to HSN/SAC code
curl 'https://hsn.krakelabsindia.com/api/lookup?q=cotton+t-shirt'

# Reverse lookup — code to description + GST rate
curl 'https://hsn.krakelabsindia.com/api/lookup?code=8517'

# Dataset metadata — counts and snapshot date
curl 'https://hsn.krakelabsindia.com/api/meta'
Reference

Endpoints

MethodPathParamsDescription
GET/api/lookup?q=...q (required), limit (1-20, default 5)Forward lookup. Returns up to limit matches ranked by confidence.
GET/api/lookup?code=...code (required)Reverse lookup. Supports prefix matches (e.g. 85 returns chapter 85 entries).
POST/api/lookupJSON body: {items: string[]} (1-10 items)Batch forward lookup. Best for bulk-classifying invoice line items.
GET/api/metaDataset metadata: counts, snapshot date, source URL.
GET/openapi.jsonOpenAPI 3.1 specification. Drop into Swagger Editor or Postman to autogenerate clients.

Sample response — forward lookup

$ curl 'https://hsn.krakelabsindia.com/api/lookup?q=cotton+t-shirt&limit=2'

{
  "query": "cotton t-shirt",
  "matches": [
    {
      "description": "T-shirts, singlets and other vests, knitted or crocheted",
      "hsn_sac": "6109",
      "chapter": "Articles of apparel and clothing accessories, knitted or crocheted",
      "gst_rate": "12%",
      "type": "goods",
      "notes": "5% if sale value below ₹1000 per piece",
      "why": "Matched on 'cotton' and 't-shirt'",
      "confidence": 0.84
    },
    { "...": "next-best candidate" }
  ]
}

Sample response — reverse lookup

$ curl 'https://hsn.krakelabsindia.com/api/lookup?code=8517'

{
  "query": "8517",
  "results": [
    {
      "description": "Telephone sets, including smartphones and other telephones for cellular networks or for other wireless networks",
      "hsn_sac": "8517",
      "chapter": "Electrical machinery and equipment and parts thereof",
      "gst_rate": "18%",
      "type": "goods",
      "notes": "",
      "confidence": 1
    }
  ]
}
Schemas

Response shape

TypeScript shape for a single match. The same shape is used inmatches[] (forward) and results[] (reverse).

interface HsnResult {
  description: string;        // Canonical description of the matched code
  hsn_sac: string;            // The HSN (goods) or SAC (services) code
  chapter: string;            // Chapter heading for context
  gst_rate: string;           // GST rate as published in the CBIC schedule
  type: "goods" | "services"; // HSN vs SAC
  notes: string;              // Caveats, sub-rates, schedule notes
  why?: string;               // Human-readable match explanation
  confidence?: number;        // 0-1; low values mean we're guessing
  alternates?: HsnResult[];   // Only on POST /api/lookup batch responses
}

interface DatasetMeta {
  totalCodes: number;
  goodsCount: number;
  servicesCount: number;
  asOf: string;       // ISO date of the CBIC snapshot
  sourceUrl: string;  // Where the dataset came from
}

interface ErrorResponse {
  error: string;
}
Fair use

How to be a good citizen

No API key is required for now. Treat this as a goodwill resource:

  • Cache aggressively. The CBIC schedule barely changes — responses are safe to cache for ~1 week. Our GET endpoints set Cache-Control: public, max-age=3600; cache longer at your edge if you want.
  • Don't hammer. Please stay under ~10 req/s sustained per origin. Batch with POST /api/lookup (up to 10 items per call) instead of looping serial GETs.
  • Credit the source. The underlying dataset is the CBIC GST schedule — same source we credit on the homepage.
  • No SLA.This is a best-effort free service running on Cloudflare Workers. We don't promise uptime numbers we can't back up.

We may introduce keys and tiered limits if abuse becomes a problem — but only after warning, and free-tier access will stay.

Rate limits

What we actually enforce

Today: a soft per-IP cap to keep abusive bursts from knocking the worker over. If you hit it you'll see HTTP 429 with a JSON error body — wait a minute and retry. We have not built a paid tier or token-bucket service; if your use case needs guaranteed throughput, email krakelabsindia.com and we'll figure something out.

Versioning

Stability promise

The current API is implicitly v1. We promise to keep the response shape for GET /api/lookup?q=, GET /api/lookup?code=, and GET /api/meta backwards-compatible: existing fields won't change type or disappear without notice.

New fields may be added. Any breaking change will live behind /api/v2/* alongside the original endpoints.

Want a drop-in UI widget instead?

If you don't want to render results yourself, our embed widget gives your site a working HSN lookup with two lines of HTML — no API integration required.

See the embed widget →
Machine-readable

OpenAPI 3.1 spec

The full API surface is published as OpenAPI 3.1 JSON. Paste the URL into Swagger Editor, Postman, or your favorite code generator.

GET /openapi.json