Secure MCA File Delivery API
1. Introduction
The Secure MCA File Delivery API is an orchestration layer over the existing MCA Initiate and Retrieve services. It retrieves a company's official registration documents — MoA (Memorandum of Association), AoA (Articles of Association), and CoI (Certificate of Incorporation) — from the Ministry of Corporate Affairs (MCA) and delivers them to the client as Base64-encoded content inside the API response.
There are no external download links at any point in the flow. The decoded document never leaves the authenticated response body — the underlying document URL is fetched and consumed server-side only.
Because documents are embedded as base64 string inside a JSON response, every response is held under two hard limits: 7.5 MB of file content and 10 MB total payload. Documents that exceed this are split into ordered, individually-verifiable chunks, linked by a secure continuation token, and reassembled by the client.
2. Usecase
An integrator (client system) needs to pull a specific company's MoA, AoA, or CoI documents inline — without handling a separate file-hosting or link-expiry mechanism, and without exposing document URLs outside the authenticated session. Typical scenarios:
- Onboarding / KYB workflows — pulling incorporation documents as part of business verification, directly into the client's own document store, with no intermediate public link.
- Small documents (e.g., a Certificate of Incorporation) — retrieved in a single call, no extra handling required.
- Large documents (e.g., a multi-MB Memorandum of Association) — retrieved across multiple sequential calls, each returning a verified piece, reassembled locally into a byte-identical copy of the original filing.
- Compliance-sensitive integrations — where security policy prohibits document delivery via any externally-shareable URL, and every byte transferred must be independently checksum-verified.
3. API Details
3.1 API Endpoints and Description
# | Endpoint | Method | Description |
|---|---|---|---|
1 | /sec/mca-files/initiate | POST | Accepts a company identifier (CIN) and forwards it upstream. Returns a requestId used for all subsequent retrieval calls, and isInstant, which indicates whether documents are immediately retrievable. |
2 | /sec/mca-files/retrieve | POST | Accepts a requestId, a docType (MOA, AOA, or COI), and an optional nextToken. Returns the requested document as Base64 — in a single response if it fits, or as sequential chunks (each carrying a nextToken) if it does not. |
3.2 Overall Workflow
sequenceDiagram
participant Client as Client (Integrator)
participant API as Secure MCA File Delivery API<br/>(/sec/mca-files/*)
participant MCA as Upstream MCA Service<br/>(/global/mca-files/*)
Client->>API: initiate(cin)
API->>MCA: initiate(cin)
MCA-->>API: requestId, isInstant
API-->>Client: requestId, isInstant
Client->>API: retrieve(requestId, docType, nextToken?)
API->>MCA: retrieve(requestId) -> file URLs
MCA-->>API: file URLs
Note over API: Download selected docType from URL<br/>Size check -> 1 chunk OR N chunks
API-->>Client: base64 chunk (+ nextToken if more)
loop While nextToken is non-empty
Client->>API: retrieve(requestId, docType, nextToken)
API-->>Client: next base64 chunk (+ nextToken if more)
end
Note over Client: Decode + join chunks +<br/>verify checksum ✔Step-by-step:
- Client calls API 1 (initiate) with the company's CIN. Receives a requestId and isInstant flag.
- Client calls API 2 (retrieve) with the requestId and the desired docType, with no nextToken on the first call.
- The API resolves the upstream document URL, downloads the file server-side, computes its size and checksum, and decides whether it fits in one response or must be chunked.
- The API returns chunk 1. If more chunks remain, it includes a nextToken; if this is the only/last chunk, nextToken is empty.
- If nextToken is non-empty, the client repeats step 2 with that token to fetch the next chunk — repeating until nextToken is empty.
- The client Base64-decodes each chunk, concatenates the decoded bytes in order, and verifies the assembled file against the fileChecksum.
3.3 API 1 — POST /sec/mca-files/initiate
Mirrors the upstream /global/mca-files/initiate contract exactly — byte-for-byte compatible, so existing integrators of the global endpoint can switch base paths with no other change.
3.3.1 API Curl
curl --location 'https://api-preproduction.signzy.app/sec/mca-files/initiate' \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"id": "U74999UP2018PTC105930",
"inputType": "cin",
"callbackUrl": ""
}'3.3.2 Input Payload
{
"id": "U74999UP2018PTC105930",
"inputType": "cin",
"callbackUrl": ""
}3.3.3 Input Description Table
Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The company identifier to look up — e.g. the CIN (Corporate Identification Number) |
inputType | string | Yes | The type of identifier passed in id. Currently "cin" |
callbackUrl | string | No | Optional callback URL for asynchronous notification once documents are ready. Can be left empty |
3.3.4 Output Payload
{
"result": {
"cin": "U74999UP2018PTC105930",
"requestId": "6a327a5c24d6446122e917a1",
"isInstant": true,
"createdAt": "2026-05-19T14:25:28.308+05:30"
},
"reason": "Request Successful",
"code": "S001"
}3.3.5 Output Description Table
Field | Type | Description |
|---|---|---|
result.cin | string | The CIN that was submitted, echoed back |
result.requestId | string | Tracking ID to be used in all subsequent /sec/mca-files/retrieve calls for this company |
result.isInstant | boolean | true if documents are immediately retrievable; false if the client may need to poll retrieve until status: FULFILLED |
result.createdAt | string (ISO-8601) | Timestamp of when the request was created |
reason | string | Human-readable status message |
code | string | Status code (see §3.3.6) |
3.3.6 Error Codes
Code | HTTP | Meaning / client action |
|---|---|---|
S001 | 200 | Success |
E400 | 400 | Invalid or malformed request body — fix request |
E401 | 401 | Missing/invalid Authorization — re-authenticate |
E502 | 502 | Upstream MCA service failure — safe to retry |
3.4 API 2 — POST /sec/mca-files/retrieve
Accepts a requestId from API 1, a docType, and an optional nextToken to drive chunked delivery.
3.4.1 API Curl
First call (start a delivery):
curl --location 'https://api-preproduction.signzy.app/sec/mca-files/retrieve' \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"requestId": "6a327a5c24d6446122e917a1",
"docType": "MOA",
"nextToken": ""
}'Subsequent call (next chunk):
curl --location 'https://api.signzy.app/sec/mca-files/retrieve' \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{
"requestId": "6a327a5c24d6446122e917a1",
"docType": "MOA",
"nextToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'3.4.2 Input Payload
{
"requestId": "6a327a5c24d6446122e917a1",
"docType": "MOA",
"nextToken": ""
}3.4.3 Input Description Table
Field | Type | Required | Description |
|---|---|---|---|
requestId | string | Yes | The tracking ID returned by API 1 (initiate) |
docType | string | Yes | Document type to retrieve. One of MOA, AOA, COI |
nextToken | string | No | Continuation token from the previous retrieve response. Empty/omitted on the first call for a document; must be passed back unchanged on every subsequent call until nextToken returns empty |
3.4.4 Output Payload
Single chunk (small document, fits in one response):
{
"fileId": "a1b2c3d4",
"contentType": "application/pdf",
"fileSize": 184320,
"fileChecksum": "sha256:9f86d0818...e3b0c44",
"chunkNumber": 1,
"totalChunks": 1,
"chunkChecksum": "sha256:ab12cd34...",
"data": "JVBERi0xLjcKJ...",
"isLast": true,
"nextToken": "",
"expiresAt": "2026-06-16T12:15:00Z"
}First of multiple chunks (large document):
{
"fileId": "a1b2c3d4",
"contentType": "application/pdf",
"fileSize": 12582912,
"fileChecksum": "sha256:9f86d0818...e3b0c44",
"chunkNumber": 1,
"totalChunks": 2,
"chunkChecksum": "sha256:ab12cd34...",
"data": "JVBERi0xLjcKJ...",
"isLast": false,
"nextToken": "eyJhbGciOiJIUzI1Ni...",
"expiresAt": "2026-06-16T12:15:00Z"
}Final chunk:
{
"fileId": "a1b2c3d4",
"contentType": "application/pdf",
"fileSize": 12582912,
"fileChecksum": "sha256:9f86d0818...e3b0c44",
"chunkNumber": 2,
"totalChunks": 2,
"chunkChecksum": "sha256:ef56ab78...",
"data": "...KJWVuZHN0cmVhbQ==",
"isLast": true,
"nextToken": "",
"expiresAt": "2026-06-16T12:15:00Z"
}3.4.5 Output Description Table
Field | Type | Description |
|---|---|---|
fileId | string | Stable identifier for this document delivery session; same across all chunks |
contentType | string | MIME type of the original file, e.g. application/pdf |
fileSize | integer | Size in bytes of the original (decoded) file; same across all chunks |
fileChecksum | string | SHA-256 of the whole original file — used for final verification after all chunks are assembled |
chunkNumber | integer | 1-based index of this chunk |
totalChunks | integer | Total number of chunks for this document |
chunkChecksum | string | SHA-256 of this chunk's raw (decoded) bytes |
data | string | Base64 of this chunk's raw bytes (RFC 4648) |
isLast | boolean | true on the terminal chunk (chunkNumber == totalChunks) |
nextToken | string | Signed JWT for the next chunk; empty string when isLast is true. Treat empty nextToken as the authoritative "stop" signal |
expiresAt | string (ISO-8601) | Expiry of the current token / delivery session — all chunks must be collected within this window |
3.4.6 Error Codes
Code | HTTP | Meaning / client action |
|---|---|---|
S001 | 200 | Success |
E400 | 400 | Invalid docType or malformed body fix request |
E401 | 401 | Missing/invalid Authorization re-authenticate |
E404 | 404 | Requested docType not present for this requestId |
E409 | 409 | Upstream not yet FULFILLED - poll retrieve again later |
E419 | 419 | Continuation token expired - restart from a no-token retrieve |
E422 | 422 | Token tampered/invalid signature - restart delivery |
E502 | 502 | Upstream MCA / document download failure - safe to retry |