{
  "openapi": "3.0.3",
  "info": {
    "title": "FileSure API",
    "version": "1.0",
    "contact": {
      "name": "FileSure Support",
      "email": "helpdesk@filesure.in",
      "url": "https://filesure.in"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://filesure.in/terms-and-conditions"
    },
    "description": "## Use with your AI tool\n\nMost integrations now start in an AI tool, so start there. Create a test key in the [Developer Portal](/portal/dashboard/keys) and put it in an environment variable named `FILESURE_API_KEY` on your machine. Then paste this into Claude, Cursor, Codex or ChatGPT. The prompt tells the tool where the key is, so the key itself never goes into the chat:\n\n```text\nRead https://api.filesure.in/llms-full.txt in full before writing any code. It is the complete reference for the FileSure API, which gives programmatic access to the Indian MCA register: companies, LLPs and directors, the documents they have filed, and the financial data extracted from those documents.\n\nMy API key is in the environment variable FILESURE_API_KEY. Read it from there; never print it, never paste it into a file, never ask me to type it. It is a test key: it works on the sandbox companies listed in the reference and nothing is charged.\n\nThen write a script that takes a company name, resolves it to a CIN, fetches the company's master data, and lists its most recent filings. Follow the reference for the base URL, the header that carries the key, the sandbox identifiers and the response envelope. Do not invent endpoints or fields that are not in the reference.\n```\n\nChange the last paragraph to whatever you are building. The reference explains what each call costs and when an unlock is needed, so the tool can tell you before it spends anything. When you are ready for real calls, put a live key in the same variable; those bill your wallet like any other request.\n\nThe same reference is available in four shapes, all generated from the source of this page, so none is ever behind it:\n\n| What | Where | Use it for |\n|---|---|---|\n| Everything in one file | [`/llms-full.txt`](/llms-full.txt) | Paste or attach the whole reference into one conversation, as above |\n| Index | [`/llms.txt`](/llms.txt) | Hand a tool the map of this reference; it follows the links it needs |\n| One page per endpoint | `/reference/<endpoint>.md`, listed in the index | Tools that index documentation page by page |\n| OpenAPI document | [`/portal/openapi-public.yaml`](/portal/openapi-public.yaml) or [`/portal/openapi-public.json`](/portal/openapi-public.json) | Any tool with an OpenAPI or custom-connector import |\n\n**Claude.** Paste the prompt, or attach `llms-full.txt` to a Project so every conversation starts with it. A custom connector can import the OpenAPI document.\n\n**Cursor.** Add `https://api.filesure.in/llms.txt` as a documentation source in Cursor's settings and reference it from chat with `@Docs`, or paste the prompt into a chat.\n\n**Codex.** Put the prompt in the task, or name `https://api.filesure.in/llms-full.txt` in your project instructions.\n\n**ChatGPT.** Paste the prompt, give a project `llms-full.txt` as a knowledge file, or import the OpenAPI document as an action.\n\nAll of the above has the tool write code against the API. To let the assistant call FileSure itself, connect it instead: [Connect your AI tool](#description/connect-your-ai-tool).\n\n---\n\n## Connect your AI tool\n\nFor an assistant that should call FileSure itself rather than write code against it, connect it to the FileSure MCP server. Every action in this reference becomes a tool the assistant can use: find a company, read its record, list its filings, read an extraction, check freshness, and so on. You ask in plain words; the assistant picks the call, makes it with your key, and reads the answer.\n\nAddress: `https://api.filesure.in/mcp`. Tools that can set a header send your key in `Authorization: Bearer` or `x-api-key`; tools that cannot sign in with your FileSure account instead. The setup for each tool is below. The [Developer Portal](/portal/dashboard/keys) shows the same blocks with your key already filled in whenever you create one.\n\n### Claude Code\n\n```bash\nclaude mcp add --transport http filesure https://api.filesure.in/mcp --header \"x-api-key: $FILESURE_API_KEY\"\n```\n\n### Cursor\n\nAdd to `.cursor/mcp.json` (or the global one in your home folder):\n\n```json\n{ \"mcpServers\": { \"filesure\": { \"url\": \"https://api.filesure.in/mcp\", \"headers\": { \"x-api-key\": \"fsk_test_YOUR_KEY\" } } } }\n```\n\n### Codex\n\nIn `~/.codex/config.toml`:\n\n```text\n[mcp_servers.filesure]\nurl = \"https://api.filesure.in/mcp\"\nhttp_headers = { \"x-api-key\" = \"fsk_test_YOUR_KEY\" }\n```\n\n### Claude.ai and Claude Desktop\n\nAdd a custom connector with the address `https://api.filesure.in/mcp` and nothing else. The tool sends you to the FileSure portal to sign in with your account; you pick which of your keys it should use and approve, and it is connected. The key itself never leaves FileSure: the tool holds a token bound to that key, and you can disconnect it any time from the API keys page, where connected tools are listed. Revoking the key disconnects it too.\n\nIf a tool cannot sign in, the keyed address is the fallback: `https://api.filesure.in/mcp/k/fsk_test_YOUR_KEY`. A key in a URL can end up in logs and history, so use a test key there, and revoke it from the portal when you are done.\n\n### Paid actions ask first\n\nUnlock, refresh and document fetch cost money. When the assistant reaches for one of them, the connector returns the price at your rate and what it buys instead of running it; the action runs only when the assistant calls again with your confirmation. Nothing is spent without a decision.\n\n### Every call is an ordinary API call\n\nEach tool call goes through the API with your key: it is billed at your rates, shows in your usage, and obeys the sandbox and your rate limit. Start with a test key; the assistant then has every tool on the sandbox companies and nothing is charged.\n\nWhat each tool does, what it takes, what it returns and what it costs: [Tools of the connector](#description/tools-of-the-connector) for the rules they share, and the [Tool reference](#description/tool-reference) for each one.\n\n---\n\n<!-- generated: connector tool pages, scripts/generate-tool-docs.ts; do not edit by hand -->\n\n## Tools of the connector\n\nThe FileSure connector gives an AI tool sixteen tools. Each one is an ordinary call to this API with your key: it is billed at your rates, shows in your usage, obeys your rate limit, and on a test key works on the sandbox and costs nothing. This page is the rules every tool follows; the [Tool reference](#description/tool-reference) describes each tool. How to connect a tool is on [Connect your AI tool](#description/connect-your-ai-tool).\n\n### The tools\n\n- **Sandbox identifiers**: `list_sandbox_entities`\n- **Look up the register**: `find_company`, `get_company`, `list_filings`, `find_director`, `get_director`\n- **Documents and financials**: `unlock_company`, `get_unlock_status`, `get_filing_document`, `list_extraction_forms`, `list_extraction_years`, `get_extraction`\n- **Keep a company current**: `check_freshness`, `refresh_company`, `fetch_documents`\n- **Your account**: `get_account`\n\nTools that read the register are billed per call at your rate for the endpoint behind them; the free ones (`list_sandbox_entities`, `get_unlock_status`, `check_freshness`, `get_account`) cost nothing on either key. Prices in the reference are the default rate card; if your account has negotiated rates, those apply.\n\n### Paid actions ask first\n\n`unlock_company`, `refresh_company`, `fetch_documents` spend money. Each takes a `confirm` flag. Called without it, the tool runs nothing: it looks up your rate for the action and returns a `quote` with the price, what it buys and how to proceed, and nothing is charged. The assistant is told to ask you before calling again with `confirm: true`, which runs the action and charges it. An action that is refused or fails is never charged, whatever the reason.\n\n### What a result looks like\n\nEvery tool returns exactly one of four results:\n\n| Result | When | What it carries |\n|---|---|---|\n| `success` | the API answered with JSON | the endpoint's `data` object unchanged, a one-line summary, and what the call cost and left in the wallet |\n| `file` | a filing PDF | the PDF as a resource, up to 10 MB, with its name, type and size, and a summary |\n| `quote` | a paid action called without `confirm: true` | your price for the action, what it buys, how to proceed; nothing ran |\n| `error` | any refusal or failure | the API's error (`code`, `message` and any extras such as the sandbox lists), the HTTP status, and a plain explanation |\n\nIn the connector, the text of a result is the summary followed by the data itself as JSON, so a client that shows the model only the text still gives it every name and identifier; the same data is also sent as structured content. A PDF larger than the inline limit comes back as a description with its size and the advice to read the extraction instead.\n\n### When a call is refused\n\nAn `error` result carries the API's code and message, and the connector adds a line telling the assistant what to do next:\n\n| Code | What the assistant is told |\n|---|---|\n| `MISSING_API_KEY` | No API key was sent. The connector needs the customer’s key. |\n| `INVALID_API_KEY` | The API key is not recognised. Check it was copied whole. |\n| `API_KEY_REVOKED` | This key was revoked in the developer portal; a new one is needed. |\n| `NO_ACCESS` | The account holds no price for this endpoint, so it cannot call it. Support can enable it. |\n| `SANDBOX_ONLY` | A test key only works on the sandbox companies and directors. The allowed ones are listed in this error (sandboxCompanies, sandboxDirectors) and by list_sandbox_entities; use one of those, or a live key. |\n| `UNLOCK_REQUIRED` | This needs an active company unlock first. unlock_company buys a year of access. |\n| `INSUFFICIENT_BALANCE` | The wallet cannot cover this call. Top up in the developer portal. |\n| `ALREADY_UNLOCKED` | The company is already unlocked; nothing was charged. |\n| `NOTHING_TO_FETCH` | Every listed filing already has its document; nothing to fetch, nothing charged. |\n| `RATE_LIMITED` | Too many requests in the last minute. Wait for the Retry-After seconds and try again. |\n| `NOT_FOUND` | FileSure does not hold this record. |\n| `COMPANY_NOT_FOUND` | FileSure does not hold this company. |\n| `INVALID_CIN` | The identifier failed format validation. |\n| `INVALID_DIN` | The DIN failed format validation. |\n| `DOC_NOT_AVAILABLE` | The document is not on file yet. Check freshness; fetch_documents downloads what is missing. |\n\n### Which form of the key each client uses\n\n| Client | How the connector gets your key | Where it is set up |\n|---|---|---|\n| Claude.ai and Claude Desktop | sign in with your FileSure account and pick a key; no key in the address | [Connect your AI tool](#description/connect-your-ai-tool) |\n| Claude Code | the key in an `x-api-key` header on the connector address | [Connect your AI tool](#description/connect-your-ai-tool) |\n| Cursor | the key in an `x-api-key` header on the connector address | [Connect your AI tool](#description/connect-your-ai-tool) |\n| Codex | the key in an `x-api-key` header on the connector address | [Connect your AI tool](#description/connect-your-ai-tool) |\n| Anything that can send neither | the keyed address, kept as a fallback | [Connect your AI tool](#description/connect-your-ai-tool) |\n\nRevoking the key in the developer portal disconnects every tool that used it.\n\n---\n\n## Tool reference\n\nOne entry per tool, generated from the definitions the connector serves, in the order the connector lists them. \"Rate\" is the default rate card for the endpoint behind the tool; negotiated rates apply if your account has them. \"Inputs\" are what the assistant passes; identifiers are validated with the same rules as the API, so a malformed CIN or DIN is refused before any call.\n\n### list_sandbox_entities\n\nCall this first when the account is on a test key (fsk_test_). Lists every company and director a test key can use: legal name, the brand it is known by, identifier, status, city and state for companies; name and DIN for directors. Free, on test and live keys. On a test key, find_company and find_director search only this set, and any other identifier is refused with SANDBOX_ONLY.\n\n- **Calls:** `GET /v1/sandbox`\n- **Rate:** Free\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\nNo inputs.\n\n---\n\n### find_company\n\nTurn a company name (or a CIN, FCIN or LLPIN you are unsure about) into ranked candidates with their identifier, status and registered address. Call this first whenever you only have a name; every other company tool needs the identifier it returns. On a test key it searches only the sandbox companies (see list_sandbox_entities), by legal name or brand. Billed per call at the account’s companies.resolve rate.\n\n- **Calls:** `GET /v1/companies/resolve`\n- **Rate:** ₹5 a call (`companies.resolve`)\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `query` | string | yes | Company name, or an exact CIN, FCIN or LLPIN. |\n| `state` | string | no | Narrow to a registered state, e.g. Maharashtra. |\n| `city` | string | no | Narrow to a registered city. |\n| `limit` | integer | no | How many candidates to return, 1 to 20. Default 10. |\n\n---\n\n### get_company\n\nThe company’s master data as MCA publishes it: names, status, class, capital, registered address, directors with their roles, and charges. Use for any question about what a company is; use list_filings for what it has filed and get_extraction for financial figures. Billed per call at the account’s companies.master rate. Dates in this record are MM/DD/YYYY.\n\n- **Calls:** `GET /v1/companies/{cin}`\n- **Rate:** ₹5 a call (`companies.master`)\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n| `idType` | one of `cin`, `fcin`, `llpin` | no | Set only to force tighter validation; auto-detected otherwise. |\n\n---\n\n### list_filings\n\nThe list of documents a company has filed with MCA (form, date, category, pages), paginated, with a filingId per row for get_filing_document. This is the index, not the documents. Rows are ordered by when FileSure recorded them, newest first; sort on dateOfFiling (DD/MM/YYYY) yourself for strict date order. Billed per call at the account’s companies.filings.list rate.\n\n- **Calls:** `GET /v1/companies/{cin}/filings`\n- **Rate:** ₹5 a call (`companies.filings.list`)\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n| `page` | integer | no | Page number, from 1. |\n| `limit` | integer | no | Rows per page, up to 200. Default 50. |\n| `formId` | string | no | Only this form, e.g. AOC-4, MGT-7, LLP Form 8. |\n| `year` | integer | no | Only filings for this calendar year. |\n| `documentCategory` | string | no | Only this MCA document category. |\n\n---\n\n### find_director\n\nTurn a person’s name into ranked director candidates with their DIN and current companies. Call this first when you only have a name; get_director needs the DIN it returns. On a test key it searches only the sandbox directors (see list_sandbox_entities). Billed per call at the account’s directors.resolve rate.\n\n- **Calls:** `GET /v1/directors/resolve`\n- **Rate:** ₹5 a call (`directors.resolve`)\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `query` | string | yes | Director name, or an exact 8-digit DIN. |\n| `limit` | integer | no | How many candidates to return, 1 to 20. Default 10. |\n\n---\n\n### get_director\n\nA director’s profile as MCA holds it (name, nationality, qualification, DIN status) and the companies they are associated with. Phone and email are not here; they sit behind a separate paid contact unlock that this connector does not offer. Billed per call at the account’s directors.profile rate.\n\n- **Calls:** `GET /v1/directors/{din}`\n- **Rate:** ₹5 a call (`directors.profile`)\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `din` | string | yes | Director Identification Number, 8 digits, as returned by find_director. |\n\n---\n\n### unlock_company\n\nBuy a year of access to every document this company has filed, in any year, and start the first download; extractions become readable as documents land. This costs money (₹330 by default). Call without confirm to get the account’s price and what it buys; ask the user; then call with confirm: true. Re-unlocking an unlocked company is refused free of charge.\n\n- **Calls:** `POST /v1/companies/{cin}/unlock`\n- **Rate:** ₹330 (`companies.unlock`)\n- **Kind:** paid action, asks first\n- **Results:** `success`, `quote` (without `confirm: true`), `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n| `confirm` | boolean | no | This action costs money. Leave unset to get the price and what it buys without doing anything; set true, after the user agrees, to run it. |\n\n---\n\n### get_unlock_status\n\nWhether the account holds an active unlock for this company, until when, the price of one if not, and the progress of the document download behind it (pending, in_progress, success). Free. Poll this after unlock_company or fetch_documents to know when documents and extractions are ready.\n\n- **Calls:** `GET /v1/companies/{cin}/unlock`\n- **Rate:** Free\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n\n---\n\n### get_filing_document\n\nThe PDF of one filing, by the filingId from list_filings. Needs an active unlock (otherwise returns the unlock state, free). Use it only when the user wants the source document; for any figure, prefer get_extraction, which is structured and small. PDFs over 10 MB come back as a description with size and pages instead of bytes. Billed per call at the account’s companies.filings.download rate.\n\n- **Calls:** `GET /v1/companies/{cin}/filings/{filingId}/download`\n- **Rate:** 5 paisa a call (`companies.filings.download`)\n- **Kind:** read-only\n- **Results:** `file` (the PDF), or `success` when no document is returned, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n| `filingId` | string | yes | The filingId of a row from list_filings. |\n\n---\n\n### list_extraction_forms\n\nWhich form types have structured data extracted for this company (for example AOC-4 financial statements, MGT-7 annual returns, PAS-3 allotments, charges). Start here before get_extraction. Needs an active unlock (otherwise returns the unlock state). Billed per call at the account’s companies.extractions.list rate.\n\n- **Calls:** `GET /v1/companies/{cin}/extractions`\n- **Rate:** 5 paisa a call (`companies.extractions.list`)\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n\n---\n\n### list_extraction_years\n\nFor one form type, which years have extracted data (for AOC-4 and MGT-7), or the latest snapshot and filings (PAS-3), or the per-charge summaries (charges). Use the formType names from list_extraction_forms. Needs an active unlock. Billed per call at the account’s companies.extractions.years rate.\n\n- **Calls:** `GET /v1/companies/{cin}/extractions/{formType}`\n- **Rate:** 5 paisa a call (`companies.extractions.years`)\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n| `formType` | string | yes | A form type from list_extraction_forms, e.g. AOC-4. |\n\n---\n\n### get_extraction\n\nThe structured data extracted from one filing: balance sheet, profit and loss, shareholding, allotments, and more, as JSON. Use this for any figure or fact from a filing; it is precise and small, unlike the PDF. Pick formType and year from list_extraction_years. Needs an active unlock. Billed per call at the account’s companies.extractions.data rate.\n\n- **Calls:** `GET /v1/companies/{cin}/extractions/{formType}/{year}`\n- **Rate:** 5 paisa a call (`companies.extractions.data`)\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n| `formType` | string | yes | A form type from list_extraction_forms, e.g. AOC-4. |\n| `year` | integer | yes | A year from list_extraction_years. |\n| `scope` | one of `standalone`, `consolidated` | no | For financial statements: standalone (default) or consolidated. |\n\n---\n\n### check_freshness\n\nHow current FileSure’s copy of this company is: when the record was last refreshed, when the filing list was last read from MCA, how many listed filings have no document on file, whether a refresh is running or still fresh, and the account’s unlock state. Free. Ask this before refresh_company or fetch_documents so you only pay when it is worth it.\n\n- **Calls:** `GET /v1/companies/{cin}/freshness`\n- **Rate:** Free\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n\n---\n\n### refresh_company\n\nRe-read this company’s record and filing list from MCA right now: master data, directors, common data and the list of filings. It fetches no documents. One refresh per company per 24 hours is shared by everyone, so inside that window you get the recent result. This costs money (₹1 by default). Call without confirm for the price; then with confirm: true after the user agrees. Use check_freshness first.\n\n- **Calls:** `POST /v1/companies/{cin}/update`\n- **Rate:** ₹1 (`companies.update`)\n- **Kind:** paid action, asks first\n- **Results:** `success`, `quote` (without `confirm: true`), `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n| `confirm` | boolean | no | This action costs money. Leave unset to get the price and what it buys without doing anything; set true, after the user agrees, to run it. |\n\n---\n\n### fetch_documents\n\nDownload the documents an unlocked company is still missing, typically filings made after the unlock. Needs the account’s active unlock; refused free of charge when nothing is missing. This costs money (₹150 by default). Call without confirm for the price; then with confirm: true after the user agrees. check_freshness tells you how many documents are missing.\n\n- **Calls:** `POST /v1/companies/{cin}/documents/fetch`\n- **Rate:** ₹150 (`companies.documents.fetch`)\n- **Kind:** paid action, asks first\n- **Results:** `success`, `quote` (without `confirm: true`), `error`\n\n| Input | Type | Required | Meaning |\n|---|---|---|---|\n| `companyId` | string | yes | Company identifier: CIN, FCIN or LLPIN, as returned by find_company. |\n| `confirm` | boolean | no | This action costs money. Leave unset to get the price and what it buys without doing anything; set true, after the user agrees, to run it. |\n\n---\n\n### get_account\n\nThe account’s wallet balance and its usage over the last 30 days, plus the price it pays for every endpoint. Free. Use it to answer \"what will this cost me\" and \"how much is left\" before a paid action.\n\n- **Calls:** `GET /v1/account/usage and GET /v1/account/pricing`\n- **Rate:** Free\n- **Kind:** read-only\n- **Results:** `success`, `error`\n\nNo inputs.\n\n---\n\n<!-- generated: end of connector tool pages -->\n\n## How FileSure data works\n\nFileSure gives you programmatic access to what the Ministry of Corporate Affairs (MCA) holds on every company, LLP and director in India. Everything the API returns is one of three kinds of thing, and knowing which one you are asking for tells you what it costs and whether you need to unlock anything first.\n\n![Three kinds of data and the one gate between them.](/portal/diagrams/data-tiers.svg)\n\n\n### The register: plain JSON, no unlock\n\nThe record MCA keeps on a company or director: name, status, registered address, capital, directors, charges, and the **list** of documents the company has filed. For a director: profile and the companies they sit on. This is what most integrations need, and it is just a call: ₹5, answered from what we hold, returned as JSON.\n\n### Documents: per company, behind an unlock\n\nThe filings themselves, as PDFs. MCA charges a fee to hand these over, so we do not hold every PDF for every company in advance. You **unlock** a company once (₹330), we fetch every document it has ever filed from MCA, and you can download any of them for a year. The price is for the whole history, not per year of filings.\n\n![What an unlock gives you, and for how long.](/portal/diagrams/unlock-lifecycle.svg)\n\n\n### Extractions: structured data from those documents\n\nFinancial statements, shareholding, charges and other forms, read out of the PDFs into JSON. Extractions come with the unlock: once a company's documents are in, its extractions are queryable too, at 5 paisa a call.\n\n### Time: how current is what we hold?\n\nThe register is a copy, and copies age. Three calls deal with that, and they are the only part of the API that costs money without returning data:\n\n- **Freshness check** (free) tells you how old our record is, when the filing list was last read from MCA, and how many listed filings we do not yet hold a PDF for. Ask this first; it tells you whether either of the next two is worth paying for.\n- **Refresh** (₹1) re-reads the company's record and filing list from MCA right now. It refreshes the register for everyone, which is why it costs a token ₹1 rather than a price. One refresh per company per 24 hours; if someone refreshed it before you inside that window, you get their result.\n- **Fetch new documents** (₹150) downloads the filings that appeared since your unlock. Needs your active unlock; if nothing is missing, it costs nothing.\n\nFour words, used the same way everywhere in this reference: **lookup** (read the register), **unlock** (buy a year of a company's documents), **refresh** (bring its record up to date), **fetch** (download what is missing).\n\n![The life of one company on your account.](/portal/diagrams/company-lifecycle.svg)\n\n\n---\n\n## Quickstart\n\nEverything below runs on a test key against a sandbox company, so it costs nothing. Swap in a live key and the same calls work on any company in India.\n\n**1. Turn a name into a CIN.**\n\n```bash\ncurl \"https://api.filesure.in/v1/companies/resolve?q=cars24\" \\\n  -H \"x-api-key: fsk_test_…\"\n```\n\n```json\n{\n  \"data\": { \"candidates\": [\n    { \"cin\": \"U74999HR2015FTC056386\", \"company\": \"CARS24 SERVICES PRIVATE LIMITED\", \"companyStatus\": \"Active\" }\n  ] },\n  \"meta\": { \"requestId\": \"…\", \"priceChargedPaisa\": 0, \"walletBalanceAfterPaisa\": 0 }\n}\n```\n\n**2. Read the register.**\n\n```bash\ncurl \"https://api.filesure.in/v1/companies/U74999HR2015FTC056386\" \\\n  -H \"x-api-key: fsk_test_…\"\n```\n\n```json\n{\n  \"data\": {\n    \"cin\": \"U74999HR2015FTC056386\",\n    \"company\": \"CARS24 SERVICES PRIVATE LIMITED\",\n    \"masterData\": {\n      \"companyData\": { \"companyStatus\": \"Active\", \"dateOfIncorporation\": \"08/12/2015\",\n                       \"authorisedCapital\": 100000000, \"paidupCapital\": 76934000, \"classOfCompany\": \"Private\" },\n      \"directorData\": [ { \"DIN\": \"07347299\", \"FirstName\": \"VIKRAM\", \"LastName\": \"CHOPRA\", \"dateOfAppointment\": \"08/12/2015\" } ],\n      \"indexChargesData\": [ { \"chName\": \"HDFC BANK LIMITED\", \"chargeAmount\": 5000000000, \"dateOfCreation\": \"03/15/2022\" } ]\n    }\n  },\n  \"meta\": { \"requestId\": \"…\", \"priceChargedPaisa\": 0, \"walletBalanceAfterPaisa\": 0 }\n}\n```\n\nAbridged: the real response carries every field in the MCA record, named exactly as MCA names them.\n\n**3. See what it has filed.**\n\n```bash\ncurl \"https://api.filesure.in/v1/companies/U74999HR2015FTC056386/filings?limit=3\" \\\n  -H \"x-api-key: fsk_test_…\"\n```\n\n```json\n{\n  \"data\": [\n    { \"filingId\": \"flg_…\", \"formId\": \"AOC-4\", \"dateOfFiling\": \"28/11/2025\", \"year\": 2025 },\n    { \"filingId\": \"flg_…\", \"formId\": \"MGT-7\", \"dateOfFiling\": \"27/11/2025\", \"year\": 2025 }\n  ],\n  \"meta\": { \"page\": 1, \"limit\": 3, \"total\": 654, \"requestId\": \"…\" }\n}\n```\n\nThat is the register, and for many integrations it is all you need. The `filingId` on each row is the handle for the PDF behind it; downloading one is where the unlock comes in, and the next page tells you which call to reach for.\n\n---\n\n## Which call do I need?\n\nThree questions, and every path ends at an endpoint:\n\n![Which call do I need?](/portal/diagrams/which-call.svg)\n\n\nOr, as a table:\n\n| You want to… | Call | Needs an unlock? | Cost |\n|---|---|---|---|\n| See what a test key can use | `GET /v1/sandbox` | No | Free |\n| Turn a company name into a CIN | `GET /v1/companies/resolve` | No | ₹5 |\n| Get a company's details, directors and charges | `GET /v1/companies/{cin}` | No | ₹5 |\n| See what a company has filed (the list, not the PDFs) | `GET /v1/companies/{cin}/filings` | No | ₹5 |\n| Turn a director's name into a DIN | `GET /v1/directors/resolve` | No | ₹5 |\n| Get a director's profile and companies | `GET /v1/directors/{din}` | No | ₹5 |\n| Download a filing PDF | `GET …/filings/{filingId}/download` | Yes, company | 5 paisa |\n| Get financials or other extracted data | `GET …/extractions/…` | Yes, company | 5 paisa |\n| Open a company's documents for a year | `POST /v1/companies/{cin}/unlock` | Creates one | ₹330 |\n| Know whether our copy is current | `GET /v1/companies/{cin}/freshness` | No | Free |\n| Bring a company's record up to date | `POST /v1/companies/{cin}/update` | No | ₹1 |\n| Download filings made since your unlock | `POST /v1/companies/{cin}/documents/fetch` | Yes, company | ₹150 |\n| Get a director's phone and email | `POST /v1/directors/{din}/unlock` then `GET …/contact` | Yes, director | ₹299, then 5 paisa |\n| Check your balance and usage, top up | `/v1/account/…` | No | Free |\n\nA typical first integration is three calls: resolve the name, read the master data, list the filings. If you need the PDFs or the numbers inside them, add the unlock. If you keep watching the same companies, add the freshness check and refresh.\n\n---\n\n## Keys and the sandbox\n\nEvery request carries your key in the `x-api-key` header. Keys come in two kinds and you can hold several of each:\n\n- **Live keys** (`fsk_live_…`) work on any company or director and are billed against your wallet.\n- **Test keys** (`fsk_test_…`) work only on a fixed list of well-known companies and directors, are never billed, and return the same shapes as live keys. `GET /v1/sandbox` lists them. Use them to build and test; switch the key when you go live. A test key outside the list gets `403 SANDBOX_ONLY`, and that error carries the list.\n\nCreate and revoke keys from the developer portal. Revoking a key takes effect immediately.\n\nEvery key is rate-limited: 60 requests a minute on a live key, 30 on a test key. Past that you get `429 RATE_LIMITED` with a `Retry-After` header and nothing is charged. The refresh has its own, lower ceiling, stated on its page.\n\nGenerate keys in the [Developer Portal](/portal/dashboard/keys).\n\n---\n\n## Testing with a test key\n\nA test key never reaches a company outside the sandbox, so the first call is to see what the sandbox holds. Everything below runs on a test key and costs nothing; the same calls work on a live key against any company in India.\n\n1. **See what you can use.** `GET /v1/sandbox` returns the sandbox companies (legal name, the brand each is known by, identifier, status, city and state) and directors (name and DIN).\n2. **Find the company.** `GET /v1/companies/resolve?q=zomato` searches only the sandbox on a test key, by legal name or brand, and returns Eternal Limited with its CIN. When nothing matches, the response carries a `hint` with the list's address instead of a live company you could not go on to use.\n3. **Read the record.** `GET /v1/companies/{cin}` for the master data, directors and charges.\n4. **See what it has filed.** `GET /v1/companies/{cin}/filings` for the filing index; each row carries a `filingId` for the download.\n5. **Read the numbers.** `GET /v1/companies/{cin}/extractions` lists the form types with extracted data, `…/extractions/AOC-4` the years, and `…/extractions/AOC-4/{year}` the financial statements as JSON. A test key counts as unlocked on every sandbox company, so these and `GET …/filings/{filingId}/download` answer without an unlock.\n\nIn the connector the same chain is `list_sandbox_entities`, `find_company`, `get_company`, `list_filings`, `list_extraction_forms`, `list_extraction_years`, `get_extraction`.\n\nWhat the set holds: every company has its documents on file and AOC-4 and MGT-7 data, most of them across many years. The two LLPs hold their filed documents but no extractions, because LLPs file neither form. Zepto, incorporated in 2024, has a single year of statements.\n\nA `403 SANDBOX_ONLY` on any call means the identifier is outside the sandbox. The error carries `sandboxCompanies`, `sandboxDirectors` and `nextStep`, so you can pick a working identifier from the response itself.\n\n---\n\n## Billing and the wallet\n\n![What happens to every request, and where it can be refused for free.](/portal/diagrams/request-flow.svg)\n\n\nYour account has a prepaid wallet in rupees. Every billed call deducts its price when it succeeds; a call that fails is never charged, whatever the reason. The response tells you what happened: `meta.priceChargedPaisa` is what the call cost and `meta.walletBalanceAfterPaisa` is what is left, both in paisa (₹1 = 100 paisa).\n\nPrices are per endpoint and per account. The defaults are on the rate card; if your account has negotiated rates, those apply instead. An endpoint your account has no price for returns `403 NO_ACCESS`. That is how access is controlled; there is no separate permission list.\n\nUnlocks are the one purchase that lasts: a company unlock is one year of documents and extractions for that CIN, and every download or extraction inside that year is only the per-call charge. Re-unlocking an already-unlocked company returns `409 ALREADY_UNLOCKED` and charges nothing.\n\nWhen the wallet cannot cover a call you get `402 INSUFFICIENT_BALANCE` and nothing runs. Top up from the portal or with `POST /v1/account/wallet/recharge`.\n\n---\n\n## Responses and errors\n\nEvery response is JSON with the same envelope: `{ data, meta }` on success, `{ error, meta }` on failure. `meta.requestId` is on every response and is also sent as the `X-Request-ID` header; quote it when you write to support.\n\nErrors carry a machine-readable `error.code` and a human `error.message`. A `403 NO_ACCESS` also carries `error.endpoint` and `error.catalogPricePaisa`, the default price of the endpoint you were refused, so you have a number to quote when asking for access. The codes you will meet most:\n\n| Code | Status | Meaning |\n|---|---|---|\n| `MISSING_API_KEY` / `INVALID_API_KEY` / `API_KEY_REVOKED` | 401 | No key, an unknown key, or a revoked one |\n| `INVALID_CIN` / `INVALID_DIN` / `INVALID_ID_TYPE` | 400 | The identifier (or the `idType` query value) failed format validation |\n| `NOT_FOUND` / `COMPANY_NOT_FOUND` | 404 | We do not hold that company or director |\n| `NO_ACCESS` | 403 | Your account has no price for this endpoint |\n| `SANDBOX_ONLY` | 403 | Test key used outside the sandbox; the error lists the sandbox identifiers and a `nextStep` |\n| `UNLOCK_REQUIRED` | 403 | This call needs an active unlock first |\n| `INSUFFICIENT_BALANCE` | 402 | Wallet cannot cover the call |\n| `ALREADY_UNLOCKED` | 409 | You already hold an active unlock |\n| `NOTHING_TO_FETCH` | 409 | Every listed filing already has its PDF |\n| `RATE_LIMITED` | 429 | Slow down; `Retry-After` says by how much |\n\nLists are paginated with `?page=` and `?limit=` (default 50, maximum 200). Identifiers are the 21-character CIN, the 6-character FCIN for foreign companies, the 8-character LLPIN for LLPs, and the 8-digit DIN for directors.\n\nDates arrive as MCA strings and the format depends on the source: company, director and charge records use MM/DD/YYYY (for example `dateOfIncorporation`), while filing records use DD/MM/YYYY (`dateOfFiling`). Each field's description says which. The endpoint examples abbreviate `meta`; the real response always carries `requestId`, and billed calls carry `priceChargedPaisa` and `walletBalanceAfterPaisa` as well.\n\n---\n\n## Support\n\n- **Service status**: [filesure-api.checkly-status-page.com](https://filesure-api.checkly-status-page.com) shows whether the API and the MCP connector are working, with incident updates and uptime history. Subscribe there to hear about incidents by email.\n- **Email**: [helpdesk@filesure.in](mailto:helpdesk@filesure.in)\n- **Phone**: +91 8104946419\n- **Website**: [filesure.in](https://filesure.in)\n"
  },
  "servers": [
    {
      "url": "https://api.filesure.in",
      "description": "Production"
    },
    {
      "url": "http://localhost:3000",
      "description": "Local dev (default port)"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Sandbox identifiers",
      "description": "Test API keys (`fsk_test_*`) work only on the companies, LLPs and directors\nbelow. Calls return real MCA data with no wallet deduction. Any other\nidentifier returns `403 SANDBOX_ONLY`, and that error carries these same\nlists so a caller can recover without leaving the API. Use them for\nintegration testing without spending credits.\n\nYou do not need to copy this page: `GET /v1/sandbox` returns the same\ncompanies and directors as JSON, free on either key. On a test key the name\nsearches (`GET /v1/companies/resolve`, `GET /v1/directors/resolve`) look\nonly at this set, by legal name or by the brand in the \"Known as\" column.\nThe flow is written up under [Testing with a test key](#description/testing-with-a-test-key).\n\nLive keys (`fsk_live_*`) are not restricted and follow each endpoint's\npricing behavior (billed or free, as documented per endpoint).\n\n## Sandbox CINs & LLPINs (52)\n\n| CIN | Company | Known as |\n|---|---|---|\n| U74999HR2015FTC056386 | CARS24 SERVICES PRIVATE LIMITED | Cars24 |\n| U51109KA2012PTC066107 | FLIPKART INTERNET PRIVATE LIMITED | Flipkart |\n| U62099KA2013PLC097389 | RAZORPAY SOFTWARE LIMITED | Razorpay |\n| L74900KA2015PLC082263 | MEESHO LIMITED | Meesho |\n| L33100DL2008PLC178355 | LENSKART SOLUTIONS LIMITED | Lenskart |\n| U72200KA2015PTC082063 | SORTING HAT TECHNOLOGIES PRIVATE LIMITED | Unacademy |\n| U74900GJ2015PTC107035 | OYO HOTELS AND HOMES PRIVATE LIMITED | OYO |\n| U63090GJ2012PLC107088 | ORAVEL STAYS LIMITED | OYO parent, Oravel Stays |\n| U93090MH2018PTC308253 | DREAMPLUG TECHNOLOGIES PRIVATE LIMITED | CRED |\n| U74900DL2009PTC189166 | RKSV SECURITIES INDIA PRIVATE LIMITED | Upstox |\n| U72900KA2016PTC093868 | HIVELOOP TECHNOLOGY PRIVATE LIMITED | Udaan |\n| U72900MH2007PTC171875 | SPORTA TECHNOLOGIES PRIVATE LIMITED | Dream11 |\n| U74999KA2015PTC103797 | MOHALLA TECH PRIVATE LIMITED | ShareChat |\n| U72900KA2011PTC060216 | INMOBI TECHNOLOGY SERVICES PRIVATE LIMITED | InMobi |\n| U60100MH2019PLC323444 | API HOLDINGS LIMITED | PharmEasy |\n| U72900KA2010PTC086596 | ANI TECHNOLOGIES PRIVATE LIMITED | Ola Cabs |\n| L40100KA2013PLC093769 | ATHER ENERGY LIMITED | Ather Energy |\n| U52210TG2015PTC097115 | ROPPEN TRANSPORTATION SERVICES PRIVATE LIMITED | Rapido |\n| U72900KA2011PTC060958 | VEDANTU INNOVATIONS PRIVATE LIMITED | Vedantu |\n| U74999TN2016PTC176669 | CUREFIT HEALTHCARE PRIVATE LIMITED | Cult.fit |\n| U51101MH2011PTC224903 | MANASH LIFESTYLE PRIVATE LIMITED | Purplle |\n| U52300MH2013PLC249758 | IMAGINE MARKETING LIMITED | boAt |\n| U74900KA2014PTC077652 | NOBROKER TECHNOLOGIES SOLUTIONS PRIVATE LIMITED | NoBroker |\n| L74140DL2014PLC274413 | URBAN COMPANY LIMITED | Urban Company |\n| U74999DL2018PTC331205 | RESILIENT INNOVATIONS PRIVATE LIMITED | BharatPe |\n| U74110KA2016PTC120161 | ACKO TECHNOLOGY & SERVICES PRIVATE LIMITED | Acko |\n| U74999KA2018FTC113333 | GALACTUS FUNWARE TECHNOLOGY PRIVATE LIMITED | MPL |\n| U74140MH2019PTC328769 | AMICA FINANCIAL TECHNOLOGIES PRIVATE LIMITED | Jupiter |\n| U80902MH2012PTC258559 | UPGRAD EDUCATION PRIVATE LIMITED | upGrad |\n| U24299DL2021PTC380760 | GLOBALBEES BRANDS PRIVATE LIMITED | GlobalBees |\n| U66000MH2013PTC249565 | TURTLEMINT INSURANCE BROKING SERVICES PRIVATE LIMITED | Turtlemint |\n| U74999MH2012PTC237035 | LEADERSHIP BOULEVARD PRIVATE LIMITED | LEAD School |\n| U74130KA2010PTC052192 | INNOVATIVE RETAIL CONCEPTS PRIVATE LIMITED | BigBasket |\n| U51909KA2011PTC060707 | SUPERMARKET GROCERY SUPPLIES PRIVATE LIMITED | BigBasket supply arm |\n| U62099KA2024PTC194937 | KIRANAKART SOFTWARE SOLUTIONS PRIVATE LIMITED | Zepto |\n| U65999DL2019FTC353020 | PINE LABS FINANCE PRIVATE LIMITED | Pine Labs |\n| U74900KA2015PTC080321 | DELIGHTFUL GOURMET PRIVATE LIMITED | Licious |\n| U28100KA2020PTC135505 | ZETWERK FABPLUS PRIVATE LIMITED | Zetwerk |\n| U74900TG2015PTC101793 | DARWINBOX DIGITAL SOLUTIONS PRIVATE LIMITED | Darwinbox |\n| U72900DL2018PTC331409 | POSTMAN MEDIA PRIVATE LIMITED | Postman |\n| U74140GJ2015PLC154393 | OFB TECH LIMITED | OfBusiness |\n| U65990DL2022PTC401899 | OXYZO FINVEST PRIVATE LIMITED | Oxyzo |\n| U72900TN2020PTC137251 | CREDAVENUE PRIVATE LIMITED | Yubi, formerly CredAvenue |\n| U67200KA2017PTC166507 | OPEN FINANCIAL TECHNOLOGIES PRIVATE LIMITED | Open |\n| U72900KA2015PTC080871 | GARAGEPRENEURS INTERNET PRIVATE LIMITED | slice |\n| L93030DL2010PLC198141 | ETERNAL LIMITED | Eternal, formerly Zomato |\n| L74110KA2013PLC096530 | SWIGGY LIMITED | Swiggy |\n| L52600MH2012PLC230136 | FSN E-COMMERCE VENTURES LIMITED | Nykaa |\n| L72200DL2000PLC108985 | ONE 97 COMMUNICATIONS LIMITED | Paytm |\n| L63090DL2011PLC221234 | DELHIVERY LIMITED | Delhivery |\n| ACK-2998 | SUGEE TWENTY SEVEN DEVELOPERS LLP |  |\n| ACX-7976 | ZALPE FOOD & BEVERAGES LLP |  |\n\n## Sandbox DINs (451)\n\nDerived from the directors of the sandbox CINs above.\n\n| DIN | DIN | DIN | DIN | DIN | DIN |\n|---|---|---|---|---|---|\n| 00002157 | 00002615 | 00002803 | 00003423 | 00003633 | 00003882 |\n| 00004223 | 00004771 | 00006486 | 00007347 | 00008886 | 00010499 |\n| 00012214 | 00012870 | 00013580 | 00017880 | 00017944 | 00018234 |\n| 00022157 | 00024141 | 00031034 | 00036043 | 00037022 | 00040491 |\n| 00040789 | 00046081 | 00054553 | 00056826 | 00058105 | 00059201 |\n| 00059877 | 00062650 | 00065640 | 00067073 | 00074964 | 00108347 |\n| 00109854 | 00118188 | 00118324 | 00125058 | 00133351 | 00162957 |\n| 00177699 | 00187429 | 00222708 | 00253613 | 00272372 | 00281547 |\n| 00307229 | 00322784 | 00337276 | 00361030 | 00381741 | 00394065 |\n| 00405142 | 00466521 | 00507827 | 00508259 | 00521511 | 00555052 |\n| 00570124 | 00644360 | 00677638 | 00677965 | 00706336 | 00754512 |\n| 00766821 | 00863123 | 00871445 | 01049871 | 01096264 | 01099294 |\n| 01113742 | 01164185 | 01173669 | 01237902 | 01243445 | 01338251 |\n| 01338477 | 01384344 | 01388140 | 01432123 | 01449885 | 01461055 |\n| 01469375 | 01494407 | 01592796 | 01653176 | 01679598 | 01730685 |\n| 01755822 | 01797971 | 01802995 | 01827653 | 01837379 | 01874769 |\n| 01893686 | 01902890 | 01913013 | 01930079 | 01947911 | 02005518 |\n| 02014353 | 02040991 | 02046291 | 02057007 | 02069428 | 02070081 |\n| 02092948 | 02102783 | 02122751 | 02124077 | 02126100 | 02131404 |\n| 02132315 | 02144558 | 02159016 | 02175753 | 02181034 | 02227607 |\n| 02242466 | 02249682 | 02339751 | 02356492 | 02376801 | 02442753 |\n| 02466181 | 02470016 | 02499607 | 02528942 | 02590433 | 02613583 |\n| 02670178 | 02741174 | 02748363 | 02844650 | 02848515 | 02853367 |\n| 02853403 | 02870609 | 02945481 | 02968574 | 02993708 | 03024803 |\n| 03090626 | 03090814 | 03098172 | 03103474 | 03118947 | 03145392 |\n| 03172733 | 03258070 | 03266967 | 03284823 | 03287473 | 03328890 |\n| 03341028 | 03399650 | 03404629 | 03430136 | 03431848 | 03440936 |\n| 03441515 | 03450221 | 03488061 | 03523267 | 03534101 | 03545900 |\n| 03549431 | 03559152 | 03565167 | 03566737 | 03579584 | 03579776 |\n| 03581311 | 03584898 | 03604399 | 03605392 | 03617181 | 05002534 |\n| 05014753 | 05116855 | 05131571 | 05132272 | 05132286 | 05138366 |\n| 05169635 | 05177838 | 05185378 | 05186193 | 05192249 | 05195656 |\n| 05223910 | 05244077 | 05251806 | 05277865 | 05318899 | 05323714 |\n| 05323737 | 05325285 | 05325741 | 05328267 | 05336659 | 05341082 |\n| 06364184 | 06371682 | 06392463 | 06449636 | 06454495 | 06502272 |\n| 06512080 | 06527810 | 06549915 | 06552579 | 06556746 | 06557158 |\n| 06557679 | 06575810 | 06594510 | 06610582 | 06618646 | 06652017 |\n| 06659730 | 06660799 | 06661731 | 06663764 | 06666246 | 06672135 |\n| 06680073 | 06682759 | 06686145 | 06732021 | 06735472 | 06754654 |\n| 06764019 | 06794418 | 06796621 | 06798956 | 06824179 | 06848801 |\n| 06891864 | 06912294 | 06940578 | 06946611 | 06998824 | 06999772 |\n| 07002169 | 07005029 | 07005033 | 07005253 | 07013113 | 07018743 |\n| 07018744 | 07019019 | 07031462 | 07031464 | 07082038 | 07106615 |\n| 07107975 | 07121539 | 07121802 | 07129633 | 07135817 | 07168514 |\n| 07197443 | 07202923 | 07203452 | 07206780 | 07209950 | 07219194 |\n| 07221836 | 07225910 | 07238872 | 07245972 | 07248661 | 07248672 |\n| 07251075 | 07254037 | 07298703 | 07304038 | 07312305 | 07315528 |\n| 07318865 | 07323472 | 07333270 | 07337772 | 07339751 | 07339752 |\n| 07406331 | 07434021 | 07439364 | 07485688 | 07505290 | 07517101 |\n| 07553913 | 07582619 | 07596310 | 07630166 | 07634689 | 07639288 |\n| 07661578 | 07696873 | 07720350 | 07736862 | 07756379 | 07767248 |\n| 07779526 | 07806792 | 07820090 | 07825610 | 07847243 | 07868696 |\n| 07878167 | 07929995 | 07931382 | 07948982 | 07955350 | 07972892 |\n| 07984221 | 07986644 | 08006199 | 08073534 | 08087425 | 08090416 |\n| 08090417 | 08113520 | 08137143 | 08154941 | 08166016 | 08174465 |\n| 08178251 | 08189873 | 08222884 | 08223390 | 08225312 | 08225313 |\n| 08239898 | 08277445 | 08284722 | 08303261 | 08343545 | 08351358 |\n| 08354909 | 08355220 | 08383621 | 08407641 | 08417798 | 08501575 |\n| 08505775 | 08507514 | 08524150 | 08658846 | 08661466 | 08682099 |\n| 08712047 | 08736307 | 08742229 | 08743508 | 08776136 | 08780334 |\n| 08780335 | 08808558 | 08821475 | 08839209 | 08908841 | 08935969 |\n| 08950500 | 08959036 | 09043859 | 09075331 | 09092519 | 09114153 |\n| 09129636 | 09136934 | 09155801 | 09166446 | 09196992 | 09218485 |\n| 09247644 | 09258341 | 09298721 | 09365919 | 09367772 | 09376632 |\n| 09389414 | 09398202 | 09408470 | 09431299 | 09434542 | 09440372 |\n| 09471450 | 09475452 | 09490014 | 09500698 | 09521316 | 09577436 |\n| 09577495 | 09580591 | 09588432 | 09632942 | 09637916 | 09660723 |\n| 09748791 | 09749539 | 09813415 | 09817635 | 10041633 | 10044673 |\n| 10049059 | 10056096 | 10061648 | 10090589 | 10105558 | 10197152 |\n| 10209423 | 10214230 | 10237124 | 10243913 | 10411559 | 10427117 |\n| 10462333 | 10475712 | 10511184 | 10511270 | 10589911 | 10593910 |\n| 10656028 | 10712707 | 10720049 | 10775163 | 10939877 | 11056907 |\n| 11061694 | 11077148 | 11086018 | 11116635 | 11222871 | 11304281 |\n| 11335707 | 11382912 | 11544170 | 11544199 | 11583385 | 11611722 |\n| 11620355 | 11632627 | 11692470 | 11692471 | 11692472 | 11745292 |\n| 11767043 |\n"
    },
    {
      "name": "Look up the register",
      "description": "The record MCA holds on a company or director, as plain JSON. Resolve a name to an identifier, read master data, directors and charges, or list what a company has filed. ₹5 a call, no unlock needed."
    },
    {
      "name": "Documents and financials",
      "description": "The filing PDFs and the data extracted from them. Unlock a company once (₹330 for every document it has filed, in any year; access lasts one year) and the first download runs; then download any filing and read any extraction for 5 paisa a call. Filings made after the unlock are picked up under Keep a company current."
    },
    {
      "name": "Keep a company current",
      "description": "How current is our copy of a company, and what to do about it. The freshness check is free; a refresh (₹1) re-reads the record and the filing list from MCA; a document fetch (₹150) downloads the listed filings still missing a PDF."
    },
    {
      "name": "Director contact",
      "description": "A director's phone and email, behind a separate per-director unlock (₹299 by default for new accounts; access lasts one year), then read for 5 paisa a call."
    },
    {
      "name": "Your account",
      "description": "Wallet balance and usage, the wallet ledger, top-ups, your billing profile and GST invoices. All free, on live and test keys alike."
    }
  ],
  "paths": {
    "/v1/sandbox": {
      "get": {
        "tags": [
          "Sandbox identifiers"
        ],
        "summary": "List the sandbox companies and directors",
        "description": "**What it returns**\n\nEvery company and director a test key can use. For companies: the legal name, the brand it is known by (`knownAs`, `null` when there is none), the identifier and its type, status, city and state, sorted by name. For directors: name and DIN, sorted by DIN. The same lists appear in the \"Sandbox identifiers\" section of this reference and inside every `403 SANDBOX_ONLY` error.\n\n**Billing**\n\nFree on test and live keys. Nothing is written to your usage.\n\n**Sandbox behavior**\n\nThis is the sandbox. On a test key, call it first: `GET /v1/companies/resolve` and `GET /v1/directors/resolve` search only what it lists, and every other endpoint refuses identifiers that are not here.\n\n**Common errors**\n\n- `401 MISSING_API_KEY` / `INVALID_API_KEY`: no key, or an unknown one\n",
        "operationId": "listSandboxEntities",
        "responses": {
          "200": {
            "description": "The sandbox companies and directors",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxEntitiesResponse"
                },
                "examples": {
                  "sandbox": {
                    "summary": "Two of each (the real response carries the whole set)",
                    "value": {
                      "data": {
                        "companies": [
                          {
                            "cin": "U74999HR2015FTC056386",
                            "company": "CARS24 SERVICES PRIVATE LIMITED",
                            "knownAs": "Cars24",
                            "idType": "cin",
                            "companyStatus": "Active",
                            "city": "Gurugram",
                            "state": "Haryana"
                          },
                          {
                            "cin": "L93030DL2010PLC198141",
                            "company": "ETERNAL LIMITED",
                            "knownAs": "Eternal, formerly Zomato",
                            "idType": "cin",
                            "companyStatus": "Active",
                            "city": "NEW DELHI",
                            "state": "Delhi"
                          }
                        ],
                        "directors": [
                          {
                            "din": "11692470",
                            "fullName": "RAHUL MANIKRAO ZALPE"
                          },
                          {
                            "din": "11692472",
                            "fullName": "NILESH KASHINATH HIWALE"
                          }
                        ]
                      },
                      "meta": {
                        "companies": 52,
                        "directors": 451,
                        "requestId": "…"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/companies/resolve": {
      "get": {
        "tags": [
          "Look up the register"
        ],
        "summary": "Resolve company name to CIN",
        "description": "**What it returns**\n\nRanked CIN candidates for a free-text company name (or a single hit when `q` is already a valid CIN/FCIN/LLPIN). Each candidate carries inline disambiguation fields — registered address, status, incorporation date, current directors/promoters, and NIC/activity code — plus a Typesense `matchScore` (higher = better).\n\nOptional `state` and `city` query filters narrow results to companies whose registered address matches.\n\n**Billing**\n\nBilled per call at your `companies.resolve` rate (see the [rate card](/pricing.html)).\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) are free and search only the sandbox companies: by legal name, by the brand the company is known by, or by exact identifier; `state` and `city` still filter. The response carries `sandbox: true`, and when nothing matches, a `hint` pointing at `GET /v1/sandbox`. A company outside the sandbox is never returned to a test key, because every other endpoint would then refuse it.\n\n**Common errors**\n\n- `400 MISSING_QUERY` — `q` (or `name`) is required\n- `503 SEARCH_UNAVAILABLE` — name search requires Typesense; exact CIN lookups still work\n",
        "operationId": "resolveCompany",
        "parameters": [
          {
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Company name or exact CIN/FCIN/LLPIN. Alias `name` is also accepted."
          },
          {
            "in": "query",
            "name": "name",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Alias for `q`."
          },
          {
            "in": "query",
            "name": "state",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by registered state (e.g. `Maharashtra`)."
          },
          {
            "in": "query",
            "name": "city",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by registered city."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 10
            },
            "description": "Maximum number of candidates to return."
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked resolve results (may be an empty `candidates` array)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyResolveResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "503": {
            "description": "Name search backend unavailable"
          }
        }
      }
    },
    "/v1/companies/{cin}": {
      "get": {
        "tags": [
          "Look up the register"
        ],
        "summary": "Get company master data",
        "description": "**What it returns**\n\nThe full MCA master-data packet for a company:\n\n- `companyData`: the MCA master record (registration, type/category/class, capital, status, dates, registered/correspondence addresses)\n- `commonData`: MCA's supplementary record (NIC industry codes, AGM date, balance-sheet date). May be `null` if it has not been fetched yet\n- `directorData[]`: the directors of this company. Rows deduped by DIN; `MCAUserRole[]` arrays merged, with a small drop list applied\n- `indexChargesData[]`: charges (mortgages) on this company, verbatim. Empty `[]` is common (most companies have none)\n\nFields are surfaced **as MCA returns them** (camelCase, British spellings like `authorisedCapital`, PascalCase charge addresses); fields are only ever dropped, never renamed. The one addition: the three capital amounts (`paidUpCapital`, `authorisedCapital`, `subscribedCapital`) each carry readable companions beside the raw number — a `…Formatted` compact form (e.g. `₹7.69 Cr`) and a `…Display` full form with Indian digit grouping (e.g. `₹7,69,34,000`). The raw integers are unchanged; the ₹ sign carries the currency. **Address filtering:** only `Registered Address` and `Correspondence Address` are kept; auxiliary address types are dropped. Identifiers supported: 21-char **CIN**, 6-char **FCIN** (foreign), 8-char **LLPIN**. The `?idType=` query param is optional; auto-detect handles all three.\n\n**Billing**\n\nBilled per call against your INR wallet at the rate in your pricing row for this endpoint.\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) work freely on sandbox-whitelisted CINs/LLPINs (no wallet deduction). Outside the whitelist, test keys return `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — identifier failed CIN/FCIN/LLPIN format validation\n- `404` — company not found in our cache. The unlock endpoint won't help here either — it requires the CIN to already be in master data. If you need a specific CIN added (or you suspect ours is stale relative to MCA), contact [helpdesk@filesure.in](mailto:helpdesk@filesure.in).\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [List company filings](#tag/look-up-the-register/GET/v1/companies/{cin}/filings)\n- [List extracted form types](#tag/documents-and-financials/GET/v1/companies/{cin}/extractions)\n- [Unlock a company](#tag/documents-and-financials/POST/v1/companies/{cin}/unlock)\n",
        "operationId": "getCompanyMaster",
        "parameters": [
          {
            "$ref": "#/components/parameters/CompanyIdentifierPath"
          },
          {
            "in": "query",
            "name": "idType",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "cin",
                "fcin",
                "llpin"
              ]
            },
            "description": "Optional. Tighter validation when set; auto-detect when omitted."
          }
        ],
        "responses": {
          "200": {
            "description": "Master data found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyMasterDataResponse"
                },
                "examples": {
                  "cinSuccess": {
                    "summary": "Sandbox CIN — CARS24 (registered company)",
                    "value": {
                      "data": {
                        "cin": "U74999HR2015FTC056386",
                        "company": "CARS24 SERVICES PRIVATE LIMITED",
                        "cinHistory": [],
                        "nameHistory": [],
                        "masterData": {
                          "companyData": {
                            "cin": "U74999HR2015FTC056386",
                            "companyName": "CARS24 SERVICES PRIVATE LIMITED",
                            "companyType": "Company limited by Shares",
                            "companyOrigin": "Indian Non-Government Company",
                            "companyCategory": "Company limited by Shares",
                            "companySubcategory": "Non-government company",
                            "classOfCompany": "Private",
                            "dateOfIncorporation": "08/12/2015",
                            "authorisedCapital": 100000000,
                            "paidupCapital": 76934000,
                            "numberOfMembers": "0",
                            "activeCompliance": "ACTIVE compliant",
                            "companyStatus": "Active",
                            "whetherListedOrNot": "Unlisted",
                            "MCAMDSCompanyAddress": [
                              {
                                "addressType": "Registered Address",
                                "streetAddress": "Plot No. 78, Sector 44, Gurugram, Haryana, 122001",
                                "country": "India"
                              }
                            ]
                          },
                          "commonData": {
                            "mainDivisionCode": "74",
                            "mainDivisionDescription": "Other professional, scientific and technical activities",
                            "companyAddress": [
                              {
                                "addressType": "Registered Address",
                                "streetAddress": "Plot No. 78, Sector 44, Gurugram, Haryana, 122001"
                              }
                            ]
                          },
                          "directorData": [
                            {
                              "DIN": "07347299",
                              "PAN": "ABCPK1234E",
                              "FirstName": "VIKRAM",
                              "LastName": "CHOPRA",
                              "dateOfAppointment": "08/12/2015",
                              "DirectorDisqualified": "false",
                              "MCAUserRole": [
                                {
                                  "role": "Director",
                                  "designation": "Director",
                                  "cin": "U74999HR2015FTC056386",
                                  "kmpFlag": "false"
                                }
                              ]
                            }
                          ],
                          "indexChargesData": [
                            {
                              "chargeId": "100123456",
                              "chName": "HDFC BANK LIMITED",
                              "chargeAmount": 5000000000,
                              "dateOfCreation": "03/15/2022",
                              "dateOfModification": null,
                              "dateOfSatisfaction": null,
                              "StreetAddress": "HDFC Bank House, Senapati Bapat Marg, Lower Parel, Mumbai",
                              "City": "Mumbai",
                              "State": "Maharashtra",
                              "PostalCode": "400013",
                              "Country": "India"
                            }
                          ]
                        }
                      },
                      "meta": {
                        "requestId": "…",
                        "createdAt": "2023-04-12T07:18:32.444Z",
                        "updatedAt": "2026-04-28T03:21:09.001Z"
                      }
                    }
                  },
                  "llpinSuccess": {
                    "summary": "Sandbox LLPIN — shape demo",
                    "value": {
                      "data": {
                        "cin": "ACK-2998",
                        "company": "SUGEE TWENTY SEVEN DEVELOPERS LLP",
                        "cinHistory": [],
                        "nameHistory": [],
                        "masterData": {
                          "companyData": {
                            "cin": "ACK-2998",
                            "companyName": "SUGEE TWENTY SEVEN DEVELOPERS LLP",
                            "companyType": "Limited Liability Partnership",
                            "dateOfIncorporation": "11/11/2024",
                            "numberOfPartners": "2",
                            "numberOfDesignatedPartners": "2",
                            "companyStatus": "Active"
                          },
                          "commonData": null,
                          "directorData": null,
                          "indexChargesData": []
                        }
                      },
                      "meta": {
                        "requestId": "…",
                        "createdAt": "2023-08-22T14:12:08.901Z",
                        "updatedAt": "2026-04-15T11:42:30.004Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidCompanyIdentifier"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/NoAccess"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/companies/{cin}/filings": {
      "get": {
        "tags": [
          "Look up the register"
        ],
        "summary": "List company filings",
        "description": "**What it returns**\n\nPaginated list of MCA filings for this company (offset-based, default `limit=50`, max `200`). Filterable by `formId` (e.g. `MGT-7`, `LLP Form 8`, `AOC-4 XBRL`), `year`, and `documentCategory`. Each row carries MCA fields verbatim — `formId`, `documentCategory`, `dateOfFiling` (DD/MM/YYYY string), `fileSize`, `fileType`, `numberOfPages`, etc. Each row also carries an opaque `filingId` token (`flg_…`); pass it as the path param to the download endpoint. The MCA `documentCode` is deliberately not surfaced. Rows are ordered by when we recorded them, newest first; that usually follows the filing date but is not guaranteed, so sort on `dateOfFiling` yourself when strict date order matters.\n\nDate-range filtering is not supported (because `dateOfFiling` is stored as a DD/MM/YYYY string). Use `?year=` to narrow by calendar year.\n\n**Billing**\n\nBilled per call. The list itself is just metadata — the actual PDF retrieval is a separate unlock-gated download per filing.\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) work freely on sandbox-whitelisted CINs/LLPINs. Real filings list returned, no wallet deduction. Outside the whitelist: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — identifier failed CIN/FCIN/LLPIN format validation\n- `400 INVALID_ID_TYPE` — `?idType=` set to a value outside the enum\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [Get company master data](#tag/look-up-the-register/GET/v1/companies/{cin})\n- [Download filing PDF](#tag/documents-and-financials/GET/v1/companies/{cin}/filings/{filingId}/download)\n- [Unlock a company](#tag/documents-and-financials/POST/v1/companies/{cin}/unlock) (required before PDFs are downloadable)\n",
        "operationId": "listCompanyFilings",
        "parameters": [
          {
            "$ref": "#/components/parameters/CompanyIdentifierPath"
          },
          {
            "in": "query",
            "name": "idType",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "cin",
                "fcin",
                "llpin"
              ]
            },
            "description": "Optional. Tighter validation when set; auto-detect when omitted. `INVALID_ID_TYPE` 400 when set to anything outside the enum."
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 200
            }
          },
          {
            "in": "query",
            "name": "formId",
            "description": "Exact match against the MCA `formId` field.",
            "schema": {
              "type": "string"
            },
            "example": "MGT-7"
          },
          {
            "in": "query",
            "name": "year",
            "description": "Exact match against the integer `year` field on the filing doc.",
            "schema": {
              "type": "integer"
            },
            "example": 2024
          },
          {
            "in": "query",
            "name": "documentCategory",
            "description": "Exact match against the MCA `documentCategory` field.",
            "schema": {
              "type": "string"
            },
            "example": "Annual Returns and Balance Sheet eForms"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of filings (empty `data` array if the company has no filings or doesn't exist).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilingsListResponse"
                },
                "examples": {
                  "paginated": {
                    "summary": "Sandbox CIN — first 3 filings (truncated)",
                    "description": "Real CARS24 has 653 filings; example shows the first 3 of page 1. Pagination uses `meta.page`, `meta.limit`, `meta.total`, `meta.totalPages`.",
                    "value": {
                      "data": [
                        {
                          "filingId": "flg_Ui2a1vItyyFYoAGGmefipN0RoT9EtmjHQz4KfzMeVE",
                          "formId": "AOC-4",
                          "documentCategory": "Annual Returns and Balance Sheet eForms",
                          "attachmentLabel": "AOC-4",
                          "dateOfFiling": "30/09/2024",
                          "year": 2024,
                          "fileSize": 412050,
                          "fileType": "pdf",
                          "numberOfPages": 24,
                          "description": null,
                          "createdAt": "2024-10-01T03:14:22.000Z",
                          "updatedAt": "2024-10-01T03:14:22.000Z"
                        },
                        {
                          "filingId": "flg_eK4hXp82mZQyaBcDeFgHiJkLmNoPqRsTuVwXyZ",
                          "formId": "MGT-7",
                          "documentCategory": "Annual Returns and Balance Sheet eForms",
                          "attachmentLabel": "MGT-7",
                          "dateOfFiling": "30/09/2024",
                          "year": 2024,
                          "fileSize": 318220,
                          "fileType": "pdf",
                          "numberOfPages": 18,
                          "description": null,
                          "createdAt": "2024-10-01T03:14:25.000Z",
                          "updatedAt": "2024-10-01T03:14:25.000Z"
                        },
                        {
                          "filingId": "flg_Q3vRtY8nWxZpLkMjNbVcXdSeFhJuKiOoPaSdF",
                          "formId": "CHG-9",
                          "documentCategory": "Charge Documents",
                          "attachmentLabel": "optional_attachment",
                          "dateOfFiling": "30/09/2021",
                          "year": 2021,
                          "fileSize": 636790,
                          "fileType": "pdf",
                          "numberOfPages": 36,
                          "description": null,
                          "createdAt": "2021-10-02T11:48:09.000Z",
                          "updatedAt": "2021-10-02T11:48:09.000Z"
                        }
                      ],
                      "meta": {
                        "page": 1,
                        "limit": 20,
                        "total": 653,
                        "totalPages": 33
                      }
                    }
                  },
                  "empty": {
                    "summary": "Company with no filings",
                    "value": {
                      "data": [],
                      "meta": {
                        "page": 1,
                        "limit": 50,
                        "total": 0,
                        "totalPages": 0
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/NoAccess"
          }
        }
      }
    },
    "/v1/directors/resolve": {
      "get": {
        "tags": [
          "Look up the register"
        ],
        "summary": "Resolve director name to DIN",
        "description": "**What it returns**\n\nRanked DIN candidates for a free-text director name (or a single hit when `q` is already an 8-digit DIN). Each candidate includes status, associated company names, directorship count, and a Typesense `matchScore`.\n\n**Billing**\n\nBilled per call at your `directors.resolve` rate (see the [rate card](/pricing.html)).\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) are free and search only the sandbox directors, by name or exact DIN. The response carries `sandbox: true`, and when nothing matches, a `hint` pointing at `GET /v1/sandbox`.\n\n**Common errors**\n\n- `400 MISSING_QUERY` — `q` (or `name`) is required\n- `503 SEARCH_UNAVAILABLE` — name search requires Typesense; exact DIN lookups still work\n",
        "operationId": "resolveDirector",
        "parameters": [
          {
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Director name or exact 8-digit DIN. Alias `name` is also accepted."
          },
          {
            "in": "query",
            "name": "name",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Alias for `q`."
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 10
            },
            "description": "Maximum number of candidates to return."
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked resolve results (may be an empty `candidates` array)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DirectorResolveResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "503": {
            "description": "Name search backend unavailable"
          }
        }
      }
    },
    "/v1/directors/{din}": {
      "get": {
        "tags": [
          "Look up the register"
        ],
        "summary": "Get director profile",
        "description": "**What it returns**\n\nThe director's identity (DIN, name), the verbatim MCA `companyData[]` array (the per-company role records MCA returns for a DIN) and `mcaSignatoryCessationMasterHistory[]`, the appointment/cessation ledger for past company roles (each row: `cin`, `accountName`, `designation`, `appointmentDate`, `cessationDate`, and usually `accountStatus`). Use history when `companyData[]` is empty or lacks cessation dates.\n\nEach `companyData[]` row carries MCA-shaped fields (`ucin`, `cin_LLPIN`, `nameOfTheCompany`, `role`, `designation`, `directorFlag`, `companyStatus`, `roleEffectiveDate`, `cessationDate`, plus LLP-specific contribution fields and body-corporate metadata).\n\nContact-tier fields are deliberately **excluded** here — query [GET /v1/directors/{din}/contact](#tag/director-contact/GET/v1/directors/{din}/contact) for those (separate unlock):\n\n`pan`, `aadhaarNumber`, `mobileNumber`, `emailAddress`, `passportNumber`, `dob`, `birthPlace`, `drivingLicenseNumber`, `votersIdNumber`, `addresses`, `fathersFirstName`/`Middle`/`Last`. Dropped both at the top level and within each `companyData[]` and `mcaSignatoryCessationMasterHistory[]` row.\n\nPer-row drops (both arrays): FileSure/MCA-internal IDs (`accountId`, `userId`, `userName`, `approverId`, `companyId`, `srn`, `v2UserId`, `bodyCorpInsideIndiaId`, `bodyCorpOutsideIndiaId`), duplicates of top-level director identity (`din` — always the DIN in the path, returned once as `data.din` — plus `firstName`, `middleName`, `lastName`, `gender`, `nationality`, `educationalQualification`), operational flags (`flagged`, `oldFlag`). Everything else passes through verbatim — MCA naming, no flattened display structures.\n\n**Billing**\n\nBilled per call.\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) work freely on sandbox-whitelisted DINs. Outside the whitelist: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_DIN` — DIN failed 8-digit format validation\n- `404` — director not found in our cache\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [Get director contact](#tag/director-contact/GET/v1/directors/{din}/contact) (unlock-gated; PII fields)\n- [Unlock director's contact](#tag/director-contact/POST/v1/directors/{din}/unlock)\n- [Get company master data](#tag/look-up-the-register/GET/v1/companies/{cin})\n",
        "operationId": "getDirectorMaster",
        "parameters": [
          {
            "$ref": "#/components/parameters/DinPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Director master data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DirectorMasterDataResponse"
                },
                "examples": {
                  "cars24Director": {
                    "summary": "Sandbox DIN — 1 company role (truncated)",
                    "description": "Real directors typically sit on 2–10 companies; example shows 1 representative `companyData[]` row.",
                    "value": {
                      "data": {
                        "din": "00002157",
                        "firstName": "AJAY",
                        "lastName": "VERMA",
                        "gender": "MALE",
                        "nationality": "India",
                        "educationalQualification": "Graduate",
                        "companyData": [
                          {
                            "ucin": "U74999HR2015FTC056386",
                            "cin_LLPIN": "U74999HR2015FTC056386",
                            "nameOfTheCompany": "CARS24 SERVICES PRIVATE LIMITED",
                            "role": "Director",
                            "designation": "Director",
                            "directorFlag": "true",
                            "companyStatus": "Active",
                            "roleEffectiveDate": "2015-02-02",
                            "cessationDate": null
                          }
                        ]
                      },
                      "meta": {
                        "updatedAt": "2026-04-15T11:42:30.004Z",
                        "source": "MCA"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidDin"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/NoAccess"
          },
          "404": {
            "$ref": "#/components/responses/DirectorNotFound"
          }
        }
      }
    },
    "/v1/companies/{cin}/unlock": {
      "post": {
        "tags": [
          "Documents and financials"
        ],
        "summary": "Unlock a company",
        "description": "**What it returns**\n\nOn a live key with an active pricing row: `202 Accepted` with the freshly-created unlock record (1-year expiry). The `data.job` field is `null` immediately after the POST — the background refresh job hasn't been registered yet. Poll [GET /v1/companies/{cin}/unlock](#tag/documents-and-financials/GET/v1/companies/{cin}/unlock) seconds later and the response will carry a populated `job` object whose `processingStages` track the asynchronous download + extraction. On a `fsk_test_*` key with a sandbox-whitelisted CIN: `200 OK` with a synthetic unlock and `job: null` — no real writes, no MCA fetch.\n\n**What happens next.** The unlock starts the first document download. Poll [GET /v1/companies/{cin}/unlock](#tag/documents-and-financials/GET/v1/companies/{cin}/unlock) for progress (`processingStages.documentDownloadV3.status` goes `pending` → `in_progress` → `success`); downloads and extractions work as documents land, and the window lasts one year. How the unlock relates to the refresh and the document fetch is explained in [How FileSure data works](#description/how-filesure-data-works).\n\n**Idempotency:** repeating this on a CIN with an active unlock returns `409 ALREADY_UNLOCKED` with the existing unlock's expiry; no double charge.\n\n**Billing**\n\nPay-gate. Charges the company-unlock fee from your wallet up front: your `companies.unlock` rate (see the [rate card](/pricing.html)). Wallet must have sufficient balance; otherwise `402 INSUFFICIENT_BALANCE` with no unlock created.\n\n**Sandbox behavior**\n\n`fsk_test_*` keys on a sandbox-whitelisted CIN return `200 OK` with a synthetic unlock (`{ unlocked: true, sandbox: true, job: null }`) and skip all real writes / MCA fetches. Test keys on non-sandbox CINs return `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — CIN/FCIN/LLPIN format validation failed\n- `402 INSUFFICIENT_BALANCE` — wallet under the unlock price\n- `403 NO_ACCESS` — no pricing row for `companies.unlock`\n- `403 SANDBOX_ONLY` — test key on a non-sandbox CIN\n- `404` — CIN not in our master-data cache\n- `409 ALREADY_UNLOCKED` — unlock already exists; no double charge\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [Cascade diagram](#description/how-filesure-data-works) (visual: POST → wallet deduct → background refresh → filings/extractions queryable)\n- [Get unlock status](#tag/documents-and-financials/GET/v1/companies/{cin}/unlock) (poll job progress + grab zip URLs)\n- [Download filing PDF](#tag/documents-and-financials/GET/v1/companies/{cin}/filings/{filingId}/download)\n- [Get extracted data](#tag/documents-and-financials/GET/v1/companies/{cin}/extractions/{formType}/{year})\n",
        "operationId": "unlockCompany",
        "parameters": [
          {
            "$ref": "#/components/parameters/CinPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Sandbox synthetic unlock (test key on a sandbox CIN).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnlockResponse"
                },
                "examples": {
                  "sandboxSynthetic": {
                    "summary": "Test key on a sandbox CIN — synthetic unlock (no real writes)",
                    "value": {
                      "data": {
                        "cin": "U74999HR2015FTC056386",
                        "unlocked": true,
                        "unlockedAt": null,
                        "expiresAt": null,
                        "sandbox": true,
                        "job": null
                      },
                      "meta": {}
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Unlock created; download + extraction job queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnlockResponse"
                },
                "examples": {
                  "firstUnlock": {
                    "summary": "Live key — unlock created, job queued (job materialises seconds later)",
                    "description": "Right after POST, `data.job` is `null` because the background refresh hasn't been registered yet. Poll [GET /v1/companies/{cin}/unlock](#tag/documents-and-financials/GET/v1/companies/{cin}/unlock) to see job progress once it has materialised.",
                    "value": {
                      "data": {
                        "cin": "U74999HR2015FTC056386",
                        "unlocked": true,
                        "unlockedAt": "2026-05-01T07:30:00.000Z",
                        "expiresAt": "2027-05-01T07:30:00.000Z",
                        "unlockPrice": 33000,
                        "job": null
                      },
                      "meta": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidCompanyIdentifier"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "description": "`NO_ACCESS` (no pricing record) or `SANDBOX_ONLY` (test key on non-sandbox CIN).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "noAccess": {
                    "summary": "Customer has no pricing for companies.unlock",
                    "value": {
                      "error": {
                        "code": "NO_ACCESS",
                        "message": "No access to endpoint 'companies.unlock'. Contact support to enable access.",
                        "endpoint": "companies.unlock",
                        "catalogPricePaisa": 33000
                      }
                    }
                  },
                  "sandboxOnly": {
                    "summary": "Test key on a non-sandbox CIN",
                    "value": {
                      "error": {
                        "code": "SANDBOX_ONLY",
                        "message": "A test key only works on the sandbox companies and directors. They are listed in this response and at GET /v1/sandbox. Use one of those, or a live key.",
                        "sandboxCompanies": [
                          {
                            "cin": "U74999HR2015FTC056386",
                            "company": "CARS24 SERVICES PRIVATE LIMITED",
                            "knownAs": "Cars24"
                          },
                          {
                            "cin": "L93030DL2010PLC198141",
                            "company": "ETERNAL LIMITED",
                            "knownAs": "Eternal, formerly Zomato"
                          }
                        ],
                        "sandboxDirectors": [
                          {
                            "din": "11692472",
                            "fullName": "NILESH KASHINATH HIWALE"
                          }
                        ],
                        "nextStep": "GET /v1/sandbox"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "CIN passed format validation but is not present in our master data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "notFound": {
                    "value": {
                      "error": {
                        "code": "NOT_FOUND",
                        "message": "No company found for CIN U99999XX2020XYZ999999."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Active unlock already exists for this CIN. No double charge.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlreadyUnlocked"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Documents and financials"
        ],
        "summary": "Get unlock status",
        "description": "**What it returns**\n\nUnlock state and live job progress for this CIN. The same envelope is used regardless of state. Three branches:\n\n- **Active unlock:** `unlocked: true`, `unlockedAt`, `expiresAt`, plus a `job` object carrying live progress from the background refresh. The `processingStages.documentDownloadV3.status` field is the primary progress signal (`pending` → `in_progress` → `success`, usually within minutes of the unlock POST). When download is complete, `documentDownloadV3` also surfaces `zipFiles[]` — direct download URLs to per-batch zip archives of the company's PDFs (use these instead of bulk-download).\n- **No unlock:** `unlocked: false`, `unlockPrice` (or `null` if your customer has no pricing for `companies.unlock`).\n- **Sandbox** (test key + sandbox CIN): synthetic `unlocked: true, sandbox: true, job: null`. No real reads or writes.\n\nRead-only — does not advance the cascade or write to the refresh job.\n\n**Billing**\n\nFree. No wallet deduction; not subject to pricing rows.\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) on a sandbox-whitelisted CIN return the synthetic branch above. Outside the whitelist: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — CIN/FCIN/LLPIN format validation failed\n\nPlus the global auth/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [Cascade diagram](#description/how-filesure-data-works) (visual: where each `processingStages.*` step sits in the pipeline)\n- [Unlock a company](#tag/documents-and-financials/POST/v1/companies/{cin}/unlock) (start the cascade)\n- [Download filing PDF](#tag/documents-and-financials/GET/v1/companies/{cin}/filings/{filingId}/download)\n",
        "operationId": "getCompanyUnlock",
        "parameters": [
          {
            "$ref": "#/components/parameters/CinPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Unlock state for this CIN (any of the three branches above).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnlockResponse"
                },
                "examples": {
                  "completedWithZipUrls": {
                    "summary": "Unlocked, download stage complete (with zip URLs)",
                    "description": "When `documentDownloadV3.status` reaches `success`, `zipFiles[]` carries direct download URLs — fetch the bundled PDFs without iterating over individual filing IDs.",
                    "value": {
                      "data": {
                        "cin": "U74999HR2015FTC056386",
                        "unlocked": true,
                        "unlockedAt": "2026-05-01T07:30:00.000Z",
                        "expiresAt": "2027-05-01T07:30:00.000Z",
                        "unlockPrice": 33000,
                        "job": {
                          "id": "67ef88c3a9b1c2d3e4f56789",
                          "processingStages": {
                            "documentDownloadV3": {
                              "status": "success",
                              "lastUpdated": "2026-05-01T04:40:08.074Z",
                              "totalZipFiles": 2,
                              "zipFiles": [
                                {
                                  "filename": "U74999HR2015FTC056386_documents_20260501_043919_batch_1.zip",
                                  "container": "zip-files",
                                  "blob_url": "https://mcavpd.blob.core.windows.net/zip-files/U74999HR2015FTC056386_documents_20260501_043919_batch_1.zip"
                                },
                                {
                                  "filename": "U74999HR2015FTC056386_documents_20260501_043947_batch_2.zip",
                                  "container": "zip-files",
                                  "blob_url": "https://mcavpd.blob.core.windows.net/zip-files/U74999HR2015FTC056386_documents_20260501_043947_batch_2.zip"
                                }
                              ]
                            },
                            "financials": {
                              "status": "success"
                            },
                            "financialExTriggered": true
                          },
                          "createdAt": "2026-05-01T04:30:00.500Z",
                          "updatedAt": "2026-05-01T04:40:08.074Z"
                        }
                      },
                      "meta": {}
                    }
                  },
                  "inProgress": {
                    "summary": "Unlocked, download stage still running",
                    "value": {
                      "data": {
                        "cin": "U74999HR2015FTC056386",
                        "unlocked": true,
                        "unlockedAt": "2026-05-01T07:30:00.000Z",
                        "expiresAt": "2027-05-01T07:30:00.000Z",
                        "unlockPrice": 33000,
                        "job": {
                          "id": "67ef88c3a9b1c2d3e4f56789",
                          "processingStages": {
                            "documentDownloadV3": {
                              "status": "in_progress",
                              "lastUpdated": "2026-05-01T07:33:00.000Z"
                            }
                          },
                          "createdAt": "2026-05-01T07:30:00.500Z",
                          "updatedAt": "2026-05-01T07:33:00.000Z"
                        }
                      },
                      "meta": {}
                    }
                  },
                  "notUnlocked": {
                    "summary": "Customer hasn't unlocked this CIN",
                    "value": {
                      "data": {
                        "cin": "U74999HR2015FTC056386",
                        "unlocked": false,
                        "unlockPrice": 33000,
                        "job": null
                      },
                      "meta": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidCompanyIdentifier"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Test key on a non-sandbox CIN.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{cin}/filings/{filingId}/download": {
      "get": {
        "tags": [
          "Documents and financials"
        ],
        "summary": "Download filing PDF",
        "description": "**What it returns**\n\nThe actual PDF binary stream when the company is unlocked and the document has been downloaded into our cache. Otherwise returns a `200` JSON unlock-status payload (Content-Type `application/json`) with `{ unlocked: false, unlockPrice }`. PDFs stream from object storage; the API picks the correct backend per CIN. `filingId` is the opaque `flg_…` token from the [list endpoint](#tag/look-up-the-register/GET/v1/companies/{cin}/filings); the underlying MCA `documentCode` is not surfaced.\n\n**Billing**\n\nUnlock-gated. Needs an active company unlock for this CIN, plus the per-call download fee; inside the unlock's year every download is just that fee. Without an active unlock, this endpoint returns the unlock-status JSON instead of the file (no charge). What an unlock covers: [How FileSure data works](#description/how-filesure-data-works).\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) on a sandbox-whitelisted CIN return a synthetic unlock state. The PDF returned is the real cached file when available, or the unlock-status JSON; no wallet deduction. Outside the sandbox: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — CIN/FCIN/LLPIN format validation failed\n- `400 INVALID_FILING_ID` — token not in `flg_…` format or failed integrity check\n- `404 DOC_NOT_AVAILABLE` — filing exists in our index but the PDF isn't downloaded yet. Right after an unlock, wait for the download job (watch `GET /v1/companies/{cin}/unlock`). If the unlock finished long ago and the filing is newer, `POST /v1/companies/{cin}/documents/fetch` (₹150) downloads it; `GET /v1/companies/{cin}/freshness` (free) shows how many are missing. `POST /v1/companies/{cin}/update` does **not** fetch PDFs — it refreshes the record and the filing list only\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [List company filings](#tag/look-up-the-register/GET/v1/companies/{cin}/filings) (where `filingId` comes from)\n- [Unlock a company](#tag/documents-and-financials/POST/v1/companies/{cin}/unlock)\n- [Get unlock status](#tag/documents-and-financials/GET/v1/companies/{cin}/unlock)\n",
        "operationId": "downloadFiling",
        "parameters": [
          {
            "$ref": "#/components/parameters/CompanyIdentifierPath"
          },
          {
            "in": "path",
            "name": "filingId",
            "required": true,
            "description": "Opaque filing identifier from the list endpoint.",
            "schema": {
              "type": "string",
              "pattern": "^flg_[A-Za-z0-9_-]+$"
            },
            "example": "flg_Ui2a1vItyyFYoAGGmefipN0RoT9EtmjHQz4KfzMeVE"
          }
        ],
        "responses": {
          "200": {
            "description": "PDF binary stream (when unlocked) OR unlock-status JSON (when not unlocked — Content-Type `application/json`).",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnlockStatus"
                },
                "examples": {
                  "notUnlocked": {
                    "summary": "Customer hasn't unlocked this CIN yet",
                    "description": "Returned with HTTP 200 and Content-Type `application/json` — no wallet deduction. Direct the customer to the unlock endpoint.",
                    "value": {
                      "data": {
                        "unlocked": false,
                        "unlockPrice": 33000
                      },
                      "meta": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`SANDBOX_ONLY` — test key used outside the sandbox whitelist. Note: a customer without an active unlock for this CIN does NOT 403; they receive a `200` with the unlock-status JSON above.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Filing not found, or PDF not yet downloaded (`DOC_NOT_AVAILABLE`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "docNotAvailable": {
                    "summary": "PDF not yet downloaded into our cache",
                    "value": {
                      "error": {
                        "code": "DOC_NOT_AVAILABLE",
                        "message": "The PDF for this filing has not been downloaded yet. PDFs are fetched by the company unlock — check progress with GET /v1/companies/{cin}/unlock. POST /v1/companies/{cin}/update refreshes the filing list only and does not fetch PDFs."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{cin}/extractions": {
      "get": {
        "tags": [
          "Documents and financials"
        ],
        "summary": "List extracted form types",
        "description": "**What it returns**\n\nThe MCA form types FileSure has extracted structured data for on this CIN. The array is sorted alphabetically and contains any subset of:\n\n- `AOC-4` — annual financial statements (balance sheet, P&L, cash flow). XBRL extraction from MCA Form AOC-4.\n- `CHARGES` — charges (mortgages, hypothecations, secured loans) registered against the company's assets. Multi-level structure: one CIN has many charges; each charge has a lifecycle of CREATION → MODIFICATION* → SATISFACTION events. Addressed by MCA's public `charge_id` string (numeric, e.g. `\"10596825\"`).\n- `MGT-7` — annual return (share capital, directors, KMP, meetings, holding/subsidiary, share-holding pattern). Covers both MGT-7 (large companies) and MGT-7A (small companies / OPC) — the response carries `form_type` to indicate which variant was actually filed.\n- `PAS-3` — share allotment events (Return of Allotment). Per-filing equity / preference / debt capital structure + per-allotment details (date, type, mode, security, total amount). Multiple filings per company across its lifetime — addressed by an opaque `filing_id` token (not a year).\n\nEmpty array when no extractions exist for the CIN.\n\n**Billing**\n\nBilled per call.\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) work freely on sandbox-whitelisted CINs/LLPINs. Outside the whitelist: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — identifier failed CIN/FCIN/LLPIN format validation\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [List extracted years](#tag/documents-and-financials/GET/v1/companies/{cin}/extractions/{formType})\n- [Get extracted data](#tag/documents-and-financials/GET/v1/companies/{cin}/extractions/{formType}/{year})\n",
        "operationId": "listExtractions",
        "parameters": [
          {
            "$ref": "#/components/parameters/CompanyIdentifierPath"
          }
        ],
        "responses": {
          "200": {
            "description": "List of available form types",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractionsListResponse"
                },
                "examples": {
                  "allExtractions": {
                    "summary": "Listed company — all four form types extracted",
                    "value": {
                      "data": {
                        "availableFormTypes": [
                          "AOC-4",
                          "CHARGES",
                          "MGT-7",
                          "PAS-3"
                        ]
                      },
                      "meta": {}
                    }
                  },
                  "aoc4ChargesMgt7": {
                    "summary": "Established company with debt — financials + annual return + charges",
                    "value": {
                      "data": {
                        "availableFormTypes": [
                          "AOC-4",
                          "CHARGES",
                          "MGT-7"
                        ]
                      },
                      "meta": {}
                    }
                  },
                  "aoc4AndMgt7": {
                    "summary": "Mid-cap — financials + annual return (no debt, no allotments)",
                    "value": {
                      "data": {
                        "availableFormTypes": [
                          "AOC-4",
                          "MGT-7"
                        ]
                      },
                      "meta": {}
                    }
                  },
                  "chargesOnly": {
                    "summary": "Older LLP — only charges history extracted",
                    "value": {
                      "data": {
                        "availableFormTypes": [
                          "CHARGES"
                        ]
                      },
                      "meta": {}
                    }
                  },
                  "noExtractions": {
                    "summary": "Newly-incorporated company — no extractions yet",
                    "value": {
                      "data": {
                        "availableFormTypes": []
                      },
                      "meta": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidCompanyIdentifier"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/NoAccess"
          }
        }
      }
    },
    "/v1/companies/{cin}/extractions/{formType}": {
      "get": {
        "tags": [
          "Documents and financials"
        ],
        "summary": "List extracted years",
        "description": "**What it returns — depends on `formType`**\n\nThe shape of this endpoint's response differs significantly by form type because the per-form lifecycle differs. `formType` is case-insensitive.\n\n- **AOC-4** — returns `{formType, availableYears}` with the calendar end-years of `period_end` (e.g. `\"2024-03-31\"` → `2024`). Union across `filing_scope` (standalone + consolidated); pick scope on the data endpoint.\n- **MGT-7** — returns `{formType, availableYears}` with the calendar year of `fyEnd` (financial year end). MGT-7 + MGT-7A both contribute to the same list (the form-variant distinction lives on the data endpoint's `form_type` field). No `filing_scope` split.\n- **PAS-3** — returns `{form_type, latest_snapshot, filings[]}`. Different shape because PAS-3 is event-based (one filing per share allotment, multiple per year). `latest_snapshot` is the consolidated capital structure as-of the most recent allotment date. Each entry in `filings[]` carries a `filing_id` opaque token (use it on the data endpoint), `filing_date`, `as_of_date`, optional `srn`, and `allotment_count`. Sorted by `filing_date` descending.\n- **CHARGES** — returns `{form_type, charges[]}`. One entry per `charge_id` (MCA's public numeric charge identifier — e.g. `\"10596825\"`). Each summary carries `charge_id`, `status` (`ACTIVE` / `SATISFIED` / `OPEN`), `holder_name` + `holder_category` (lender details), `amount_inr` + `amount_crore` (current outstanding), `counts` (creation/modification/satisfaction event counts), `first_event_date`, `latest_event_date`, `latest_event_type`. Sorted by `latest_event_date` descending. Hand the `charge_id` to the data endpoint for the full lifecycle of events.\n\n**Relationship to the master-data endpoint** — `/v1/companies/{cin}` already includes a flat `indexChargesData[]` inline summary (suitable for at-a-glance views in a company profile UI). The dedicated `/extractions/CHARGES` endpoint **augments** that — it surfaces the full lifecycle history (CREATION → MODIFICATION* → SATISFACTION) and per-event details. Use the master-data inline summary for quick views; use these dedicated endpoints for due-diligence-grade lifecycle analysis.\n\n**Billing**\n\nBilled per call.\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) work freely on sandbox-whitelisted CINs/LLPINs. Outside the whitelist: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — identifier failed CIN/FCIN/LLPIN format validation\n- `404 FORM_TYPE_NOT_AVAILABLE` — form type unknown to FileSure (supported: `AOC-4`, `CHARGES`, `MGT-7`, `PAS-3`)\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [List extracted form types](#tag/documents-and-financials/GET/v1/companies/{cin}/extractions)\n- [Get extracted data](#tag/documents-and-financials/GET/v1/companies/{cin}/extractions/{formType}/{year})\n",
        "operationId": "listExtractionYears",
        "parameters": [
          {
            "$ref": "#/components/parameters/CompanyIdentifierPath"
          },
          {
            "$ref": "#/components/parameters/FormTypePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Available years for AOC-4 / MGT-7, OR latest snapshot + filings list for PAS-3,\nOR per-charge summaries for CHARGES. Shape depends on `formType` — see the\nper-form details in the endpoint description.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ExtractionYearsResponse"
                    },
                    {
                      "$ref": "#/components/schemas/Pas3FilingsListResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ChargesListResponse"
                    }
                  ]
                },
                "examples": {
                  "cars24AOC4Years": {
                    "summary": "AOC-4 — years available (descending)",
                    "value": {
                      "data": {
                        "formType": "AOC-4",
                        "availableYears": [
                          2025,
                          2024,
                          2022,
                          2021,
                          2020,
                          2019,
                          2018,
                          2017,
                          2016
                        ]
                      },
                      "meta": {}
                    }
                  },
                  "listedCompanyMGT7Years": {
                    "summary": "MGT-7 — years (one annual return per FY)",
                    "value": {
                      "data": {
                        "formType": "MGT-7",
                        "availableYears": [
                          2025,
                          2024,
                          2023,
                          2022,
                          2021,
                          2020,
                          2019
                        ]
                      },
                      "meta": {}
                    }
                  },
                  "companyWithDebtCharges": {
                    "summary": "CHARGES — per-charge summaries (different shape than AOC-4/MGT-7)",
                    "description": "Real charges list for a CIN with multi-event lifecycle. Sorted by latest_event_date desc.\nEach summary carries enough to identify the charge + its current state at a glance —\ndrill into the detail endpoint via `charge_id` for the full event timeline.\n",
                    "value": {
                      "data": {
                        "form_type": "CHARGES",
                        "charges": [
                          {
                            "charge_id": "10596825",
                            "status": "ACTIVE",
                            "holder_name": "HDFC BANK LIMITED",
                            "holder_category": "Private Sector Bank",
                            "amount_inr": 1249843306,
                            "amount_crore": 124.9843306,
                            "counts": {
                              "creation": 1,
                              "modification": 14,
                              "satisfaction": 0
                            },
                            "first_event_date": "2015-08-29T00:00:00.000Z",
                            "latest_event_date": "2024-05-04T00:00:00.000Z",
                            "latest_event_type": "MODIFICATION"
                          },
                          {
                            "charge_id": "100459847",
                            "status": "ACTIVE",
                            "holder_name": "HDFC BANK LIMITED",
                            "holder_category": "Private Sector Bank",
                            "amount_inr": 2992000,
                            "amount_crore": 0.2992,
                            "counts": {
                              "creation": 1,
                              "modification": 0,
                              "satisfaction": 0
                            },
                            "first_event_date": "2021-05-04T00:00:00.000Z",
                            "latest_event_date": "2021-05-04T00:00:00.000Z",
                            "latest_event_type": "CREATION"
                          }
                        ]
                      },
                      "meta": {
                        "createdAt": "2026-04-15T10:22:00.000Z",
                        "updatedAt": "2026-05-08T03:14:00.000Z"
                      }
                    }
                  },
                  "listedCompanyPAS3Filings": {
                    "summary": "PAS-3 — latest snapshot + filings list (different shape than AOC-4/MGT-7)",
                    "description": "Real PAS-3 list for a high-cardinality listed company. Capital amounts surface as\nstrings (BSON Decimal128) to preserve precision; share counts as JS numbers when\nthey fit in `Number.MAX_SAFE_INTEGER` (else strings).\n",
                    "value": {
                      "data": {
                        "form_type": "PAS-3",
                        "latest_snapshot": {
                          "filing_id": "flg_xKpQyNwz3FdJaT_l5sA9bKp4XmHfVc_pQk1nR5tWzE2YuJrCqL3mNbDgHvSf",
                          "as_of_date": "2025-04-30T00:00:00.000Z",
                          "filing_date": "2025-05-29T00:00:00.000Z",
                          "srn": "AB4296232",
                          "equity": {
                            "authorised": {
                              "shares": 49000000000,
                              "nominal": "10",
                              "total": "490000000000.00"
                            },
                            "issued": {
                              "shares": 13532472634,
                              "nominal": "10",
                              "total": "135324726340.00"
                            },
                            "subscribed": {
                              "shares": 13532472634,
                              "nominal": "10",
                              "total": "135324726340.00"
                            },
                            "paid_up": {
                              "shares": 13532472634,
                              "nominal": "10",
                              "total": "135324726340.00"
                            }
                          }
                        },
                        "filings": [
                          {
                            "filing_id": "flg_xKpQyNwz3FdJaT_l5sA9bKp4XmHfVc_pQk1nR5tWzE2YuJrCqL3mNbDgHvSf",
                            "filing_date": "2025-05-29T00:00:00.000Z",
                            "as_of_date": "2025-04-30T00:00:00.000Z",
                            "srn": "AB4296232",
                            "allotment_count": 1
                          },
                          {
                            "filing_id": "flg_2bMc7VxNqRfDjY_t8wL5pXk3FzEhSa_nWy6oQ4mUrJiKvBtCgL9pHbNzGfM7",
                            "filing_date": "2024-11-22T00:00:00.000Z",
                            "as_of_date": "2024-10-31T00:00:00.000Z",
                            "srn": "AB1812685",
                            "allotment_count": 1
                          }
                        ]
                      },
                      "meta": {
                        "createdAt": "2024-10-22T03:14:00.000Z",
                        "updatedAt": "2025-05-29T07:55:46.687Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidCompanyIdentifier"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/NoAccess"
          },
          "404": {
            "description": "Form type is not extracted by FileSure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "formTypeNotAvailable": {
                    "summary": "Unknown form type",
                    "value": {
                      "error": {
                        "code": "FORM_TYPE_NOT_AVAILABLE",
                        "message": "Form type \"XYZ-99\" is not extracted. Supported: AOC-4, CHARGES, MGT-7, PAS-3."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{cin}/extractions/{formType}/{year}": {
      "get": {
        "tags": [
          "Documents and financials"
        ],
        "summary": "Get extracted data",
        "description": "**What it returns — depends on `formType`**\n\nStructured data extracted from the requested form filing. The path parameter formerly named `{year}` is reused per-form:\n\n- **AOC-4** — `{year}` is the calendar end-year (e.g. `2024`). Returns three arrays of `{qname, value, unit}` triplets covering balance sheet, profit & loss, and cash flow (XBRL output). Standalone vs consolidated are stored as separate extractions; pick via `?scope=` (default `standalone`). If only one scope exists for a year, requesting the other returns `404` with a hint.\n- **MGT-7** — `{year}` is the calendar year of `fyEnd` (e.g. `2024` matches a financial year ending Mar 2024). Returns annual return contents: registration details (`form_type` indicating MGT-7 vs MGT-7A, `fy_start`, `fy_end`, `agm_date`, `srn`, `filing_date`), principal business activities, holding/subsidiary companies, share capital + share-holding pattern, turnover + net worth, directors + KMP, meetings + attendance, remuneration. `?scope=` is ignored on MGT-7.\n- **PAS-3** — `{year}` slot reused for an opaque **`filing_id`** token (`flg_...`). Obtain a `filing_id` from the list endpoint above, then drop it into this URL slot. Returns full filing payload: per-event `capital_structure` (equity + preference + debt) + chronological `allotments[]` (each with date, type, mode, securities, amounts). The same token format is also used by the [filings download endpoint](#tag/documents-and-financials/GET/v1/companies/{cin}/filings/{filingId}/download) — tokens are reversible only by the server (AES-encrypted `(cin, documentCode)`), so a token from one CIN's URL won't work on another CIN's URL (returns 404).\n- **CHARGES** — `{year}` slot reused for the **`charge_id`** (MCA's public numeric charge identifier, e.g. `\"10596825\"`). Obtain a `charge_id` from the list endpoint above. Returns full charge lifecycle: `current` consolidated state (omitted on `SATISFIED` charges where there's nothing currently active) + `counts` + `events[]` — chronologically ascending CREATION → MODIFICATION* → SATISFACTION events. Each event carries `event_type`, `event_date`, `filing_date`, `srn`, plus the per-event detail subdocs (`charge` with amount + roi + repay terms, `holder` with bank name + category + address, `security`, `asset_particulars`, `desc_of_modification` for MODIFICATION events, `satisfaction` for SATISFACTION events). Older events may have only event-type + dates (variable richness — surface populated fields only, no nulls).\n\nAll fields are surfaced verbatim from MCA's filed form — no UI flattening, no derived totals. Customers compose their own views from the raw data.\n\n**Billing**\n\nUnlock-gated. Needs an active company unlock for this CIN, the same unlock that gates filing downloads (one fee covers every extraction of every form type), plus the per-call fee. Without an active unlock this endpoint returns the unlock-status JSON instead of the data (no charge). What an unlock covers: [How FileSure data works](#description/how-filesure-data-works).\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) on a sandbox-whitelisted CIN return a synthetic unlock state and the real cached extraction; no wallet deduction. Outside the sandbox: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — CIN/FCIN/LLPIN format validation failed\n- `400 INVALID_YEAR` — AOC-4/MGT-7: year out of range (must be 1900..currentYear+1)\n- `400 INVALID_FILING_ID` — PAS-3: path slot is not a valid `flg_*` token (malformed, or AES-tampered)\n- `400 INVALID_CHARGE_ID` — CHARGES: path slot is not a numeric string\n- `400 INVALID_QUERY` — `?scope=` set to a value outside the enum (AOC-4 only — ignored on MGT-7/PAS-3/CHARGES)\n- `404 EXTRACTION_NOT_AVAILABLE` — AOC-4/MGT-7: no extraction for this `(form, year)`. AOC-4 hint may point to the other `?scope=`\n- `404 FILING_NOT_FOUND` — PAS-3: token decodes to a `(cin, documentCode)` that doesn't have a matching event in `pas3_events`, OR the decoded `cin` doesn't match the URL `cin` (cross-CIN paste defense)\n- `404 CHARGE_NOT_FOUND` — CHARGES: no charge with the given `charge_id` exists for this CIN\n- `404 FORM_TYPE_NOT_AVAILABLE` — form type unknown (supported: `AOC-4`, `CHARGES`, `MGT-7`, `PAS-3`)\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [List extracted form types](#tag/documents-and-financials/GET/v1/companies/{cin}/extractions)\n- [List extracted years](#tag/documents-and-financials/GET/v1/companies/{cin}/extractions/{formType})\n- [Unlock a company](#tag/documents-and-financials/POST/v1/companies/{cin}/unlock)\n",
        "operationId": "getExtractionData",
        "parameters": [
          {
            "$ref": "#/components/parameters/CompanyIdentifierPath"
          },
          {
            "$ref": "#/components/parameters/FormTypePath"
          },
          {
            "in": "path",
            "name": "year",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+$|^flg_[A-Za-z0-9_-]+$"
            },
            "example": 2024,
            "description": "Per-form axis (path-slot name reused historically):\n- **AOC-4 / MGT-7**: 4-digit calendar end-year (e.g. `2024`). Must be in `[1900, currentYear+1]`.\n- **PAS-3**: opaque `flg_*` filing_id token from the list endpoint's `filings[].filing_id`.\n- **CHARGES**: numeric `charge_id` (e.g. `\"10596825\"`) from the list endpoint's `charges[].charge_id`.\n"
          },
          {
            "in": "query",
            "name": "scope",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "standalone",
                "consolidated"
              ],
              "default": "standalone"
            },
            "description": "Which filing scope to return. Defaults to standalone."
          }
        ],
        "responses": {
          "200": {
            "description": "Extraction data (shape depends on `formType`), OR unlock-status payload when not unlocked.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ExtractionDataResponse"
                    },
                    {
                      "$ref": "#/components/schemas/Mgt7ExtractionDataResponse"
                    },
                    {
                      "$ref": "#/components/schemas/Pas3ExtractionDataResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ChargesDetailResponse"
                    },
                    {
                      "$ref": "#/components/schemas/UnlockStatus"
                    }
                  ]
                },
                "examples": {
                  "aoc4Unlocked": {
                    "summary": "AOC-4 standalone for 2024 (truncated, CARS24)",
                    "description": "Real AOC-4 extractions have 80–100 rows per array; example shows 1 representative row each.",
                    "value": {
                      "data": {
                        "cin": "U74999HR2015FTC056386",
                        "filing_scope": "standalone",
                        "period_end": "2024-03-31",
                        "period_start": "2023-04-01",
                        "taxonomy_id": "in-ca:Schedule3IndAS",
                        "balance_sheet": [
                          {
                            "qname": "in-ca:Equity",
                            "value": 12450000000,
                            "unit": "INR"
                          }
                        ],
                        "profit_and_loss": [
                          {
                            "qname": "in-ca:RevenueFromOperations",
                            "value": 89400000000,
                            "unit": "INR"
                          }
                        ],
                        "cash_flow": [
                          {
                            "qname": "in-ca:CashFlowsFromUsedInOperatingActivities",
                            "value": -3210000000,
                            "unit": "INR"
                          }
                        ],
                        "metadata": {
                          "source": {
                            "dateOfFiling": "30/09/2024",
                            "paymentDate": "28/09/2024",
                            "year": 2024
                          }
                        }
                      },
                      "meta": {
                        "createdAt": "2024-09-30T14:22:18.000Z",
                        "updatedAt": "2024-10-12T08:05:42.000Z"
                      }
                    }
                  },
                  "mgt7Unlocked": {
                    "summary": "MGT-7 annual return for 2025 (truncated, listed company L15400TG2009PLC062658)",
                    "description": "Listed company MGT-7 with full sections. Real responses have all populated MCA sections;\nexample trims nested arrays to one representative row. `form_type` reflects which actual\nfiling variant was used (`MGT-7` for standard, `MGT-7A` for small companies / OPC).\n",
                    "value": {
                      "data": {
                        "cin": "L15400TG2009PLC062658",
                        "form_type": "MGT-7",
                        "srn": "AC0745199",
                        "fy_start": "2024-04-01T00:00:00.000Z",
                        "fy_end": "2025-03-31T00:00:00.000Z",
                        "agm_date": "2025-09-24T00:00:00.000Z",
                        "filing_date": "2025-12-28T00:00:00.000Z",
                        "is_opc": false,
                        "is_share_listed": true,
                        "number_stock_exchange": 1,
                        "stock_exchanges": [
                          "BSE"
                        ],
                        "num_business_actv": 3,
                        "business_activities": [
                          {
                            "main_group_code": "N",
                            "main_group_desc": "Administrative and support service activities",
                            "activity_code": "80",
                            "activity_desc": "Security and investigation activities",
                            "turnover_pct": 29.89
                          }
                        ],
                        "num_rtas": 1,
                        "rtas": [
                          {
                            "cin_other_reg_no": "U72400TG2017PTC117649",
                            "name_of_rta": "KFin Technologies Limited",
                            "address1": "Selenium Tower-B, Plot 31 & 32"
                          }
                        ],
                        "num_holding_subs": 2,
                        "holding_subs": [],
                        "share_capital": {
                          "equity": {
                            "num_classes": 1,
                            "totals": {
                              "shares": {
                                "authorised": 23000000,
                                "issued": 20288122,
                                "subscribed": 20288122,
                                "paid_up": 20288122
                              },
                              "amount": {
                                "authorised": 115000000,
                                "issued": 101440610,
                                "subscribed": 101440610,
                                "paid_up": 101440610
                              }
                            }
                          },
                          "preference": {
                            "num_classes": 0,
                            "totals": {
                              "shares": {
                                "authorised": 0,
                                "issued": 0,
                                "subscribed": 0,
                                "paid_up": 0
                              },
                              "amount": {
                                "authorised": 0,
                                "issued": 0,
                                "subscribed": 0,
                                "paid_up": 0
                              }
                            }
                          },
                          "unclassified_total": 0
                        },
                        "share_holding_pattern": {
                          "promoter": {
                            "equity_pct": 50.78,
                            "preference_pct": 0
                          },
                          "public": {
                            "equity_pct": 49.22,
                            "preference_pct": 0
                          }
                        },
                        "turnover": 6887017470,
                        "net_worth": 888754630,
                        "meetings": {
                          "members_total": 1,
                          "board_total": 4,
                          "committee_total": 12,
                          "directors_attendance": []
                        },
                        "kmp": [
                          {
                            "din": "00037022",
                            "name": "Prem Kishan Dass Gupta",
                            "designation": "MANAGING DIRECTOR"
                          }
                        ],
                        "remuneration": {
                          "directors": [],
                          "total": 0
                        }
                      },
                      "meta": {
                        "createdAt": "2026-04-20T08:34:29.719Z",
                        "updatedAt": "2026-04-20T08:34:29.719Z"
                      }
                    }
                  },
                  "pas3Unlocked": {
                    "summary": "PAS-3 — full filing detail for a single share allotment (listed company, L17110MH1973PLC019786)",
                    "description": "The `:filing_id` path slot carries a `flg_*` token (from the list endpoint). Returns\nthe per-event `capital_structure` (equity + preference + debt) + chronological\n`allotments[]` array. Decimal128 values surface as strings to preserve precision.\n",
                    "value": {
                      "data": {
                        "cin": "L17110MH1973PLC019786",
                        "form_type": "PAS-3",
                        "filing_id": "flg_xKpQyNwz3FdJaT_l5sA9bKp4XmHfVc_pQk1nR5tWzE2YuJrCqL3mNbDgHvSf",
                        "filing_date": "2025-05-29T00:00:00.000Z",
                        "srn": "AB4296232",
                        "capital_structure": {
                          "equity": {
                            "authorised": {
                              "shares": 49000000000,
                              "nominal": "10",
                              "total": "490000000000.00"
                            },
                            "issued": {
                              "shares": 13532472634,
                              "nominal": "10",
                              "total": "135324726340.00"
                            },
                            "subscribed": {
                              "shares": 13532472634,
                              "nominal": "10",
                              "total": "135324726340.00"
                            },
                            "paid_up": {
                              "shares": 13532472634,
                              "nominal": "10",
                              "total": "135324726340.00"
                            }
                          },
                          "preference": {
                            "authorised": {
                              "shares": 1000000000,
                              "nominal": "10",
                              "total": "10000000000.00"
                            },
                            "issued": {
                              "shares": 0,
                              "nominal": "0",
                              "total": "0.00"
                            },
                            "subscribed": {
                              "shares": 0,
                              "nominal": "0",
                              "total": "0.00"
                            },
                            "paid_up": {
                              "shares": 0,
                              "nominal": "0",
                              "total": "0.00"
                            }
                          },
                          "debt": {
                            "debentures": "283888000000",
                            "secured_loans": "73708977566.46",
                            "others": "1610154091933.08"
                          }
                        },
                        "allotments": [
                          {
                            "allotment_date": "2025-04-30T00:00:00.000Z",
                            "security_type": "Equity",
                            "allotment_type": "Employee stock option Plan (ESOP)",
                            "details": "PARI-PASSU WITH EXISTING FULLY PAID-UP EQ SHARES",
                            "terms_in_attachment": false,
                            "mode": "Cash",
                            "num_securities_allotted": 99736,
                            "nominal_per_security": "10",
                            "premium_per_security": "0",
                            "discount_per_security": "0",
                            "total_amount": "997360",
                            "non_cash": null
                          }
                        ]
                      },
                      "meta": {
                        "createdAt": "2025-05-29T07:55:46.687Z",
                        "updatedAt": "2025-05-29T07:55:46.687Z"
                      }
                    }
                  },
                  "chargesUnlocked": {
                    "summary": "CHARGES — full lifecycle for one charge (HDFC working-capital, U27100PB1996PLC017827)",
                    "description": "Real charge with 15 events (1 creation + 14 modifications, no satisfaction — still\nACTIVE). `current` block carries the consolidated state-as-of-now; `events[]` is\nchronologically ascending. Older events have less rich per-event detail (variable\nrichness — surface populated fields only, no nulls).\n",
                    "value": {
                      "data": {
                        "cin": "U27100PB1996PLC017827",
                        "form_type": "CHARGES",
                        "charge_id": "10596825",
                        "status": "ACTIVE",
                        "counts": {
                          "creation": 1,
                          "modification": 14,
                          "satisfaction": 0
                        },
                        "current": {
                          "amount_inr": 1249843306,
                          "amount_crore": 124.9843306,
                          "roi_pct": "9.50%",
                          "holder_name": "HDFC BANK LIMITED",
                          "holder_category": "Private Sector Bank",
                          "num_holders": 1,
                          "flags": {
                            "is_joint": false,
                            "is_consortium": false,
                            "is_pari_passu": false
                          },
                          "property_type_raw": [
                            "Movable property - Inventory",
                            "Movable property - Motor Vehicle (Hypothecation)",
                            "Movable property - Others",
                            "Book debts"
                          ],
                          "property_types": [
                            "MOVABLE_INVENTORY",
                            "VEHICLES",
                            "MOVABLE_PROPERTY",
                            "BOOK_DEBTS"
                          ],
                          "instrument_desc": "Supplementary Letter of Hypothecation."
                        },
                        "events": [
                          {
                            "event_type": "CREATION",
                            "event_date": "2015-08-29T00:00:00.000Z",
                            "filing_date": "2015-09-15T00:00:00.000Z",
                            "reg_date": "2015-09-15T00:00:00.000Z",
                            "srn": "C67177063",
                            "charge": {
                              "amount_inr": 365000000,
                              "amount_crore": 36.5,
                              "amount_words": "Rupees Thirty Six Crore Fifty Lacs only",
                              "roi_pct": "Interest at the rate as stipulated in the Bank's Sanction Letter.",
                              "nature_facility": "MFA",
                              "terms_of_repay": "MFA repayable on demand and/or as stipulated in the Bank's Sanction Letter."
                            },
                            "holder": {
                              "is_joint": false,
                              "is_consortium": false,
                              "is_pari_passu": false,
                              "num_holders": 1,
                              "category": "PVTB",
                              "name_of_chg_holder": "HDFC BANK LIMITED",
                              "name": "HDFC BANK LIMITED",
                              "add_line1": "HDFC BANK HOUSE, SENAPATI BAPAT MARG",
                              "city": "MUMBAI",
                              "state": "MH",
                              "pin_code": "400013",
                              "country": "IN"
                            }
                          },
                          {
                            "event_type": "MODIFICATION",
                            "event_date": "2020-06-04T00:00:00.000Z",
                            "filing_date": "2020-07-03T00:00:00.000Z",
                            "srn": "R44284271",
                            "desc_of_modification": "The charge shall now stand increased from Rs.3050 Lakhs to Rs.3650 Lakhs in favour of the Bank against the security of Stocks & Book Debts, Plant & Machinery and vehicles and immovable properties...",
                            "charge": {
                              "amount_inr": 365000000,
                              "amount_crore": 36.5
                            },
                            "holder": {
                              "num_holders": 1,
                              "category": "PVTB",
                              "name_of_chg_holder": "HDFC BANK LIMITED"
                            }
                          }
                        ]
                      },
                      "meta": {
                        "createdAt": "2026-04-15T10:22:00.000Z",
                        "updatedAt": "2024-05-08T03:14:00.000Z"
                      }
                    }
                  },
                  "notUnlocked": {
                    "summary": "Customer hasn't unlocked this CIN yet",
                    "value": {
                      "data": {
                        "unlocked": false,
                        "unlockPrice": 33000
                      },
                      "meta": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid CIN, year out of range, or unknown scope value",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidYear": {
                    "summary": "AOC-4 / MGT-7 — year out of range",
                    "value": {
                      "error": {
                        "code": "INVALID_YEAR",
                        "message": "`year` must be between 1900 and the current calendar year + 1."
                      }
                    }
                  },
                  "invalidFilingId": {
                    "summary": "PAS-3 — path slot is not a valid flg_* token",
                    "value": {
                      "error": {
                        "code": "INVALID_FILING_ID",
                        "message": "`filing_id` is not a valid identifier."
                      }
                    }
                  },
                  "invalidChargeId": {
                    "summary": "CHARGES — path slot is not numeric",
                    "value": {
                      "error": {
                        "code": "INVALID_CHARGE_ID",
                        "message": "`charge_id` path parameter must be a numeric string."
                      }
                    }
                  },
                  "invalidScope": {
                    "value": {
                      "error": {
                        "code": "INVALID_QUERY",
                        "message": "`scope` must be one of: standalone, consolidated."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`SANDBOX_ONLY` — test key (`fsk_test_*`) used outside the sandbox-whitelisted CIN list. `unlockCheck()` doesn't 403 live keys for missing pricing — when no unlock and no pricing record exist, it returns the 200 not-unlocked envelope with `unlockPrice: null`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "SANDBOX_ONLY",
                    "message": "A test key only works on the sandbox companies and directors. They are listed in this response and at GET /v1/sandbox. Use one of those, or a live key.",
                    "sandboxCompanies": [
                      {
                        "cin": "U74999HR2015FTC056386",
                        "company": "CARS24 SERVICES PRIVATE LIMITED",
                        "knownAs": "Cars24"
                      },
                      {
                        "cin": "L93030DL2010PLC198141",
                        "company": "ETERNAL LIMITED",
                        "knownAs": "Eternal, formerly Zomato"
                      }
                    ],
                    "sandboxDirectors": [
                      {
                        "din": "11692472",
                        "fullName": "NILESH KASHINATH HIWALE"
                      }
                    ],
                    "nextStep": "GET /v1/sandbox"
                  }
                }
              }
            }
          },
          "404": {
            "description": "No extraction available for the requested form/year/scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missingYear": {
                    "summary": "AOC-4 / MGT-7 — year has no extraction",
                    "value": {
                      "error": {
                        "code": "EXTRACTION_NOT_AVAILABLE",
                        "message": "No AOC-4 extraction available for 1995."
                      }
                    }
                  },
                  "wrongScope": {
                    "summary": "AOC-4 — other scope is available",
                    "value": {
                      "error": {
                        "code": "EXTRACTION_NOT_AVAILABLE",
                        "message": "No AOC-4 consolidated extraction for 2024. The standalone extraction is available — try ?scope=standalone."
                      }
                    }
                  },
                  "pas3FilingNotFound": {
                    "summary": "PAS-3 — token decodes successfully but no matching event for this CIN",
                    "description": "Returned when the `flg_*` token decodes (valid AES) but either (a) the decoded\ndocumentCode doesn't match a PAS-3 event for this CIN, or (b) the decoded `cin`\ninside the token differs from the URL CIN (cross-CIN paste defense).\n",
                    "value": {
                      "error": {
                        "code": "FILING_NOT_FOUND",
                        "message": "No PAS-3 filing matches filing_id \"flg_xKpQy...\" for this company."
                      }
                    }
                  },
                  "chargeNotFound": {
                    "summary": "CHARGES — no charge with that charge_id exists for this CIN",
                    "value": {
                      "error": {
                        "code": "CHARGE_NOT_FOUND",
                        "message": "No charge with charge_id \"9999999999\" exists for this company."
                      }
                    }
                  },
                  "unknownFormType": {
                    "value": {
                      "error": {
                        "code": "FORM_TYPE_NOT_AVAILABLE",
                        "message": "Form type \"XYZ-99\" is not extracted. Supported: AOC-4, CHARGES, MGT-7, PAS-3."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{cin}/freshness": {
      "get": {
        "tags": [
          "Keep a company current"
        ],
        "summary": "How current is our copy of this company?",
        "description": "Dates and counts only — no company data — so you can decide whether to pay for a refresh\nbefore you do. **Free.** Covered by the per-key rate limit like the account calls.\n\n**The flow this call starts**\n\n1. `GET /v1/companies/{cin}/freshness` — free. Is the record stale? Are PDFs missing?\n2. `POST /v1/companies/{cin}/update` — ₹1. Refreshes the record and the filing list from MCA. No PDFs.\n3. `POST /v1/companies/{cin}/documents/fetch` — ₹150. Downloads the PDFs that are still missing (needs your unlock).\n\n**What the fields mean**\n\n| Field | Meaning |\n|---|---|\n| `data.updatedAt` | When the company's master data, directors, common data and charges were last written. They are refreshed together, so one date is enough. |\n| `filings.total` / `downloaded` / `missing` | Our filing index for the company: rows, rows with a PDF on file, rows without. `missing > 0` is what a document job would fetch. |\n| `filings.listRefreshedAt` | When the filing list was last re-read from MCA (a data refresh or a filing-list refresh). |\n| `refresh` | The newest data refresh for this company, whoever asked for it: `status`, `lastCompletedAt` and `freshUntil` — until then a `POST /update` joins the finished refresh (`alreadyFresh: true`) instead of fetching again. |\n| `documentJob` | The newest document download job for this company: `status` (`pending` → `in_progress` → `success`) and its counters. `null` if none has run. |\n| `unlock` | Whether **you** hold an active unlock for this company, and when it expires. |\n\n**Sandbox behavior**\n\n`fsk_test_*` keys on a whitelisted CIN return a synthetic, settled shape with `sandbox: true`. Outside the whitelist: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_CIN` — format validation failed\n- `404 COMPANY_NOT_FOUND` — we do not hold this company\n",
        "operationId": "getCompanyFreshness",
        "parameters": [
          {
            "$ref": "#/components/parameters/CinPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Freshness of our data for this company",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "cin": "U62013KA2024PTC188236",
                    "data": {
                      "updatedAt": "2026-09-13T22:10:04.000Z"
                    },
                    "filings": {
                      "total": 30,
                      "downloaded": 21,
                      "missing": 9,
                      "listRefreshedAt": "2026-09-13T22:10:19.000Z"
                    },
                    "refresh": {
                      "jobId": "6aa7f0c1b22e2991f01371aa",
                      "status": "completed",
                      "requestedAt": "2026-09-13T22:09:52.000Z",
                      "lastCompletedAt": "2026-09-13T22:10:19.000Z",
                      "freshUntil": "2026-09-14T22:10:19.000Z"
                    },
                    "documentJob": {
                      "status": "success",
                      "totalDocuments": 21,
                      "downloadedDocuments": 21,
                      "pendingDocuments": 0,
                      "createdAt": "2026-08-03T06:49:12.000Z",
                      "updatedAt": "2026-08-03T07:02:40.000Z"
                    },
                    "unlock": {
                      "active": true,
                      "unlockedAt": "2026-08-16T09:12:40.000Z",
                      "expiresAt": "2027-08-16T09:12:40.000Z"
                    }
                  },
                  "meta": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidCompanyIdentifier"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Test key on a non-sandbox CIN.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "We do not hold this company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{cin}/update": {
      "post": {
        "tags": [
          "Keep a company current"
        ],
        "summary": "Refresh a company from MCA",
        "operationId": "updateCompany",
        "description": "Fetches this company again from MCA, now, and updates what we hold: its master data, its\ndirector list, its common data and its filing list. Returns `202 Accepted` with a job id.\n**₹1** — a nominal fee, because the refresh also improves our own data.\n\n**This refreshes data, not documents.** It fetches no PDFs. Unlock buys you the company's\n*documents* — PDFs and extracted financials — for a year; once unlocked, new filings the\nrefresh finds are downloaded by `POST /v1/companies/{cin}/documents/fetch` (₹150). Update\nrefreshes the *record*: name, status, registered address, capital, directors, charges, and\nthe list of filings. If you unlocked a company last year and want to know whether anything\nhas changed since, this is the call — and it is free to find out first with\n`GET /v1/companies/{cin}/freshness`.\n\nWhere this sits in the flow, and what the other two calls do: [How FileSure data works](#description/how-filesure-data-works).\n\n**What to do next is in the response.** `documents.newFilings` is how many filings the\nrefresh added to our list; once the job is `completed`, `documents.missing` is how many\nlisted filings have no PDF on file and `documents.nextStep` names the document job when that\nis above zero.\n\n**It is asynchronous.** A live MCA fetch takes seconds to minutes and can fail on captcha or\nupstream quota, so the response comes back immediately with a job id. Poll\n`GET /v1/companies/{cin}/update/status` for progress.\n\n**Stages are reported separately**, because a partial refresh is the normal case rather than\nthe exception:\n\n| Stage | What it refreshes |\n|---|---|\n| `masterData` | Company name, status, dates, address, capital |\n| `directors` | The board as MCA currently lists it |\n| `commonData` | PAN and associated identifiers |\n| `documents` | The filing index on our side |\n\nA stage reads `completed`, `failed` or `skipped`. `skipped` means we chose not to run it —\nthe director list is read from the master-data response, so it is skipped when that stage\nfails. It does not mean an error.\n\n**One refresh per company per 24 hours, shared.** If someone else already asked for this\ncompany inside that window you join their job rather than starting a second scrape, and the\nresponse carries `joinedExisting: true`. Where their refresh has already finished you also\nget `alreadyFresh: true` — the data was current before you asked, and no new fetch was run.\n`freshUntil` says when the window ends (`cooldownUntil` is the same value, kept for older\nintegrations). Every call is charged, including one that joins.\n\n**Rate limit:** 10 companies per minute, separate from the general per-key limit. Each\nrefresh is a live MCA round trip, not a cached read.\n\n**Billing**\n\nCharges your `companies.update` rate (see the [rate card](/pricing.html)) on success, including when you join a\nrunning or freshly-completed refresh. If the refresh cannot be queued you get `503` and are\n**not** charged.\n\n**Sandbox behavior**\n\n`fsk_test_*` keys on a whitelisted CIN return a synthetic completed job. No MCA fetch, no\ncharge, no job record.\n\n**Common errors**\n\n- `400 INVALID_CIN` — format validation failed\n- `402 INSUFFICIENT_BALANCE` — wallet below the update fee; nothing queued\n- `404 COMPANY_NOT_FOUND` — we do not hold this company; no charge\n- `429 RATE_LIMITED` — past 10 refreshes/minute; no charge\n- `409 REFRESH_IN_PROGRESS` — a filing-list-only refresh (`POST /v1/companies/{cin}/filings/refresh`) is running for this company; retry after `Retry-After` seconds to start the full refresh. No charge\n- `503 UPDATE_QUEUE_UNAVAILABLE` — could not queue; no charge, safe to retry\n",
        "parameters": [
          {
            "name": "cin",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "U74999HR2015FTC056386"
          }
        ],
        "responses": {
          "202": {
            "description": "Refresh queued, or joined to one already running",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "cin": "U74999HR2015FTC056386",
                    "jobId": "6a7c6b00b22e2991f0137105",
                    "status": "pending",
                    "requestedAt": "2026-08-12T12:45:52.000Z",
                    "lastCompletedAt": null,
                    "freshUntil": null,
                    "cooldownUntil": null,
                    "stages": {
                      "masterData": {
                        "status": "pending"
                      },
                      "directors": {
                        "status": "pending"
                      },
                      "commonData": {
                        "status": "pending"
                      },
                      "documents": {
                        "status": "pending"
                      }
                    }
                  },
                  "meta": {
                    "priceChargedPaisa": 100,
                    "walletBalanceAfterPaisa": 44190
                  }
                }
              }
            }
          },
          "402": {
            "description": "Insufficient wallet balance"
          },
          "404": {
            "description": "Company not found"
          },
          "429": {
            "description": "Refresh rate limit exceeded"
          },
          "503": {
            "description": "Could not queue the refresh — not charged"
          }
        }
      }
    },
    "/v1/companies/{cin}/update/status": {
      "get": {
        "tags": [
          "Keep a company current"
        ],
        "summary": "Progress of a company refresh",
        "operationId": "getCompanyUpdateStatus",
        "description": "Per-stage progress for the most recent refresh of this company. Free.\n\nThe job is per *company*, not per customer — if you joined someone else's refresh, this\nshows you its progress.\n\n`status` is `pending`, `in_progress`, `completed` or `failed`. It reads `failed` when any\nstage failed, so check the individual stages to see what did land: three of four refreshed\nis a normal outcome and better than none.\n\n`freshUntil` (and its older alias `cooldownUntil`) is set only on a successful refresh —\n24 hours after it completed. A failed one never blocks a retry.\n\n`documents` says what the refresh found: `newFilings` added to our list, and once the job\nis `completed`, `missing` (listed filings with no PDF on file) and `nextStep`, which names\n`POST /v1/companies/{cin}/documents/fetch` when there is something to download.\n",
        "parameters": [
          {
            "name": "cin",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "U74999HR2015FTC056386"
          }
        ],
        "responses": {
          "200": {
            "description": "Current refresh state",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "cin": "U74999HR2015FTC056386",
                    "jobId": "6a7c6b00b22e2991f0137105",
                    "status": "completed",
                    "requestedAt": "2026-08-12T12:45:52.000Z",
                    "lastCompletedAt": "2026-08-12T12:46:07.000Z",
                    "freshUntil": "2026-08-13T12:46:07.000Z",
                    "cooldownUntil": "2026-08-13T12:46:07.000Z",
                    "stages": {
                      "masterData": {
                        "status": "completed"
                      },
                      "directors": {
                        "status": "completed"
                      },
                      "commonData": {
                        "status": "completed"
                      },
                      "documents": {
                        "status": "completed"
                      }
                    },
                    "documents": {
                      "newFilings": 9,
                      "missing": 9,
                      "nextStep": "POST /v1/companies/{cin}/documents/fetch"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{cin}/documents/fetch": {
      "post": {
        "tags": [
          "Keep a company current"
        ],
        "summary": "Fetch new documents for an unlocked company",
        "description": "Queues a download of the filings whose PDFs we do not hold yet, for a company you have\nalready unlocked. Returns `202 Accepted`; watch progress at\n[GET /v1/companies/{cin}/unlock](#tag/documents-and-financials/GET/v1/companies/{cin}/unlock).\n\n**When to use it.** The ₹330 unlock includes the first download. Months later the company\nhas filed more, and a data refresh (`POST /v1/companies/{cin}/update`) has listed the new\nfilings — but a refresh never fetches PDFs. This call does: it starts a new download job\nfor everything in the filing list that is still missing a PDF.\n\n**The flow**\n\n1. `POST /v1/companies/{cin}/unlock` — once, opens a 1-year window and runs the first download.\n2. `POST /v1/companies/{cin}/update` — ₹1, pulls the current filing list from MCA.\n3. `POST /v1/companies/{cin}/documents/fetch` — ₹150, downloads the PDFs that appeared.\n\n**Rules**\n\n- **Needs your active unlock** for this company. Without one: `403 UNLOCK_REQUIRED` with\n  `nextStep` pointing at the unlock, and **no charge**.\n- **Nothing missing, nothing charged.** If every filing we list already has its PDF (or we\n  hold no filing list yet), you get `409 NOTHING_TO_FETCH` with the counts and a `nextStep`\n  pointing at the data refresh. No charge.\n- **Joining a running job is still charged.** If a download job for this company is already\n  running, the response carries `joinedExisting: true` and the call is charged at the full\n  rate — the job will pick up your missing filings.\n- **Charged only once the job is queued.** If it cannot be queued you get `503` and are not\n  charged.\n\n`filings` in the response counts our filing index: `total`, `downloaded` (PDF on file) and\n`missing` (what this job will fetch). New MCA filings we have not indexed yet are not in it —\nrun the data refresh first.\n\n**Billing**\n\nCharges your `companies.documents.fetch` rate (see the [rate card](/pricing.html)) on `202`. All other\nresponses are free.\n\n**Sandbox behavior**\n\n`fsk_test_*` keys on a whitelisted CIN return a synthetic `202` with `sandbox: true`. No\nunlock is needed, nothing is queued, no charge.\n\n**Common errors**\n\n- `400 INVALID_CIN` — format validation failed\n- `402 INSUFFICIENT_BALANCE` — wallet below the document-job fee; nothing queued\n- `403 UNLOCK_REQUIRED` — no active unlock for this company; no charge\n- `403 NO_ACCESS` — no pricing row for `companies.documents.fetch`\n- `404 COMPANY_NOT_FOUND` — we do not hold this company; no charge\n- `409 NOTHING_TO_FETCH` — every listed filing already has its PDF; no charge\n- `503 DOCUMENT_JOB_QUEUE_UNAVAILABLE` — could not queue; no charge, safe to retry\n",
        "operationId": "fetchCompanyDocuments",
        "parameters": [
          {
            "$ref": "#/components/parameters/CinPath"
          }
        ],
        "responses": {
          "202": {
            "description": "Document job queued, or joined to one already running",
            "content": {
              "application/json": {
                "examples": {
                  "queued": {
                    "summary": "New job queued",
                    "value": {
                      "data": {
                        "cin": "U62013KA2024PTC188236",
                        "queued": true,
                        "joinedExisting": false,
                        "filings": {
                          "total": 30,
                          "downloaded": 21,
                          "missing": 9
                        },
                        "unlockExpiresAt": "2027-08-16T09:12:40.000Z",
                        "progress": "GET /v1/companies/{cin}/unlock"
                      },
                      "meta": {
                        "priceChargedPaisa": 15000,
                        "walletBalanceAfterPaisa": 44190
                      }
                    }
                  },
                  "joined": {
                    "summary": "Joined a job already running — still charged",
                    "value": {
                      "data": {
                        "cin": "U62013KA2024PTC188236",
                        "queued": true,
                        "joinedExisting": true,
                        "filings": {
                          "total": 30,
                          "downloaded": 21,
                          "missing": 9
                        },
                        "unlockExpiresAt": "2027-08-16T09:12:40.000Z",
                        "progress": "GET /v1/companies/{cin}/unlock"
                      },
                      "meta": {
                        "priceChargedPaisa": 15000,
                        "walletBalanceAfterPaisa": 29190
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidCompanyIdentifier"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "description": "`UNLOCK_REQUIRED` (no active unlock — no charge), `NO_ACCESS` (no pricing row) or `SANDBOX_ONLY` (test key on a non-sandbox CIN).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unlockRequired": {
                    "value": {
                      "error": {
                        "code": "UNLOCK_REQUIRED",
                        "message": "A document job needs an active unlock for this company. Unlock it first; the unlock includes the first download. No charge was made.",
                        "nextStep": "POST /v1/companies/{cin}/unlock",
                        "unlockPrice": 33000
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "We do not hold this company. No charge.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Every listed filing already has its PDF — nothing to fetch, no charge.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "nothingToFetch": {
                    "value": {
                      "error": {
                        "code": "NOTHING_TO_FETCH",
                        "message": "Every filing we list for this company already has its PDF. Run a data refresh to pick up new MCA filings first. No charge was made.",
                        "nextStep": "POST /v1/companies/{cin}/update",
                        "filings": {
                          "total": 30,
                          "downloaded": 30,
                          "missing": 0
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Could not queue the document job — not charged, safe to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/directors/{din}/unlock": {
      "post": {
        "tags": [
          "Director contact"
        ],
        "summary": "Unlock a director's contact",
        "description": "Creates a 1-year unlock for this DIN's contact tier (mobile + email) and unlocks [GET /v1/directors/{din}/contact](#tag/director-contact/GET/v1/directors/{din}/contact) for the customer for the next 365 days. The cascade here is structurally different from the company unlock — no background download, no extraction job. Instead:\n\n1. **Hot path** (cached contact <365 days old, mobile or email present): atomic wallet deduction + unlock create + `200 OK`. Sub-200 ms; no MCA fetch.\n2. **Cold path** (cached contact stale or missing): triggers an upstream refresh and polls our cache for up to ~10 seconds. If the refresh lands fresh contact within the window, the API deducts the wallet and returns `200`. If it doesn't land, returns `422 CONTACT_NOT_AVAILABLE` with `lastUpdateAttempt` for diagnosis — **wallet is not deducted**.\n3. **DIN never seeded:** if we have no record of this DIN at all (its containing CIN was never refreshed), returns `422 CONTACT_NOT_AVAILABLE` with `nextStep: POST /v1/companies/{cin}/unlock` — that endpoint seeds the chain. No upstream call, no deduction.\n\n**Idempotency:** repeating this on a DIN with an active contact unlock returns `409 ALREADY_UNLOCKED` — no double charge.\n\n**Billing**\n\nPay-gate. Charges the director-contact unlock fee from your wallet (your `directors.unlock` rate, see the [rate card](/pricing.html)). Wallet must have sufficient balance. The wallet-deduction guard ensures: if the upstream refresh fails or times out, wallet is not deducted.\n\n**Sandbox behavior**\n\n`fsk_test_*` keys on a sandbox-whitelisted DIN return `200 OK` with a synthetic unlock (`{ unlocked: true, sandbox: true }`) — no real writes, no upstream refresh, no real contact data ever leaked. Test keys on non-sandbox DINs return `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `503 SERVICE_UNAVAILABLE` — director-contact unlock disabled by ops (`DIRECTOR_CONTACT_UNLOCK_ENABLED=false`). Wallet **not** deducted\n- `400 INVALID_DIN` — DIN failed 8-digit format validation\n- `402 INSUFFICIENT_BALANCE` — wallet under the unlock price\n- `403 NO_ACCESS` — no pricing row for `directors.unlock`\n- `403 SANDBOX_ONLY` — test key on a non-sandbox DIN\n- `409 ALREADY_UNLOCKED` — unlock already exists for this DIN\n- `422 CONTACT_NOT_AVAILABLE` — upstream refresh failed/timed out, OR DIN not in our cache. Wallet **not** deducted\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [Cascade diagram](#description/how-filesure-data-works) (visual: hot path vs cold path with the ~10s upstream-refresh poll)\n- [Get director contact unlock status](#tag/director-contact/GET/v1/directors/{din}/unlock)\n- [Get director contact](#tag/director-contact/GET/v1/directors/{din}/contact) (the gated read)\n- [Unlock a company](#tag/documents-and-financials/POST/v1/companies/{cin}/unlock) (seeds the chain when 422 nextStep is given)\n",
        "operationId": "unlockDirectorContact",
        "parameters": [
          {
            "$ref": "#/components/parameters/DinPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Unlock created (live key) or sandbox synthetic (test key on sandbox DIN).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DirectorUnlockResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidDin"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "description": "`NO_ACCESS` (no pricing record) or `SANDBOX_ONLY` (test key on non-sandbox DIN).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "noAccess": {
                    "summary": "Customer has no pricing for directors.unlock",
                    "value": {
                      "error": {
                        "code": "NO_ACCESS",
                        "message": "No access to endpoint 'directors.unlock'. Contact support to enable access.",
                        "endpoint": "directors.unlock",
                        "catalogPricePaisa": 29900
                      }
                    }
                  },
                  "sandboxOnly": {
                    "summary": "Test key on a non-sandbox DIN",
                    "value": {
                      "error": {
                        "code": "SANDBOX_ONLY",
                        "message": "A test key only works on the sandbox companies and directors. They are listed in this response and at GET /v1/sandbox. Use one of those, or a live key.",
                        "sandboxCompanies": [
                          {
                            "cin": "U74999HR2015FTC056386",
                            "company": "CARS24 SERVICES PRIVATE LIMITED",
                            "knownAs": "Cars24"
                          },
                          {
                            "cin": "L93030DL2010PLC198141",
                            "company": "ETERNAL LIMITED",
                            "knownAs": "Eternal, formerly Zomato"
                          }
                        ],
                        "sandboxDirectors": [
                          {
                            "din": "11692472",
                            "fullName": "NILESH KASHINATH HIWALE"
                          }
                        ],
                        "nextStep": "GET /v1/sandbox"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Active contact unlock already exists for this DIN. No double charge.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlreadyUnlocked"
                }
              }
            }
          },
          "422": {
            "description": "Contact data could not be made available (refresh failed/timed out, or DIN\nrow missing). Wallet is not deducted.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactNotAvailable"
                },
                "examples": {
                  "missingRow": {
                    "summary": "DIN never seen by our master-data chain",
                    "value": {
                      "error": {
                        "code": "CONTACT_NOT_AVAILABLE",
                        "message": "We don't have contact data for this DIN yet. Update a containing company first.",
                        "nextStep": "POST /v1/companies/:cin/unlock"
                      }
                    }
                  },
                  "refreshTimeout": {
                    "summary": "Upstream refresh did not land contact in the polling window",
                    "value": {
                      "error": {
                        "code": "CONTACT_NOT_AVAILABLE",
                        "message": "Contact refresh did not return contact data within the allowed window.",
                        "lastUpdateAttempt": {
                          "status": "error",
                          "timestamp": "2026-05-01T07:30:00.000Z",
                          "errorMessage": "No data found in parsed resStr"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Director contact"
        ],
        "summary": "Get director contact unlock status",
        "description": "**What it returns**\n\nUnlock state for this DIN's contact tier, plus freshness metadata (`contactUpdatedAt` + `lastUpdateAttempt`) so customers can self-detect stale data. Three branches:\n\n- **Active unlock:** `unlocked: true`, `unlockedAt`, `expiresAt`, plus `contactUpdatedAt` and `lastUpdateAttempt` so customers can self-detect stale data.\n- **No unlock:** `unlocked: false`, `unlockPrice` (or `null` if customer has no pricing for `directors.unlock`). Same freshness metadata included.\n- **Sandbox** (test key + sandbox DIN): synthetic `unlocked: true, sandbox: true`. No real contact metadata leaked.\n\nRead-only — doesn't trigger an upstream refresh or write to our cache.\n\n**Billing**\n\nFree. No wallet deduction; not subject to pricing rows.\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) on a sandbox-whitelisted DIN return the synthetic branch above. Outside the whitelist: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_DIN` — DIN failed 8-digit format validation\n\nPlus the global auth/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [Unlock director's contact](#tag/director-contact/POST/v1/directors/{din}/unlock)\n- [Get director contact](#tag/director-contact/GET/v1/directors/{din}/contact)\n",
        "operationId": "getDirectorContactUnlock",
        "parameters": [
          {
            "$ref": "#/components/parameters/DinPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Unlock state for this DIN.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DirectorUnlockResponse"
                },
                "examples": {
                  "unlocked": {
                    "summary": "Active unlock with fresh contact data",
                    "value": {
                      "data": {
                        "din": "00002157",
                        "unlocked": true,
                        "unlockedAt": "2026-05-01T07:30:00.000Z",
                        "expiresAt": "2027-05-01T07:30:00.000Z",
                        "unlockPrice": 29900,
                        "contactUpdatedAt": "2026-04-15T12:00:00.000Z",
                        "lastUpdateAttempt": {
                          "status": "success",
                          "timestamp": "2026-04-15T12:00:00.000Z"
                        }
                      },
                      "meta": {}
                    }
                  },
                  "notUnlocked": {
                    "summary": "Customer hasn't unlocked this DIN's contact",
                    "value": {
                      "data": {
                        "din": "00002157",
                        "unlocked": false,
                        "unlockPrice": 29900,
                        "contactUpdatedAt": "2026-04-15T12:00:00.000Z",
                        "lastUpdateAttempt": {
                          "status": "success",
                          "timestamp": "2026-04-15T12:00:00.000Z"
                        }
                      },
                      "meta": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidDin"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Test key on a non-sandbox DIN.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/directors/{din}/contact": {
      "get": {
        "tags": [
          "Director contact"
        ],
        "summary": "Get director contact",
        "description": "**What it returns**\n\nDirector contact details — email, phone, and any other PII fields the MCA contact tier carries for this DIN. Returned only when the customer has an active contact-unlock for this DIN; otherwise returns the unlock-status JSON.\n\nDirector-contact data is sourced from a separate refresh path, **not** the company download cascade. If our cached contact is fresh (<365 days old), the unlock returns instantly. Otherwise the unlock POST triggers an upstream refresh and polls for up to ~10 seconds; see [POST /v1/directors/{din}/unlock](#tag/director-contact/POST/v1/directors/{din}/unlock) for how that works.\n\n**Billing**\n\nUnlock-gated. The contact unlock is per-DIN, separate from the company-level unlock. Without an active contact unlock for this DIN, this endpoint returns `200 { unlocked: false, unlockPrice }` instead of the contact data, with no charge. Inside the unlock window (1 year), each call is metered at your `directors.contact` rate (see the [rate card](/pricing.html)).\n\n**Sandbox behavior**\n\nTest keys (`fsk_test_*`) on a sandbox-whitelisted DIN return a synthetic unlock state and the cached contact when present. Outside the sandbox: `403 SANDBOX_ONLY`.\n\n**Common errors**\n\n- `400 INVALID_DIN` — DIN failed 8-digit format validation\n- `404` — director not found in our cache. The contact unlock won't seed the row either (it'll return `422 CONTACT_NOT_AVAILABLE`); instead, unlock a containing company first via [POST /v1/companies/{cin}/unlock](#tag/documents-and-financials/POST/v1/companies/{cin}/unlock), which seeds the whole director chain, then retry the contact unlock for this DIN.\n\nPlus the global auth/wallet/permission errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [Get director profile](#tag/look-up-the-register/GET/v1/directors/{din}) (no unlock; non-PII fields)\n- [Unlock director's contact](#tag/director-contact/POST/v1/directors/{din}/unlock)\n- [Get director contact unlock status](#tag/director-contact/GET/v1/directors/{din}/unlock)\n",
        "operationId": "getDirectorContact",
        "parameters": [
          {
            "$ref": "#/components/parameters/DinPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Contact data (when unlocked) or unlock status (when not unlocked).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "$ref": "#/components/schemas/UnlockStatus"
                    }
                  ]
                },
                "examples": {
                  "unlockedSuccess": {
                    "summary": "Sandbox DIN — contact unlocked (truncated)",
                    "value": {
                      "data": {
                        "din": "00002157",
                        "mobileNumber": "+91 98xxxxxx00",
                        "emailAddress": "example@cars24.in"
                      },
                      "meta": {}
                    }
                  },
                  "notUnlocked": {
                    "summary": "Customer hasn't unlocked this DIN's contact yet",
                    "value": {
                      "data": {
                        "unlocked": false,
                        "unlockPrice": 29900
                      },
                      "meta": {}
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/account/usage": {
      "get": {
        "tags": [
          "Your account"
        ],
        "summary": "Get wallet + usage",
        "description": "**What it returns**\n\nYour current wallet balance plus a per-endpoint breakdown of usage in the last 30 days. Money values are integers in **paisa** (1/100 of an INR rupee — e.g. `balancePaisa: 1000000` is ₹10,000.00). The `byEndpoint` array is sorted by `spendPaisa` descending and only contains endpoints actually called in the window — endpoints with zero usage are absent.\n\nUse this endpoint to surface \"Wallet: ₹XYZ\" + \"Top spend: companies.master at ₹ABC\" in your own dashboards. The 30-day window is rolling.\n\n**Billing**\n\nFree. No wallet deduction; not subject to pricing rows. Works with both `fsk_live_*` and `fsk_test_*` keys.\n\n**Sandbox behavior**\n\nTest keys see the same response shape with the same wallet (test/live keys share one wallet per customer). Sandbox-only test calls don't deduct, so they don't show up in `spendPaisa` totals — but they DO appear in usage logs with `priceChargedPaisa: 0`.\n\n**Common errors**\n\nJust the global auth errors — see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- The [Developer Portal usage page](/portal/dashboard/usage) for an interactive view of the same data\n",
        "operationId": "getAccountUsage",
        "responses": {
          "200": {
            "description": "Wallet balance and 30-day usage summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountUsageResponse"
                },
                "examples": {
                  "activeCustomer": {
                    "summary": "Active customer with realistic usage (truncated)",
                    "description": "Real customers may show 5–10 endpoints in `byEndpoint`; example shows top 3 spenders.",
                    "value": {
                      "data": {
                        "wallet": {
                          "balancePaisa": 873500,
                          "currency": "INR"
                        },
                        "usage": {
                          "last30Days": {
                            "totalCalls": 2340,
                            "totalSpendPaisa": 126500,
                            "byEndpoint": [
                              {
                                "endpoint": "companies.master",
                                "calls": 412,
                                "spendPaisa": 41200
                              },
                              {
                                "endpoint": "companies.unlock",
                                "calls": 3,
                                "spendPaisa": 66000
                              },
                              {
                                "endpoint": "companies.filings.download",
                                "calls": 1925,
                                "spendPaisa": 19250
                              }
                            ]
                          }
                        }
                      },
                      "meta": {
                        "generatedAt": "2026-05-01T07:45:12.000Z"
                      }
                    }
                  },
                  "newCustomer": {
                    "summary": "New customer with no spend yet",
                    "value": {
                      "data": {
                        "wallet": {
                          "balancePaisa": 1000000,
                          "currency": "INR"
                        },
                        "usage": {
                          "last30Days": {
                            "totalCalls": 0,
                            "totalSpendPaisa": 0,
                            "byEndpoint": []
                          }
                        }
                      },
                      "meta": {
                        "generatedAt": "2026-05-01T07:45:12.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`ACCOUNT_DISABLED` — the customer account associated with this API key has been deactivated. Contact support to re-enable.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/account/pricing": {
      "get": {
        "tags": [
          "Your account"
        ],
        "summary": "Your rate card",
        "description": "**What it returns**\n\nThe price your account pays for each endpoint, in **paisa**, read from the same pricing rows every billed call is charged from, so what you see here is exactly what a call will cost. One row per endpoint key you hold a price for; an endpoint with no row is one your account cannot call (`403 NO_ACCESS`). `defaultPricePaisa` is the published rate-card price for that endpoint, so you can see where your account has a negotiated rate; it is `null` for endpoints not on the public rate card.\n\nUse it to show your own users what an action will cost before they take it. Unlocks appear under their keys (`companies.unlock`, `directors.unlock`) at the unlock fee; per-call endpoints at the per-call fee.\n\n**Billing**\n\nFree. No wallet deduction; not subject to pricing rows.\n\n**Sandbox behavior**\n\nTest keys see the same rates as live keys (one rate card per account); sandbox calls are never charged regardless.\n\n**Common errors**\n\nJust the global auth errors, see the [error codes table](#description/responses-and-errors).\n\n**See also**\n\n- [Billing and the wallet](#description/billing-and-the-wallet)\n- [Get wallet + usage](#tag/your-account/GET/v1/account/usage)\n",
        "operationId": "getAccountPricing",
        "responses": {
          "200": {
            "description": "The caller's effective rates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountPricingResponse"
                },
                "example": {
                  "data": {
                    "currency": "INR",
                    "rates": [
                      {
                        "endpoint": "companies.documents.fetch",
                        "pricePerCallPaisa": 15000,
                        "defaultPricePaisa": 15000,
                        "effectiveFrom": "2026-09-14T00:00:00.000Z"
                      },
                      {
                        "endpoint": "companies.master",
                        "pricePerCallPaisa": 500,
                        "defaultPricePaisa": 500,
                        "effectiveFrom": "2026-07-27T00:00:00.000Z"
                      },
                      {
                        "endpoint": "companies.unlock",
                        "pricePerCallPaisa": 33000,
                        "defaultPricePaisa": 33000,
                        "effectiveFrom": "2026-07-27T00:00:00.000Z"
                      },
                      {
                        "endpoint": "companies.update",
                        "pricePerCallPaisa": 100,
                        "defaultPricePaisa": 100,
                        "effectiveFrom": "2026-09-14T00:00:00.000Z"
                      }
                    ]
                  },
                  "meta": {
                    "requestId": "…",
                    "generatedAt": "2026-09-15T09:30:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/wallet/transactions": {
      "get": {
        "tags": [
          "Your account"
        ],
        "summary": "Wallet ledger",
        "description": "Every credit to your wallet, newest first: top-ups, refunds and manual credits. Charges are not\nledger rows; they are usage, and appear in [usage](#tag/your-account/GET/v1/account/usage) and on\nevery metered response as `meta.priceChargedPaisa`.\n\n`type` is `recharge`, `refund` or `admin_credit`. `balanceAfterPaisa` is the wallet balance right\nafter that row landed, so the ledger reads as a running statement. `referenceId` links a top-up\nto its recharge order or a refund to what it refunds.\n\n**Billing:** free. **Sandbox:** same response on a test key; test and live keys share one wallet.\n",
        "operationId": "getWalletTransactions",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ledger rows, newest first.",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "6aa7a0c1b22e2991f01372ff",
                      "type": "recharge",
                      "source": "zoho",
                      "amountPaisa": 1000000,
                      "balanceAfterPaisa": 1129390,
                      "referenceId": "pay_0123456789",
                      "metadata": null,
                      "createdAt": "2026-09-10T08:12:40.000Z"
                    },
                    {
                      "id": "6a9db6f052dc117ec46157c2",
                      "type": "refund",
                      "source": "system",
                      "amountPaisa": 15000,
                      "balanceAfterPaisa": 129390,
                      "referenceId": null,
                      "metadata": {
                        "reason": "Refund of a charge that did no work"
                      },
                      "createdAt": "2026-09-06T18:55:02.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 2,
                    "totalPages": 1,
                    "requestId": "…"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/wallet/recharge": {
      "post": {
        "tags": [
          "Your account"
        ],
        "summary": "Top up the wallet",
        "description": "Creates a payment order for the amount of credit you want and returns the session that opens the\nhosted checkout. GST at 18% is added on top: `amountPaisa` is the credit you receive,\n`totalPaisa` is what you pay. Credit lands in the wallet when the payment is confirmed; read\n[recharge status](#tag/your-account/GET/v1/account/wallet/recharge/{orderId}/status) to follow it,\nand expect a GST invoice against the order once it is paid.\n\nRequires a live key (`403 SANDBOX_NOT_ALLOWED` on a test key) and a completed\n[billing profile](#tag/your-account/GET/v1/account/billing), since the invoice needs it.\nCredit must be between ₹10,000 and ₹10,00,000 per order.\n\n**Billing:** creating the order is free; you pay at the checkout.\n",
        "operationId": "createWalletRecharge",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amountPaisa"
                ],
                "properties": {
                  "amountPaisa": {
                    "type": "integer",
                    "description": "Credit to add, in paisa. ₹10,000 to ₹10,00,000.",
                    "example": 1000000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment order created; open the checkout with `paymentsSessionId`.",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "orderId": "6aa7a0c1b22e2991f01372ff",
                    "paymentsSessionId": 2000000012345678800,
                    "accountId": "60064718354",
                    "amountPaisa": 1000000,
                    "gstPaisa": 180000,
                    "totalPaisa": 1180000
                  },
                  "meta": {
                    "requestId": "…"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_AMOUNT` (not a positive integer) or `AMOUNT_OUT_OF_RANGE` (outside ₹10,000 to ₹10,00,000).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "`SANDBOX_NOT_ALLOWED` on a test key, or `BILLING_INCOMPLETE` until the billing profile is set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/account/wallet/recharge/{orderId}/status": {
      "get": {
        "tags": [
          "Your account"
        ],
        "summary": "Recharge status",
        "description": "The state of one top-up order: `pending` until the payment is confirmed, then `paid` (credit is in\nthe wallet), or `failed` / `expired`. Read-only; polling it never credits anything. A payment that\nwas confirmed but has not yet shown here is picked up by a periodic check within about fifteen\nminutes.\n\n**Billing:** free.\n",
        "operationId": "getWalletRechargeStatus",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `orderId` returned when the order was created."
          }
        ],
        "responses": {
          "200": {
            "description": "Order state.",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "orderId": "6aa7a0c1b22e2991f01372ff",
                    "status": "paid",
                    "amountPaisa": 1000000,
                    "gstPaisa": 180000,
                    "totalPaisa": 1180000,
                    "currency": "INR",
                    "paymentsSessionId": 2000000012345678800,
                    "createdAt": "2026-09-10T08:12:40.000Z",
                    "paidAt": "2026-09-10T08:14:03.000Z"
                  },
                  "meta": {
                    "requestId": "…"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_ORDER_ID`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "`RECHARGE_NOT_FOUND`: no such order on your account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/account/billing": {
      "get": {
        "tags": [
          "Your account"
        ],
        "summary": "Billing profile",
        "description": "The name, address and tax details your GST invoices are issued to. `null` until you set it with\n[PUT /v1/account/billing](#tag/your-account/PUT/v1/account/billing); a top-up needs it.\n\n**Billing:** free.\n",
        "operationId": "getBillingProfile",
        "responses": {
          "200": {
            "description": "The profile, or `billing: null`.",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "billing": {
                      "billingType": "business",
                      "businessName": "Example Analytics Private Limited",
                      "contactName": "Priya Nair",
                      "email": "finance@example.in",
                      "phone": "+91 98xxxxxx00",
                      "gstin": "27AAAAA0000A1Z5",
                      "address": "4th Floor, 12 MG Road",
                      "city": "Mumbai",
                      "state": "27",
                      "zipCode": "400001",
                      "country": "India"
                    }
                  },
                  "meta": {
                    "requestId": "…"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "put": {
        "tags": [
          "Your account"
        ],
        "summary": "Set the billing profile",
        "description": "Replaces the billing profile. `billingType` is `business` or `consumer`. A business must give\n`businessName`, a valid `gstin` and an `address`; the state of supply is read from the GSTIN. A\nconsumer in India must give a two-digit `state` code. `contactName` is always required; `email`,\n`phone`, `city` and `zipCode` are optional. Values are trimmed and the GSTIN upper-cased before\nsaving; the response returns the saved profile.\n\n**Billing:** free.\n",
        "operationId": "putBillingProfile",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "billingType": "business",
                "businessName": "Example Analytics Private Limited",
                "contactName": "Priya Nair",
                "email": "finance@example.in",
                "gstin": "27AAAAA0000A1Z5",
                "address": "4th Floor, 12 MG Road",
                "city": "Mumbai",
                "zipCode": "400001",
                "country": "India"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The saved profile.",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "billing": {
                      "billingType": "business",
                      "businessName": "Example Analytics Private Limited",
                      "contactName": "Priya Nair",
                      "email": "finance@example.in",
                      "gstin": "27AAAAA0000A1Z5",
                      "address": "4th Floor, 12 MG Road",
                      "city": "Mumbai",
                      "state": "27",
                      "zipCode": "400001",
                      "country": "India"
                    }
                  },
                  "meta": {
                    "requestId": "…"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_BILLING`, `INVALID_BILLING_TYPE`, `MISSING_CONTACT_NAME`, `MISSING_BUSINESS_NAME`, `MISSING_GSTIN`, `INVALID_GSTIN`, `MISSING_ADDRESS`, `MISSING_STATE` or `INVALID_STATE`; the message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/recharges": {
      "get": {
        "tags": [
          "Your account"
        ],
        "summary": "Top-up history",
        "description": "Every top-up order on your account, newest first, with its payment state and invoice state.\n`canDownloadInvoice` is `true` once the GST invoice for a paid order has been issued; fetch it\nfrom [the invoice endpoint](#tag/your-account/GET/v1/account/invoices/{rechargeId}/pdf).\n\n**Billing:** free.\n",
        "operationId": "getRecharges",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Orders, newest first.",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "orderId": "6aa7a0c1b22e2991f01372ff",
                      "amountPaisa": 1000000,
                      "gstPaisa": 180000,
                      "totalPaisa": 1180000,
                      "status": "paid",
                      "invoiceStatus": "invoiced",
                      "invoiceNumber": "FS/2026-27/000123",
                      "invoiceDate": "2026-09-10",
                      "canDownloadInvoice": true,
                      "createdAt": "2026-09-10T08:12:40.000Z",
                      "paidAt": "2026-09-10T08:14:03.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1,
                    "totalPages": 1,
                    "requestId": "…"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/account/invoices/{rechargeId}/pdf": {
      "get": {
        "tags": [
          "Your account"
        ],
        "summary": "Download a GST invoice",
        "description": "The GST invoice for one paid top-up, as a PDF. This is the one account endpoint that does not\nreturn the JSON envelope: the response body is the file, with a `Content-Disposition` filename\nof the invoice number.\n\n**Billing:** free.\n",
        "operationId": "getInvoicePdf",
        "parameters": [
          {
            "name": "rechargeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `orderId` of a paid top-up."
          }
        ],
        "responses": {
          "200": {
            "description": "The invoice PDF.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_ORDER_ID`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "`RECHARGE_NOT_FOUND`: no such order on your account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`INVOICE_NOT_READY`: the order is not paid yet, or its invoice has not been issued yet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`INVOICING_UNAVAILABLE`: invoicing is temporarily unavailable; try again later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "FileSure API key. Format: `fsk_live_<uuid>` (production) or `fsk_test_<uuid>` (sandbox).\n\nGenerate from the [Developer Portal](/portal/dashboard/keys).\n"
      }
    },
    "parameters": {
      "CinPath": {
        "in": "path",
        "name": "cin",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "U74999HR2015FTC056386",
        "description": "21-character Corporate Identification Number (CIN)."
      },
      "CompanyIdentifierPath": {
        "in": "path",
        "name": "cin",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Company identifier. One of three formats — accepted on `/v1/companies/:cin`:\n\n- **CIN** — 21-character Indian Corporate Identification Number (e.g., U72900PB2022PTC055860)\n- **FCIN** — 6-character Foreign Company Identification Number (e.g., F07030)\n- **LLPIN** — 8-character LLP Identification Number (e.g., AAA-1234)\n\nPair with the optional `?idType=cin|fcin|llpin` query param for stricter validation; auto-detect when omitted.\n\nTest keys (`fsk_test_*`) can only call identifiers in the **Sandbox** allowlist — see the Sandbox tag in the sidebar for the full list of 50 sample CINs and 2 LLPINs.\n",
        "example": "U72200KA2013PLC097389"
      },
      "DinPath": {
        "in": "path",
        "name": "din",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "08087425",
        "description": "8-digit Director Identification Number (DIN). Test keys (`fsk_test_*`) can only call DINs in the **Sandbox** allowlist — see the Sandbox tag in the sidebar for the full list.\n"
      },
      "FormTypePath": {
        "in": "path",
        "name": "formType",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "AOC-4",
        "description": "MCA form whose extraction to access. Today only `AOC-4` (annual financials) is extracted; future\nforms will be added as additional extractors come online. Case-insensitive — `aoc-4` and `AOC-4`\nboth match.\n"
      }
    },
    "schemas": {
      "SuccessEnvelope": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "oneOf": [
              {
                "type": "object"
              },
              {
                "type": "array"
              }
            ]
          },
          "meta": {
            "type": "object",
            "properties": {
              "page": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "totalPages": {
                "type": "integer"
              },
              "priceChargedPaisa": {
                "type": "integer",
                "description": "Amount charged to the wallet for this call, in paisa. Present on every\nbilled and unlock-gated 2xx response. `0` on sandbox calls (test keys\nnever deduct).\n",
                "example": 100
              },
              "walletBalanceAfterPaisa": {
                "type": "integer",
                "description": "Wallet balance after this call's deduction, in paisa. Present on every\nbilled and unlock-gated 2xx response. `0` on sandbox calls.\n",
                "example": 999900
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "NO_ACCESS"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "NoAccessError": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Error"
          },
          {
            "type": "object",
            "properties": {
              "error": {
                "type": "object",
                "properties": {
                  "endpoint": {
                    "type": "string",
                    "description": "The endpoint key for which no pricing was found. Present on\n`NO_ACCESS` only.\n"
                  },
                  "catalogPricePaisa": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Default rate-card price (paisa) for this endpoint, or `null`\nif the endpoint has no default. Lets the caller see what they\nwould pay if access were enabled. Present on `NO_ACCESS` only.\n"
                  }
                }
              }
            }
          }
        ]
      },
      "UnlockStatus": {
        "type": "object",
        "description": "Returned by unlock-gated endpoints when the customer has no active unlock.\n`data` is locked to `{unlocked, unlockPrice}` (no extra properties) so the\nenvelope is unambiguously distinguishable from real success payloads under\na `oneOf` — required for spec validators to accept the data fetch route's\n`oneOf: [ExtractionDataResponse, UnlockStatus]` shape.\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "unlocked"
            ],
            "additionalProperties": false,
            "properties": {
              "unlocked": {
                "type": "boolean",
                "example": false
              },
              "unlockPrice": {
                "type": "integer",
                "nullable": true,
                "description": "Price in paisa to unlock this resource. `null` if no pricing assigned.",
                "example": 20000
              }
            }
          },
          "meta": {
            "type": "object"
          }
        }
      },
      "UnlockResponse": {
        "type": "object",
        "description": "Returned by both `POST /unlock` (`202` — fresh unlock created) and `GET /unlock`\n(`200` — status check). The same envelope is used regardless of state; field\npresence varies (e.g., `expiresAt: null` and `sandbox: true` for synthetic\nsandbox responses).\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "cin",
              "unlocked",
              "job"
            ],
            "properties": {
              "cin": {
                "type": "string",
                "example": "U72900PB2022PTC055860"
              },
              "unlocked": {
                "type": "boolean"
              },
              "unlockedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When the unlock was created. `null` for sandbox synthetic responses."
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "1 year after `unlockedAt`. `null` for sandbox."
              },
              "unlockPrice": {
                "type": "integer",
                "nullable": true,
                "description": "Per-unlock price in paisa (₹ × 100). `null` if no pricing exists for this customer.",
                "example": 1000
              },
              "sandbox": {
                "type": "boolean",
                "description": "Present only on synthetic sandbox responses (test key + sandbox CIN).",
                "example": true
              },
              "job": {
                "nullable": true,
                "description": "Live snapshot of the background refresh job for this unlock. `null` immediately\nafter `POST /unlock` (the refresh hasn't been registered yet) or for sandbox responses.\n",
                "allOf": [
                  {
                    "$ref": "#/components/schemas/UnlockJob"
                  }
                ]
              }
            }
          },
          "meta": {
            "type": "object"
          }
        }
      },
      "UnlockJob": {
        "type": "object",
        "description": "Live snapshot of the download + extraction job for this CIN. Watch\n`processingStages.documentDownloadV3.status` for the primary download\nsignal — progresses `pending` → `in_progress` → `success`, usually within\nminutes once the downloader picks up the job.\n\nField set is intentionally narrow: we surface only the document-download\nstage, the financial extraction stage, and the two `*ExTriggered` flags.\nInternal identifiers, persistence metadata, internal email-notification\ntracking, and legacy stages (always-pending) are not surfaced.\n",
        "required": [
          "id",
          "processingStages"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Internal job ID, useful for support / debugging.",
            "example": "69e35b8a39d43c8b8b579a4e"
          },
          "processingStages": {
            "type": "object",
            "description": "Per-stage progress. Stage keys are added as work progresses —\n`documentDownloadV3` is always present once the background refresh\nhas registered the job; `financials`, `financialExTriggered`, and\n`mgt7ExTriggered` appear after the document download completes and\nextraction kicks off.\n",
            "properties": {
              "documentDownloadV3": {
                "type": "object",
                "description": "PDF download from MCA. The status field is the primary completion signal.",
                "required": [
                  "status",
                  "lastUpdated"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "pending",
                      "in_progress",
                      "success"
                    ],
                    "example": "pending"
                  },
                  "totalDocuments": {
                    "type": "integer",
                    "example": 0
                  },
                  "downloadedDocuments": {
                    "type": "integer",
                    "example": 0
                  },
                  "pendingDocuments": {
                    "type": "integer",
                    "example": 0
                  },
                  "errorDocuments": {
                    "type": "integer"
                  },
                  "completionPercentage": {
                    "type": "number",
                    "example": 0
                  },
                  "lastUpdated": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "completedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "totalZipFiles": {
                    "type": "integer"
                  },
                  "zipFiles": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "filename": {
                          "type": "string"
                        },
                        "blob_url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "total_size_bytes": {
                          "type": "integer"
                        },
                        "successful_files": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              },
              "financials": {
                "type": "object",
                "description": "Present only after the financial-extraction pipeline runs (post-V3 success).\n`perFiling[]` reports per-period extraction status; `summary` aggregates counts.\n",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "pending",
                      "in_progress",
                      "success",
                      "failed"
                    ]
                  },
                  "progress": {
                    "type": "number"
                  },
                  "startedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "completedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "summary": {
                    "type": "object",
                    "properties": {
                      "filingsSeen": {
                        "type": "integer"
                      },
                      "processed": {
                        "type": "integer"
                      },
                      "skipped": {
                        "type": "integer"
                      },
                      "failed": {
                        "type": "integer"
                      }
                    }
                  },
                  "perFiling": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  }
                }
              },
              "financialExTriggered": {
                "type": "boolean",
                "description": "True once the financial-extraction trigger has fired downstream."
              },
              "mgt7ExTriggered": {
                "type": "boolean",
                "description": "True once the MGT-7 extraction trigger has fired downstream."
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DirectorUnlockResponse": {
        "type": "object",
        "description": "Returned by `POST /v1/directors/{din}/unlock` (`200`) and\n`GET /v1/directors/{din}/unlock` (`200`). Same envelope used regardless\nof unlock state.\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "din",
              "unlocked"
            ],
            "properties": {
              "din": {
                "type": "string",
                "example": "08087425"
              },
              "unlocked": {
                "type": "boolean"
              },
              "unlockedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When the unlock was created. `null` for sandbox or no-unlock states."
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "1 year after `unlockedAt`. `null` for sandbox or no-unlock states."
              },
              "unlockPrice": {
                "type": "integer",
                "nullable": true,
                "description": "Per-unlock price in paisa (₹ × 100). `null` if no pricing exists for this customer.",
                "example": 1000
              },
              "sandbox": {
                "type": "boolean",
                "description": "Present only on synthetic sandbox responses (test key + sandbox DIN).",
                "example": true
              },
              "contactUpdatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When this DIN's cached contact was last refreshed. Use it to self-detect\nstale contact data (we treat anything <365 days old as fresh and won't\nre-trigger refresh on the next unlock attempt). `null` for sandbox.\n"
              },
              "lastUpdateAttempt": {
                "nullable": true,
                "description": "Latest upstream refresh attempt status. Surfaces success/failure\ndiagnostics. `null` for sandbox or when no refresh has ever been attempted.\n",
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "`success` or `error`.",
                    "example": "success"
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "errorMessage": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object"
          }
        }
      },
      "ContactNotAvailable": {
        "type": "object",
        "description": "422 body when contact data could not be made available — either we have\nno record of this DIN at all (need to seed via a containing-company unlock),\nor the upstream refresh failed/timed out within the polling window.\nWallet is **not** deducted in either case.\n",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "CONTACT_NOT_AVAILABLE"
              },
              "message": {
                "type": "string",
                "example": "We don't have contact data for this DIN yet. Update a containing company first."
              },
              "nextStep": {
                "type": "string",
                "description": "Hint at the next user-actionable endpoint (only present when the row is missing entirely).",
                "example": "POST /v1/companies/:cin/unlock"
              },
              "lastUpdateAttempt": {
                "nullable": true,
                "description": "Latest upstream refresh attempt status (only present on refresh-failure paths).",
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "example": "error"
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "errorMessage": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "AlreadyUnlocked": {
        "type": "object",
        "description": "409 conflict body when an active unlock already exists for this CIN.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "ALREADY_UNLOCKED"
              },
              "message": {
                "type": "string",
                "example": "An active unlock exists for this CIN. Use GET /unlock to check status."
              },
              "unlockedAt": {
                "type": "string",
                "format": "date-time"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              },
              "jobId": {
                "type": "string",
                "nullable": true,
                "description": "Background refresh job ID, if it has already been registered; `null` otherwise."
              }
            }
          }
        }
      },
      "FilingListItem": {
        "type": "object",
        "required": [
          "createdAt",
          "updatedAt"
        ],
        "description": "Raw verbatim MCA fields, with one deliberate omission: MCA's internal `documentCode` is never surfaced. The opaque `filingId` (`flg_…`) is the customer-facing handle — pass it to the download endpoint.\n\nStrings `\"NULL\"` (literal) are normalised to JSON `null` in the response.\n",
        "properties": {
          "filingId": {
            "type": "string",
            "pattern": "^flg_[A-Za-z0-9_-]+$",
            "description": "Opaque identifier — AES-encrypted token over `(cin, documentCode)`. Pass to the download endpoint as `:filingId`.",
            "example": "flg_Ui2a1vItyyFYoAGGmefipN0RoT9EtmjHQz4KfzMeVE"
          },
          "formId": {
            "type": "string",
            "nullable": true,
            "example": "MGT-7"
          },
          "documentCategory": {
            "type": "string",
            "nullable": true,
            "example": "Annual Returns and Balance Sheet eForms"
          },
          "attachmentLabel": {
            "type": "string",
            "nullable": true,
            "example": "SIGNEDDPT3"
          },
          "dateOfFiling": {
            "type": "string",
            "nullable": true,
            "description": "DD/MM/YYYY string verbatim from MCA.",
            "example": "14/06/2021"
          },
          "dscUploadDate": {
            "type": "string",
            "nullable": true
          },
          "paymentDate": {
            "type": "string",
            "nullable": true,
            "example": "14/06/2021"
          },
          "fileName": {
            "type": "string",
            "nullable": true,
            "example": "Form DPT-3"
          },
          "fileSize": {
            "type": "integer",
            "nullable": true,
            "description": "File size in bytes.",
            "example": 2349981
          },
          "fileType": {
            "type": "string",
            "nullable": true,
            "example": "pdf"
          },
          "numberOfPages": {
            "type": "integer",
            "nullable": true,
            "example": 7
          },
          "year": {
            "type": "integer",
            "nullable": true,
            "example": 2021
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When this filing row was first written to our cache. ISO 8601. `null` for LLP rows (LLP filings have no source timestamps)."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Last write to this filing row (refresh / re-download). ISO 8601. `null` for LLP rows — same reason as `createdAt`."
          }
        }
      },
      "FilingsListResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilingListItem"
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "page": {
                "type": "integer",
                "example": 1
              },
              "limit": {
                "type": "integer",
                "example": 50
              },
              "total": {
                "type": "integer",
                "example": 8743
              },
              "totalPages": {
                "type": "integer",
                "example": 175
              }
            }
          }
        }
      },
      "AccountPricingResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "currency",
              "rates"
            ],
            "properties": {
              "currency": {
                "type": "string",
                "example": "INR"
              },
              "rates": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "endpoint",
                    "pricePerCallPaisa",
                    "defaultPricePaisa",
                    "effectiveFrom"
                  ],
                  "properties": {
                    "endpoint": {
                      "type": "string",
                      "description": "Endpoint key, the same key shown in usage and in 403 NO_ACCESS errors.",
                      "example": "companies.master"
                    },
                    "pricePerCallPaisa": {
                      "type": "integer",
                      "description": "What your account pays per call (or per unlock), in paisa.",
                      "example": 500
                    },
                    "defaultPricePaisa": {
                      "type": "integer",
                      "nullable": true,
                      "description": "The published rate-card price for this endpoint, or null if it is not on the public card.",
                      "example": 500
                    },
                    "effectiveFrom": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "generatedAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        }
      },
      "AccountUsageResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "wallet",
              "usage"
            ],
            "properties": {
              "wallet": {
                "type": "object",
                "required": [
                  "balancePaisa",
                  "currency"
                ],
                "properties": {
                  "balancePaisa": {
                    "type": "integer",
                    "description": "Current wallet balance in paisa (1/100 INR). Hard-blocks at 0 — top up before further billed calls.",
                    "example": 50000
                  },
                  "currency": {
                    "type": "string",
                    "example": "INR"
                  }
                }
              },
              "usage": {
                "type": "object",
                "required": [
                  "last30Days"
                ],
                "properties": {
                  "last30Days": {
                    "type": "object",
                    "required": [
                      "totalCalls",
                      "totalSpendPaisa",
                      "byEndpoint"
                    ],
                    "properties": {
                      "totalCalls": {
                        "type": "integer",
                        "example": 42
                      },
                      "totalSpendPaisa": {
                        "type": "integer",
                        "description": "Total spend in paisa across all endpoints in the last 30 days.",
                        "example": 12500
                      },
                      "byEndpoint": {
                        "type": "array",
                        "description": "Per-endpoint breakdown, sorted by `spendPaisa` descending. Only includes endpoints with at least one call in the window.",
                        "items": {
                          "type": "object",
                          "required": [
                            "endpoint",
                            "calls",
                            "spendPaisa"
                          ],
                          "properties": {
                            "endpoint": {
                              "type": "string",
                              "description": "Endpoint identifier (dotted-constant form, e.g. `companies.master`).",
                              "example": "companies.master"
                            },
                            "calls": {
                              "type": "integer",
                              "example": 30
                            },
                            "spendPaisa": {
                              "type": "integer",
                              "example": 9000
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "generatedAt"
            ],
            "properties": {
              "generatedAt": {
                "type": "string",
                "format": "date-time",
                "description": "ISO timestamp when the response was computed."
              }
            }
          }
        }
      },
      "ExtractionsListResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "availableFormTypes"
            ],
            "properties": {
              "availableFormTypes": {
                "type": "array",
                "items": {
                  "type": "string",
                  "example": "AOC-4"
                },
                "description": "Sorted list of form types FileSure has extracted for this CIN. Empty array when no extractions exist."
              }
            }
          },
          "meta": {
            "type": "object",
            "example": {}
          }
        }
      },
      "ExtractionYearsResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "formType",
              "availableYears"
            ],
            "properties": {
              "formType": {
                "type": "string",
                "example": "AOC-4",
                "description": "Canonical form type, normalized to upper case."
              },
              "availableYears": {
                "type": "array",
                "description": "Calendar end-years (descending) where any extraction exists for this form type. Union across `filing_scope` — pick scope on the data endpoint.",
                "items": {
                  "type": "integer",
                  "example": 2024
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "example": {}
          }
        }
      },
      "ExtractionDataResponse": {
        "type": "object",
        "description": "Extracted financial statement for a specific (cin, formType, year, scope). Surfaced verbatim from the\nextraction pipeline — no derived fields, no UI shaping. Each fact in `balance_sheet`, `profit_and_loss`,\nand `cash_flow` carries a `qname` (XBRL element name), `value` (numeric or string), and `unit`.\nOptional verbosity fields (`decimals`, `labels`, `context`, `order_hint`) appear only when enabled\nupstream — design for mixed presence.\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "cin",
              "period_end",
              "filing_scope",
              "balance_sheet",
              "profit_and_loss",
              "cash_flow",
              "metadata"
            ],
            "properties": {
              "cin": {
                "type": "string",
                "example": "U72900PB2022PTC055860"
              },
              "period_start": {
                "type": "string",
                "nullable": true,
                "description": "Reporting period start date — string `YYYY-MM-DD`.",
                "example": "2023-04-01"
              },
              "period_end": {
                "type": "string",
                "description": "Reporting period end date — string `YYYY-MM-DD`.",
                "example": "2024-03-31"
              },
              "filing_scope": {
                "type": "string",
                "enum": [
                  "standalone",
                  "consolidated",
                  "unknown"
                ],
                "example": "standalone"
              },
              "taxonomy_id": {
                "type": "string",
                "nullable": true,
                "description": "XBRL taxonomy used for the extraction.",
                "example": "in-gaap-2016"
              },
              "balance_sheet": {
                "type": "array",
                "description": "Balance-sheet facts. Each item is an object with `qname`, `value`, `unit` and optional verbosity fields — passthrough so additions surface without redeploy.",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "profit_and_loss": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "cash_flow": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "metadata": {
                "type": "object",
                "description": "Filing-source metadata. `metadata.source` carries `dateOfFiling`, `paymentDate`, `year`, etc. — but **never** the MCA-internal `documentCode`, storage pointers (`storage_account`, `container`, `azureFileName`), or download URLs.\n",
                "additionalProperties": true
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "createdAt",
              "updatedAt"
            ],
            "properties": {
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When FileSure first extracted this filing."
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Last write to this extraction (re-runs are idempotent)."
              }
            }
          }
        }
      },
      "Mgt7ExtractionDataResponse": {
        "type": "object",
        "description": "Extracted MGT-7 (Annual Return) data for a specific (cin, year). Surfaced verbatim from MCA's filed\nform — no derived totals, no UI flattening. The `form_type` field indicates which variant was\nactually filed (`MGT-7` for large companies, `MGT-7A` for small companies / OPC); MGT-7A omits\nsome sections (no `kmp`, no `remuneration`).\n\nSub-objects (`share_capital`, `share_holding_pattern`, `meetings`, `kmp`, `business_activities`,\netc.) use `additionalProperties: true` so MCA additions and Tanim's extractor enhancements surface\nwithout redeploying this spec.\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "cin",
              "form_type",
              "fy_end"
            ],
            "properties": {
              "cin": {
                "type": "string",
                "example": "L15400TG2009PLC062658"
              },
              "form_type": {
                "type": "string",
                "enum": [
                  "MGT-7",
                  "MGT-7A"
                ],
                "description": "Which actual filing variant. MGT-7A omits some sections (no kmp, no remuneration); the field exists so customer code can branch on it.",
                "example": "MGT-7"
              },
              "srn": {
                "type": "string",
                "description": "MCA Service Request Number for this filing (the public reference shown on MCA portal).",
                "example": "AC0745199"
              },
              "fy_start": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Financial year start (ISO 8601, UTC midnight). Omitted when MCA's form left it blank.",
                "example": "2024-04-01T00:00:00.000Z"
              },
              "fy_end": {
                "type": "string",
                "format": "date-time",
                "description": "Financial year end (ISO 8601, UTC midnight). Always present.",
                "example": "2025-03-31T00:00:00.000Z"
              },
              "agm_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Annual General Meeting date."
              },
              "filing_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Date MCA accepted the filing."
              },
              "is_opc": {
                "type": "boolean",
                "description": "One-Person-Company flag."
              },
              "is_share_listed": {
                "type": "boolean",
                "description": "Whether the company's shares are listed on any stock exchange."
              },
              "number_stock_exchange": {
                "type": "integer",
                "description": "Count of stock exchanges the company is listed on. `0` for unlisted companies."
              },
              "stock_exchanges": {
                "type": "array",
                "description": "List of exchange identifiers. Empty array for unlisted companies.",
                "items": {
                  "type": "string"
                }
              },
              "num_business_actv": {
                "type": "integer"
              },
              "business_activities": {
                "type": "array",
                "description": "Principal business activities, each carrying NIC code + description + turnover %.",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "num_rtas": {
                "type": "integer",
                "description": "Count of Registrar and Transfer Agents."
              },
              "rtas": {
                "type": "array",
                "description": "Registrar/Transfer Agent records. Empty when the company has none (common for unlisted).",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "num_holding_subs": {
                "type": "integer",
                "description": "Count of holding / subsidiary / associate / joint-venture companies."
              },
              "holding_subs": {
                "type": "array",
                "description": "Holding/subsidiary/associate corporate records.",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "share_capital": {
                "type": "object",
                "description": "Authorised/issued/subscribed/paid-up breakdown for equity and preference shares, plus\nan unclassified-total and the paid-up breakup. Numeric values are in INR rupees\n(not paise — MCA filings use whole-rupee units).\n",
                "additionalProperties": true
              },
              "share_holding_pattern": {
                "type": "object",
                "nullable": true,
                "description": "Promoter / public split + FII details. Surfaced as `null` for OPCs (single-shareholder\ncompanies — there's no \"shareholding pattern\" to report).\n",
                "additionalProperties": true
              },
              "turnover": {
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "string"
                  }
                ],
                "description": "Total turnover for the fiscal year, in INR rupees. Surfaced as a JS number when the value\nfits in `Number.MAX_SAFE_INTEGER` (≈ 9 quadrillion); else as a numeric string to preserve\nprecision. Customers should treat large monetary values defensively.\n",
                "example": 6887017470
              },
              "net_worth": {
                "type": "number",
                "description": "Company net worth (assets − liabilities) in INR rupees.",
                "example": 888754630
              },
              "kmp": {
                "type": "array",
                "description": "Directors + Key Managerial Personnel. **MGT-7 only** — omitted entirely on MGT-7A filings.\nEach entry carries `din`, `name`, `designation`, etc. — keys are MCA's own.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "meetings": {
                "type": "object",
                "description": "Meeting counts + attendance for Members, Board, and Committees. Keys: `board_meetings`,\n`board_total`, `members_meetings`, `members_total`, `committee_meetings`, `committee_total`,\n`directors_attendance`.\n",
                "additionalProperties": true
              },
              "remuneration": {
                "type": "object",
                "description": "Directors + Managing Director + CFO + Company Secretary remuneration details.\n**MGT-7 only** — omitted entirely on MGT-7A filings.\n",
                "additionalProperties": true
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "createdAt",
              "updatedAt"
            ],
            "properties": {
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When FileSure first extracted this MGT-7 filing."
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Last write to this extraction (re-runs are idempotent — upsert on `(cin, formId, fyEnd)`)."
              }
            }
          }
        }
      },
      "Pas3CapitalColumn": {
        "type": "object",
        "description": "One column of an AOC-1 / PAS-3 capital structure block (authorised, issued, subscribed, paid_up).\nShare counts surface as JS number when within `Number.MAX_SAFE_INTEGER`; nominal + total are\nstrings (BSON Decimal128) to preserve precision.\n",
        "properties": {
          "shares": {
            "oneOf": [
              {
                "type": "integer"
              },
              {
                "type": "string"
              }
            ],
            "description": "Share count for this column. JS integer when safe; otherwise string."
          },
          "nominal": {
            "type": "string",
            "description": "Nominal (face) value per share, as a decimal string."
          },
          "total": {
            "type": "string",
            "description": "Total monetary value for this column (shares × nominal), as a decimal string."
          }
        }
      },
      "Pas3ShareCapital": {
        "type": "object",
        "description": "Authorised / issued / subscribed / paid_up breakdown for one share class.",
        "properties": {
          "authorised": {
            "$ref": "#/components/schemas/Pas3CapitalColumn"
          },
          "issued": {
            "$ref": "#/components/schemas/Pas3CapitalColumn"
          },
          "subscribed": {
            "$ref": "#/components/schemas/Pas3CapitalColumn"
          },
          "paid_up": {
            "$ref": "#/components/schemas/Pas3CapitalColumn"
          }
        }
      },
      "Pas3DebtStructure": {
        "type": "object",
        "description": "Per-filing debt structure at allotment time.",
        "properties": {
          "debentures": {
            "type": "string",
            "description": "Outstanding debentures value, as a decimal string."
          },
          "secured_loans": {
            "type": "string"
          },
          "others": {
            "type": "string"
          }
        }
      },
      "Pas3CapitalStructure": {
        "type": "object",
        "description": "Capital structure as-of the filing. Carries equity + preference share capital and a debt block.\nNumbers are surfaced verbatim from MCA's form (no derived totals).\n",
        "properties": {
          "equity": {
            "$ref": "#/components/schemas/Pas3ShareCapital"
          },
          "preference": {
            "$ref": "#/components/schemas/Pas3ShareCapital"
          },
          "debt": {
            "$ref": "#/components/schemas/Pas3DebtStructure",
            "nullable": true
          }
        }
      },
      "Pas3FilingSummary": {
        "type": "object",
        "description": "Compact per-filing summary for the list endpoint. Enough for the customer to decide which\nfiling to fetch the detail for — pass `filing_id` into the detail URL.\n",
        "required": [
          "filing_id"
        ],
        "properties": {
          "filing_id": {
            "type": "string",
            "description": "Opaque server-derived token (`flg_<base64url>`). AES-encrypted `(cin, documentCode)`. Deterministic per `(cin, docId)`, server-side decoded.",
            "pattern": "^flg_[A-Za-z0-9_-]+$",
            "example": "flg_xKpQyNwz3FdJaT_l5sA9bKp4XmHfVc_pQk1nR5tWzE2YuJrCqL3mNbDgHvSf"
          },
          "filing_date": {
            "type": "string",
            "format": "date-time",
            "description": "Date MCA accepted the filing (ISO 8601, UTC)."
          },
          "as_of_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Capital-structure-as-of date — derived from the latest `allotment_date` in this filing.\nNull when the filing has no allotments (defensive — shouldn't happen on real data).\n"
          },
          "srn": {
            "type": "string",
            "description": "MCA Service Request Number for this filing. **Omitted when null** — Tanim's XFA-variant\nextractors don't populate srn on every event (~79% of historical events have null srn);\nomission is normal, not an error.\n"
          },
          "allotment_count": {
            "type": "integer",
            "description": "Number of allotment tranches in this filing."
          }
        }
      },
      "Pas3Snapshot": {
        "type": "object",
        "description": "Latest capital-structure snapshot for the CIN. Carries an opaque `filing_id` pointing to the\nunderlying source filing (use it on the detail endpoint), the `as_of_date` (capital structure\nin effect as of), `filing_date` (when the filing was accepted), optional `srn`, and the full\ncapital structure subdocs (equity + preference + debt).\n",
        "properties": {
          "filing_id": {
            "type": "string",
            "description": "Opaque `flg_*` token addressing the underlying source filing."
          },
          "as_of_date": {
            "type": "string",
            "format": "date-time"
          },
          "filing_date": {
            "type": "string",
            "format": "date-time"
          },
          "srn": {
            "type": "string"
          },
          "equity": {
            "$ref": "#/components/schemas/Pas3ShareCapital"
          },
          "preference": {
            "$ref": "#/components/schemas/Pas3ShareCapital"
          },
          "debt": {
            "$ref": "#/components/schemas/Pas3DebtStructure",
            "nullable": true
          }
        }
      },
      "Pas3FilingsListResponse": {
        "type": "object",
        "description": "PAS-3 list-endpoint response shape. Different from `ExtractionYearsResponse` because PAS-3 is\nevent-based (one filing per share allotment, multiple per year). Returns the most-recent\nconsolidated `latest_snapshot` + a sorted list of per-filing summaries — `filing_id` is the\ntoken to use on the detail endpoint.\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "form_type",
              "latest_snapshot",
              "filings"
            ],
            "properties": {
              "form_type": {
                "type": "string",
                "enum": [
                  "PAS-3"
                ],
                "example": "PAS-3"
              },
              "latest_snapshot": {
                "$ref": "#/components/schemas/Pas3Snapshot",
                "nullable": true,
                "description": "Most-recent capital-structure snapshot. `null` when the CIN has no PAS-3 events at all\n(but in that case `filings: []` too — use either signal).\n"
              },
              "filings": {
                "type": "array",
                "description": "Per-filing summaries, sorted by `filing_date` descending.",
                "items": {
                  "$ref": "#/components/schemas/Pas3FilingSummary"
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "createdAt",
              "updatedAt"
            ],
            "properties": {
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          }
        }
      },
      "Pas3Allotment": {
        "type": "object",
        "description": "One allotment tranche within a PAS-3 filing. Multi-tranche filings (rare — typically used for\ncompound transactions) carry several entries here. Field set varies by `allotment_type`:\ncash allotments populate `total_amount`, non-cash allotments populate the `non_cash` subdoc.\n",
        "properties": {
          "allotment_date": {
            "type": "string",
            "format": "date-time"
          },
          "security_type": {
            "type": "string",
            "description": "MCA-coded security type — e.g. `Equity`, `Preference`, `Debenture`, `Other`."
          },
          "allotment_type": {
            "type": "string",
            "description": "MCA-coded allotment reason — examples: `Employee stock option Plan (ESOP)`,\n`Right Issue`, `Bonus issue`, `Conversion of debentures`, `Private placement`, etc.\n"
          },
          "details": {
            "type": "string",
            "description": "Free-text additional details (often blank for routine ESOP allotments)."
          },
          "terms_in_attachment": {
            "type": "boolean",
            "description": "Whether full terms live in an attached PDF rather than in form fields."
          },
          "mode": {
            "type": "string",
            "enum": [
              "Cash",
              "Other than cash",
              "Partly cash and partly non-cash"
            ],
            "description": "Consideration mode."
          },
          "num_securities_allotted": {
            "type": "integer"
          },
          "nominal_per_security": {
            "type": "string",
            "description": "Face value per share, as a decimal string."
          },
          "premium_per_security": {
            "type": "string"
          },
          "discount_per_security": {
            "type": "string"
          },
          "total_amount": {
            "type": "string",
            "description": "Total consideration in INR, as a decimal string."
          },
          "non_cash": {
            "type": "object",
            "nullable": true,
            "description": "Non-cash consideration breakdown (property, services, goodwill, etc.). Null for cash allotments.\n",
            "additionalProperties": true
          }
        }
      },
      "Pas3ExtractionDataResponse": {
        "type": "object",
        "description": "PAS-3 (Return of Allotment) detail-endpoint response. Addressed by `filing_id` (an opaque\n`flg_*` token), the response returns the per-event `capital_structure` (equity + preference +\ndebt subdocs) + chronological `allotments[]` for that one filing.\n\nDecimal128 values surface as strings to preserve precision. BSON Long (share counts) surface\nas JS number when in safe range; else as string.\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "cin",
              "form_type",
              "filing_id"
            ],
            "properties": {
              "cin": {
                "type": "string",
                "example": "L17110MH1973PLC019786"
              },
              "form_type": {
                "type": "string",
                "enum": [
                  "PAS-3"
                ],
                "example": "PAS-3"
              },
              "filing_id": {
                "type": "string",
                "description": "The same opaque token used in the URL — surfaced back for bookmarkable response cohesion."
              },
              "filing_date": {
                "type": "string",
                "format": "date-time"
              },
              "srn": {
                "type": "string",
                "description": "MCA Service Request Number. Omitted when null (XFA extractors)."
              },
              "capital_structure": {
                "$ref": "#/components/schemas/Pas3CapitalStructure"
              },
              "allotments": {
                "type": "array",
                "description": "Allotment tranches within this filing. Usually one entry; multi-tranche filings are rare.",
                "items": {
                  "$ref": "#/components/schemas/Pas3Allotment"
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "createdAt",
              "updatedAt"
            ],
            "properties": {
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When FileSure first extracted this PAS-3 filing."
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Last write to this extraction (re-runs are idempotent — upsert on `(cin, docId)`)."
              }
            }
          }
        }
      },
      "ChargeFlags": {
        "type": "object",
        "description": "Per-charge flags (multi-bank / consortium / pari-passu).",
        "properties": {
          "is_joint": {
            "type": "boolean"
          },
          "is_consortium": {
            "type": "boolean"
          },
          "is_pari_passu": {
            "type": "boolean"
          }
        }
      },
      "ChargeCurrent": {
        "type": "object",
        "description": "Current consolidated state of a charge (computed by the worker on every event). Omitted entirely\nfrom the detail response when the source `current` is empty `{}` (typical for SATISFIED charges\nwhere there's nothing currently active).\n",
        "properties": {
          "amount_inr": {
            "type": "integer",
            "description": "Current outstanding amount in INR rupees (after modifications)."
          },
          "amount_crore": {
            "type": "number"
          },
          "roi_pct": {
            "type": "string",
            "description": "Rate of interest — often free-text (`\"9.50%\"` or `\"as per Bank's Sanction Letter\"`)."
          },
          "holder_name": {
            "type": "string",
            "description": "Primary lender name."
          },
          "holder_category": {
            "type": "string",
            "description": "MCA-coded category — examples `\"Private Sector Bank\"`, `\"Public Sector Bank\"`, `\"NBFC\"`."
          },
          "num_holders": {
            "type": "integer"
          },
          "flags": {
            "$ref": "#/components/schemas/ChargeFlags"
          },
          "property_type_raw": {
            "type": "array",
            "description": "MCA's original property-type classifications, verbatim.",
            "items": {
              "type": "string"
            }
          },
          "property_types": {
            "type": "array",
            "description": "Normalized property-type enum.",
            "items": {
              "type": "string"
            }
          },
          "instrument_desc": {
            "type": "string"
          }
        }
      },
      "ChargeSummary": {
        "type": "object",
        "description": "Per-charge summary entry in the list endpoint's `charges[]` array.",
        "required": [
          "charge_id"
        ],
        "properties": {
          "charge_id": {
            "type": "string",
            "description": "MCA's public charge identifier (numeric string).",
            "pattern": "^[0-9]+$",
            "example": "10596825"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "SATISFIED",
              "OPEN"
            ]
          },
          "holder_name": {
            "type": "string"
          },
          "holder_category": {
            "type": "string"
          },
          "amount_inr": {
            "type": "integer"
          },
          "amount_crore": {
            "type": "number"
          },
          "counts": {
            "type": "object",
            "properties": {
              "creation": {
                "type": "integer"
              },
              "modification": {
                "type": "integer"
              },
              "satisfaction": {
                "type": "integer"
              }
            }
          },
          "first_event_date": {
            "type": "string",
            "format": "date-time",
            "description": "Earliest event_date in the charge's timeline."
          },
          "latest_event_date": {
            "type": "string",
            "format": "date-time"
          },
          "latest_event_type": {
            "type": "string",
            "enum": [
              "CREATION",
              "MODIFICATION",
              "SATISFACTION"
            ]
          }
        }
      },
      "ChargeEventCharge": {
        "type": "object",
        "description": "Per-event loan / facility detail. Populated on CREATION + MODIFICATION events; usually absent on SATISFACTION events.",
        "properties": {
          "amount_inr": {
            "type": "integer"
          },
          "amount_crore": {
            "type": "number"
          },
          "amount_words": {
            "type": "string"
          },
          "date_of_security": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "roi_pct": {
            "type": "string"
          },
          "repay_months": {
            "type": "string"
          },
          "terms_of_repay": {
            "type": "string"
          },
          "nature_facility": {
            "type": "string",
            "nullable": true
          },
          "date_of_disburs": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "margin": {
            "type": "string"
          },
          "extent_ops_chg": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "ChargeEventHolder": {
        "type": "object",
        "description": "Per-event holder (lender) detail. For consortium charges, the `holders[]` nested array carries co-lenders.",
        "properties": {
          "is_joint": {
            "type": "boolean"
          },
          "is_consortium": {
            "type": "boolean"
          },
          "is_pari_passu": {
            "type": "boolean"
          },
          "num_holders": {
            "type": "integer"
          },
          "lead_bank": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "description": "MCA short code (e.g. `PVTB` = Private Bank, `PUB` = Public Bank)."
          },
          "name_of_chg_holder": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "add_line1": {
            "type": "string"
          },
          "add_line2": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "pin_code": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "holders": {
            "type": "array",
            "description": "Co-lender entries (consortium charges only). Each entry has the same shape as the primary holder.",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "ChargeEvent": {
        "type": "object",
        "description": "One lifecycle event for a charge. Variable richness — older events may have only `event_type`\n+ dates + `srn`. Newer / fully-extracted events have the full set of subdocs. Surface only\npopulated fields; null values are omitted entirely (no null placeholders).\n",
        "required": [
          "event_type"
        ],
        "properties": {
          "event_type": {
            "type": "string",
            "enum": [
              "CREATION",
              "MODIFICATION",
              "SATISFACTION"
            ]
          },
          "event_date": {
            "type": "string",
            "format": "date-time"
          },
          "filing_date": {
            "type": "string",
            "format": "date-time"
          },
          "reg_date": {
            "type": "string",
            "format": "date-time"
          },
          "sat_date": {
            "type": "string",
            "format": "date-time",
            "description": "Date of satisfaction. Populated only on SATISFACTION events."
          },
          "srn": {
            "type": "string"
          },
          "charge": {
            "$ref": "#/components/schemas/ChargeEventCharge"
          },
          "holder": {
            "$ref": "#/components/schemas/ChargeEventHolder"
          },
          "security": {
            "type": "object",
            "additionalProperties": true
          },
          "asset_particulars": {
            "type": "object",
            "additionalProperties": true
          },
          "desc_of_modification": {
            "type": "string",
            "description": "Free-text description of the modification (MODIFICATION events)."
          },
          "satisfaction": {
            "type": "object",
            "additionalProperties": true,
            "description": "Closure details (SATISFACTION events)."
          }
        }
      },
      "ChargesListResponse": {
        "type": "object",
        "description": "CHARGES list-endpoint response shape. One entry per `charge_id` for the CIN, sorted by\n`latest_event_date` descending so most-recently-active charges appear first.\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "form_type",
              "charges"
            ],
            "properties": {
              "form_type": {
                "type": "string",
                "enum": [
                  "CHARGES"
                ],
                "example": "CHARGES"
              },
              "charges": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ChargeSummary"
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "createdAt",
              "updatedAt"
            ],
            "properties": {
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          }
        }
      },
      "ChargesDetailResponse": {
        "type": "object",
        "description": "CHARGES detail-endpoint response. Returns the full lifecycle for one charge_id — `current`\nconsolidated state (omitted for SATISFIED charges with empty current), `counts`, and\nchronologically-ascending `events[]` with per-event detail subdocs.\n",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "cin",
              "form_type",
              "charge_id",
              "events"
            ],
            "properties": {
              "cin": {
                "type": "string",
                "example": "U27100PB1996PLC017827"
              },
              "form_type": {
                "type": "string",
                "enum": [
                  "CHARGES"
                ],
                "example": "CHARGES"
              },
              "charge_id": {
                "type": "string",
                "pattern": "^[0-9]+$"
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "SATISFIED",
                  "OPEN"
                ]
              },
              "counts": {
                "type": "object",
                "properties": {
                  "creation": {
                    "type": "integer"
                  },
                  "modification": {
                    "type": "integer"
                  },
                  "satisfaction": {
                    "type": "integer"
                  }
                }
              },
              "current": {
                "$ref": "#/components/schemas/ChargeCurrent",
                "description": "Current consolidated state. **Omitted entirely** when source `current` is empty\n(typical for SATISFIED charges).\n"
              },
              "events": {
                "type": "array",
                "description": "Lifecycle events, sorted by `event_date` ascending (chronological).",
                "items": {
                  "$ref": "#/components/schemas/ChargeEvent"
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "createdAt",
              "updatedAt"
            ],
            "properties": {
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When FileSure first extracted this charge."
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Last write to this extraction (re-runs are idempotent — upsert on `(cin, chargeId)`)."
              }
            }
          }
        }
      },
      "SandboxEntitiesResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "companies",
              "directors"
            ],
            "properties": {
              "companies": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "cin",
                    "company",
                    "knownAs",
                    "idType",
                    "companyStatus",
                    "city",
                    "state"
                  ],
                  "properties": {
                    "cin": {
                      "type": "string",
                      "description": "CIN, or LLPIN for an LLP.",
                      "example": "L93030DL2010PLC198141"
                    },
                    "company": {
                      "type": "string",
                      "description": "Legal name as MCA records it.",
                      "example": "ETERNAL LIMITED"
                    },
                    "knownAs": {
                      "type": "string",
                      "nullable": true,
                      "description": "The brand the company is known by, when it differs from the legal name.",
                      "example": "Eternal, formerly Zomato"
                    },
                    "idType": {
                      "type": "string",
                      "enum": [
                        "cin",
                        "fcin",
                        "llpin"
                      ]
                    },
                    "companyStatus": {
                      "type": "string",
                      "nullable": true,
                      "example": "Active"
                    },
                    "city": {
                      "type": "string",
                      "nullable": true,
                      "example": "NEW DELHI"
                    },
                    "state": {
                      "type": "string",
                      "nullable": true,
                      "example": "Delhi"
                    }
                  }
                }
              },
              "directors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "din",
                    "fullName"
                  ],
                  "properties": {
                    "din": {
                      "type": "string",
                      "example": "11692472"
                    },
                    "fullName": {
                      "type": "string",
                      "nullable": true,
                      "example": "NILESH KASHINATH HIWALE"
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "companies": {
                "type": "integer",
                "description": "How many companies the sandbox holds."
              },
              "directors": {
                "type": "integer",
                "description": "How many directors the sandbox holds."
              },
              "requestId": {
                "type": "string"
              }
            }
          }
        }
      },
      "CompanyResolveResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "query",
              "candidates"
            ],
            "properties": {
              "query": {
                "type": "string",
                "example": "swiggy"
              },
              "candidates": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CompanyResolveCandidate"
                }
              },
              "sandbox": {
                "type": "boolean",
                "description": "Present and `true` on a test key, whose search covers only the sandbox."
              },
              "hint": {
                "type": "string",
                "description": "On a test key with no match, where the sandbox identifiers are listed."
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "priceChargedPaisa": {
                "type": "integer"
              },
              "walletBalanceAfterPaisa": {
                "type": "integer"
              }
            }
          }
        }
      },
      "CompanyResolveCandidate": {
        "type": "object",
        "required": [
          "cin",
          "company",
          "idType",
          "directors",
          "matchScore"
        ],
        "properties": {
          "cin": {
            "type": "string",
            "example": "L74110KA2013PLC096530"
          },
          "company": {
            "type": "string",
            "example": "SWIGGY LIMITED"
          },
          "idType": {
            "type": "string",
            "enum": [
              "cin",
              "fcin",
              "llpin"
            ]
          },
          "companyStatus": {
            "type": "string",
            "nullable": true,
            "example": "Active"
          },
          "dateOfIncorporation": {
            "type": "string",
            "nullable": true,
            "description": "MM/DD/YYYY string as MCA returns it. Every date in company, director and charge records uses this format; filing records use DD/MM/YYYY.",
            "example": "09/12/2013"
          },
          "registeredAddress": {
            "type": "object",
            "nullable": true,
            "properties": {
              "streetAddress": {
                "type": "string",
                "nullable": true
              },
              "city": {
                "type": "string",
                "nullable": true
              },
              "state": {
                "type": "string",
                "nullable": true
              },
              "postalCode": {
                "type": "string",
                "nullable": true
              },
              "country": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "nicCode": {
            "type": "string",
            "nullable": true
          },
          "mainDivisionDescription": {
            "type": "string",
            "nullable": true
          },
          "directors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "din": {
                  "type": "string",
                  "nullable": true
                },
                "fullName": {
                  "type": "string",
                  "nullable": true
                },
                "designation": {
                  "type": "string",
                  "nullable": true
                },
                "isPromoter": {
                  "type": "boolean"
                }
              }
            }
          },
          "matchScore": {
            "type": "number",
            "description": "Typesense relevance score (higher = better match)"
          }
        }
      },
      "DirectorResolveResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "query",
              "candidates"
            ],
            "properties": {
              "query": {
                "type": "string",
                "example": "amit sharma"
              },
              "candidates": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/DirectorResolveCandidate"
                }
              },
              "sandbox": {
                "type": "boolean",
                "description": "Present and `true` on a test key, whose search covers only the sandbox."
              },
              "hint": {
                "type": "string",
                "description": "On a test key with no match, where the sandbox identifiers are listed."
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "requestId": {
                "type": "string"
              },
              "priceChargedPaisa": {
                "type": "integer"
              },
              "walletBalanceAfterPaisa": {
                "type": "integer"
              }
            }
          }
        }
      },
      "DirectorResolveCandidate": {
        "type": "object",
        "required": [
          "din",
          "companies",
          "totalDirectorshipCount",
          "matchScore"
        ],
        "properties": {
          "din": {
            "type": "string",
            "example": "00002157"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "dinAllocationDate": {
            "type": "string",
            "nullable": true
          },
          "personType": {
            "type": "string",
            "nullable": true
          },
          "companies": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "totalDirectorshipCount": {
            "type": "integer"
          },
          "matchScore": {
            "type": "number"
          }
        }
      },
      "CompanyMasterDataResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "cin",
              "company",
              "cinHistory",
              "nameHistory",
              "masterData"
            ],
            "properties": {
              "cin": {
                "type": "string",
                "example": "U72900PB2022PTC055860"
              },
              "company": {
                "type": "string",
                "example": "ARKIZE SOLUTIONS PRIVATE LIMITED"
              },
              "cinHistory": {
                "type": "array",
                "description": "Observed CIN changes. Empty array if none.",
                "items": {
                  "type": "object",
                  "properties": {
                    "oldCin": {
                      "type": "string"
                    },
                    "detectedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              },
              "nameHistory": {
                "type": "array",
                "description": "Observed name changes. Empty array if none.",
                "items": {
                  "type": "object",
                  "properties": {
                    "oldName": {
                      "type": "string"
                    },
                    "detectedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              },
              "masterData": {
                "type": "object",
                "description": "The MCA master-data packet. Always-present keys with sensible defaults:\n`null` for missing object blocks, `[]` for missing arrays.\n",
                "required": [
                  "companyData",
                  "commonData",
                  "directorData",
                  "indexChargesData"
                ],
                "properties": {
                  "companyData": {
                    "type": "object",
                    "nullable": true,
                    "description": "The MCA master record: companyType, companyOrigin, registrationNumber,\ndateOfIncorporation, MCAMDSCompanyAddress[] (registered + correspondence only),\nauthorisedCapital, paidUpCapital, whetherListedOrNot, mainDivisionDescription, etc.\nSurfaced verbatim from MCA (camelCase, British spellings preserved). 9 always-empty\nfields are dropped: `ARDefaulter2Yrs`, `ARDefaulter3Yrs`, `BSDefaulter3Yrs`,\n`establishmentDate`, `incorporationDateObj`, `numberOfMembers`, `previousFirm_companyDetails`,\n`smallLLPFlag`, `statementDate`. `null` if not yet fetched.\n\nCapital amounts additionally carry readable companions, added beside the\nraw numbers rather than replacing them: `paidUpCapitalFormatted`, `authorisedCapitalFormatted` and\n`subscribedCapitalFormatted` (compact, e.g. `₹7.69 Cr`),\n`paidUpCapitalDisplay`, `authorisedCapitalDisplay` and\n`subscribedCapitalDisplay` (full, with Indian digit grouping, e.g.\n`₹7,69,34,000`). The raw integers are unchanged. No separate currency\nfield — the ₹ sign carries it.\n",
                    "additionalProperties": true
                  },
                  "commonData": {
                    "type": "object",
                    "nullable": true,
                    "description": "MCA's supplementary record: NIC codes 1/2/3 with descriptions, AGM date,\nbalance-sheet date, compliance flags, etc. Surfaced verbatim. `null` if not yet\nfetched (this stage runs after `companyData`). Two drop categories applied:\n(1) 14 fields that duplicate `companyData` 1:1 are stripped here (canonical lives\nthere): `companyName`, `cin`, `pan`, `companyType`, `companyOrigin`, `companyCategory`,\n`companySubcategory`, `classOfCompany`, `whetherListedOrNot`, `numberOfMembers`,\n`numberOfPartners`, `numberOfDesignatedPartners`, `authorisedCapital`, `paidupCapital`.\n(2) 16 always-empty fields: `NoOfMembersExcludingProposedEmployees`, `agmDate`,\n`amalgamatedDate`, `dateOfBalanceSheet`, `dateOfIncorporation`, `establishmentDt`,\n`inc24Flag`, `inspectionFlag`, `maxNoOfMembersExcludingProposedEmployees`, `officeType`,\n`otherOfficeType`, `phone`, `section8LicenseNumber`, `statusChangeDate`, `vanishFlag`,\n`whetherListedOrNot`.\n",
                    "additionalProperties": true
                  },
                  "directorData": {
                    "type": "array",
                    "description": "Directors-of-this-company list. Rows deduped by DIN — same-DIN duplicates collapsed\n(preferring populated `PAN`), `MCAUserRole[]` arrays merged with composite-key\ndedup (`role + cin + currentDesignationDate + roleEffectiveDate`). All-blank rows\n(DIN + PAN + name all empty) are dropped. Each item carries `DIN`, `PAN`,\n`FirstName`, `MiddleName`, `LastName`, `dateOfAppointment`, `DirectorDisqualified`,\n`contactAddress[]`, `MCAUserRole[]`. Inside each `MCAUserRole` entry, 13 fields are\ndropped: 4 MCA-internal IDs (`userId`, `companyId`, `userName`, `approverId`),\n3 always-empty (`directorDeathDate`, `opcType`, `shareholdingPercentage`),\n1 single-value noise (`oidFlag`), and 5 duplicates of director-row fields\n(`firstName`, `middleName`, `lastName`, `din`, `pan`). All other role fields\n(designation, role, kmpFlag, opcFlag, dob, mobileNumber, emailAddress, etc.)\npass through. Filter `MCAUserRole[]` yourself to derive current/past/executive\ncategorization. Empty `[]` is rare.\n",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  },
                  "indexChargesData": {
                    "type": "array",
                    "description": "Charges (mortgages) on this company verbatim. PascalCase address fields preserved\n(`StreetAddress`, `StreetAddress2`, `Country`, `Locality`, `State`, `District`,\n`City`, `PostalCode`). Always-empty fields dropped: `StreetAddress3`, `StreetAddress4`,\n`registeredName`. `chargeHolderName` (16-value bucket) and `chName` (actual entity\nname, 53 distinct values) are both kept — they're different fields, not duplicates.\nEmpty `[]` is common — most companies have no charges. Detailed CHG-1/CHG-4 form\ndata (rate of interest, instrument description, particulars) is **not** in this\nresponse — query the Filings/Extractions APIs for that.\n",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                },
                "additionalProperties": true
              }
            }
          },
          "meta": {
            "type": "object",
            "description": "Data freshness signal — stored timestamps from our cached company\ndata, surfaced verbatim. ISO 8601 strings; `null` on legacy rows that\npre-date timestamping.\n",
            "required": [
              "createdAt",
              "updatedAt"
            ],
            "properties": {
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "When FileSure first fetched this CIN."
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Last write to this doc (refresh from MCA)."
              }
            }
          }
        }
      },
      "DirectorMasterDataResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "din",
              "companyData",
              "mcaSignatoryCessationMasterHistory"
            ],
            "properties": {
              "din": {
                "type": "string",
                "example": "00002157"
              },
              "firstName": {
                "type": "string",
                "nullable": true,
                "example": "ARUN"
              },
              "middleName": {
                "type": "string",
                "nullable": true
              },
              "lastName": {
                "type": "string",
                "nullable": true,
                "example": "GUPTA"
              },
              "fullName": {
                "type": "string",
                "nullable": true,
                "example": "ARUN GUPTA"
              },
              "companyData": {
                "type": "array",
                "description": "Per-company role records verbatim from MCA's director lookup\nresponse. Each row is the company-side view of this director's relationship — role,\ndesignation, directorship dates, company metadata. PII (`pan`, `mobileNumber`, etc.),\nMCA / FileSure-internal IDs (`accountId`, `userId`, `srn`, `companyId`, etc.), per-row\ndupes of top-level identity fields, and operational flags (`flagged`, `oldFlag`) are\nstripped. Everything else passes through. Customers filter / aggregate this themselves\nto derive views like \"current directorships\" or \"ceased\". Empty `[]` is rare — almost\nevery DIN has at least one row.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "mcaSignatoryCessationMasterHistory": {
                "type": "array",
                "description": "Past (and sometimes current) company appointments with cessation dates from MCA's\nsignatory cessation ledger. Complements `companyData[]` when that array is empty or\nrows lack `cessationDate`. Rows carry `cin`, `accountName`, `designation`,\n`appointmentDate`, `cessationDate` and usually `accountStatus`. PII, internal IDs and\nthe per-row `din` (always equal to `data.din`) are stripped with the same rules as\n`companyData[]`. Empty `[]` when no history is cached for this DIN.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "updatedAt",
              "source"
            ],
            "properties": {
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "ISO timestamp of the most recent write to this director's cached record. `null` on legacy rows that pre-date timestamping. No `createdAt` is surfaced — the upstream source doesn't carry one."
              },
              "source": {
                "type": "string",
                "enum": [
                  "MCA"
                ],
                "example": "MCA"
              }
            }
          }
        }
      }
    },
    "responses": {
      "InvalidCompanyIdentifier": {
        "description": "Identifier failed format validation, or unknown idType value",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "invalidCin": {
                "summary": "Identifier doesn't match CIN/FCIN/LLPIN format",
                "value": {
                  "error": {
                    "code": "INVALID_CIN",
                    "message": "The provided identifier failed format validation. Expected CIN, FCIN, or LLPIN."
                  }
                }
              },
              "invalidIdType": {
                "summary": "Unknown idType query value",
                "value": {
                  "error": {
                    "code": "INVALID_ID_TYPE",
                    "message": "Unknown idType. Valid values: cin, fcin, llpin."
                  }
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "API key missing, invalid, or revoked",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "missing": {
                "summary": "Header absent",
                "value": {
                  "error": {
                    "code": "MISSING_API_KEY",
                    "message": "API key is required. Pass it via the x-api-key header."
                  }
                }
              },
              "invalid": {
                "summary": "Key not recognised",
                "value": {
                  "error": {
                    "code": "INVALID_API_KEY",
                    "message": "The provided API key is not valid."
                  }
                }
              },
              "revoked": {
                "summary": "Key revoked",
                "value": {
                  "error": {
                    "code": "API_KEY_REVOKED",
                    "message": "This API key has been revoked."
                  }
                }
              }
            }
          }
        }
      },
      "InsufficientBalance": {
        "description": "Wallet balance is below the endpoint price",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Error"
                },
                {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "balancePaisa": {
                          "type": "integer"
                        },
                        "requiredPaisa": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              ]
            },
            "example": {
              "error": {
                "code": "INSUFFICIENT_BALANCE",
                "message": "Insufficient wallet balance. Please recharge.",
                "balancePaisa": 0,
                "requiredPaisa": 500
              }
            }
          }
        }
      },
      "NoAccess": {
        "description": "No pricing assigned, or test key tried to access non-sandbox CIN/DIN",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/NoAccessError"
            },
            "examples": {
              "noPricing": {
                "summary": "No pricing record (live key)",
                "value": {
                  "error": {
                    "code": "NO_ACCESS",
                    "message": "No access to endpoint 'companies.master'. Contact support to enable access.",
                    "endpoint": "companies.master",
                    "catalogPricePaisa": 500
                  }
                }
              },
              "sandboxOnly": {
                "summary": "Test key outside sandbox whitelist",
                "value": {
                  "error": {
                    "code": "SANDBOX_ONLY",
                    "message": "A test key only works on the sandbox companies and directors. They are listed in this response and at GET /v1/sandbox. Use one of those, or a live key.",
                    "sandboxCompanies": [
                      {
                        "cin": "U74999HR2015FTC056386",
                        "company": "CARS24 SERVICES PRIVATE LIMITED",
                        "knownAs": "Cars24"
                      },
                      {
                        "cin": "L93030DL2010PLC198141",
                        "company": "ETERNAL LIMITED",
                        "knownAs": "Eternal, formerly Zomato"
                      }
                    ],
                    "sandboxDirectors": [
                      {
                        "din": "11692472",
                        "fullName": "NILESH KASHINATH HIWALE"
                      }
                    ],
                    "nextStep": "GET /v1/sandbox"
                  }
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "No pricing assigned for this endpoint (live key), or the account is disabled. A test key is\nnever refused here: its search is scoped to the sandbox instead (see `sandbox` and `hint` in\nthe response), so `SANDBOX_ONLY` does not occur.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/NoAccessError"
            },
            "examples": {
              "noPricing": {
                "summary": "No pricing record (live key)",
                "value": {
                  "error": {
                    "code": "NO_ACCESS",
                    "message": "No access to endpoint 'companies.resolve'. Contact support to enable access.",
                    "endpoint": "companies.resolve",
                    "catalogPricePaisa": 500
                  }
                }
              },
              "accountDisabled": {
                "summary": "Customer account deactivated",
                "value": {
                  "error": {
                    "code": "ACCOUNT_DISABLED",
                    "message": "Your account has been disabled. Contact support."
                  }
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found in master data",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InvalidDin": {
        "description": "DIN failed format validation (must be 8 numeric digits)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "INVALID_DIN",
                "message": "DIN must be 8 numeric digits."
              }
            }
          }
        }
      },
      "DirectorNotFound": {
        "description": "No director found for the given DIN",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "DIRECTOR_NOT_FOUND",
                "message": "No director found for DIN 12345678."
              }
            }
          }
        }
      },
      "BadRequest": {
        "description": "Request validation failed (invalid identifier, malformed query param, etc.)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
