Aadhaar DigiLocker — Fetch Result
kycCollect the verified record once your customer has completed DigiLocker. Call it with the `transaction_id` from aadhaar-digilocker-init-v1. THE AADHAAR NUMBER IS MASKED and always will be — the full number is never returned by this flow. You receive name, date of birth, gender, care-of, a structured address and a base64 photo. POLL, DO NOT ASSUME. Until the customer finishes, this returns 422 with "The given transaction id for digilocker is not success". That is normal and is not an error on your side — it means they have not completed the UIDAI screens yet. Poll after your redirect fires, or on a sensible interval. Three outcomes are the CUSTOMER’s and not a fault: they declined consent, their DigiLocker account holds no eAadhaar, or they did not select the Aadhaar document. Treat those as a failed verification rather than a retryable error.
Authentication
Pass your key in the X-API-Key header. Use a test_ key against the sandbox and a live_ key in production. Send an optional Idempotency-Key header to safely retry — the same key returns the same response for 24h.
Request
Endpoint: POST https://apisathi.in/gw/v1/aadhaar-digilocker-fetch-v1/
The trailing slash is required. /v1/aadhaar-digilocker-fetch-v1/ works; /v1/aadhaar-digilocker-fetch-v1 returns 404 Not Found. This applies to every product.
| Field | Type | Required | Constraints |
|---|---|---|---|
| transaction_id | string | required | pattern: ^[0-9]{6,32}$ · The transaction_id returned by aadhaar-digilocker-init-v1 — a long number, e.g. 304842915616921275. Not the kyc_url, not the short link, not your uid. |
Code snippets
curl -X POST https://apisathi.in/gw/v1/aadhaar-digilocker-fetch-v1/ \
-H "X-API-Key: $API_SATHI_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"transaction_id":"873585497344017339"}'Response
| Field | Type | Required | Constraints |
|---|---|---|---|
| verified | boolean | optional | THE FIELD TO BRANCH ON. true = the customer completed DigiLocker and the record below is UIDAI-verified. Anything else is not a successful verification. |
| status | string | optional | The source's own status code, passed through. On success this is the single letter "s" — not "SUCCESS". Do not string-match it; use `verified`. |
| masked_aadhaar | string | optional | Masked. Never the full number. |
| name | string | optional | — |
| dob | string | optional | — |
| gender | string | optional | — |
| care_of | string | optional | — |
| address | object | optional | house, street, loc, dist, state, pc and more. |
| photo_base64 | string | optional | Base64 photo from the Aadhaar record. |
| documents | array | optional | The DigiLocker files behind the record — signed, time-limited links (`docLink`) with `docType` and `docExtension` (xml, pdf). |
Sample response
{
"verified": true,
"status": "s",
"masked_aadhaar": "XXXXXXXX1234",
"name": "RAHUL VERMA",
"dob": "1990-04-12",
"gender": "M",
"address": {
"house": "12",
"street": "MG Road",
"dist": "Jaipur",
"state": "Rajasthan",
"pc": "302001"
}
}Reading a 400
A schema rejection returns INVALID_REQUEST with a details array naming the exact field. Read it before guessing — it gives you the JSON path and what was wrong with it.
{
"error": {
"code": "INVALID_REQUEST",
"message": "Request body failed schema validation",
"details": [
{ "path": "/callback_url",
"message": "unexpected property 'callback_url' — this endpoint does not accept unknown fields" }
]
}
}Most endpoints reject unknown top-level fields outright, so an extra key you added for your own bookkeeping will fail the call. Enum errors list the accepted values, and a missing required field is named with its full path.
Error codes
| Code | HTTP | When |
|---|---|---|
| INVALID_REQUEST — transaction_id is not a number | 400 | You sent something other than the transaction_id — usually the kyc_url, the short link, or your own uid. The transaction_id is the long number in the Start response. Rejected before any lookup; not charged. |
| NOT_FOUND — unknown transaction_id | 404 | Well-formed, but no verification exists with that id. Definitive — a typo, or an id from a different Start call. Not charged. Do not retry the same value. |
| INVALID_INPUT — "transaction id … is not success" | 422 | The customer has NOT finished DigiLocker yet. This is the normal state between Start and completion, not a fault. Not charged. Poll again after your redirect fires, or on a sensible interval. |
| INVALID_INPUT — DG1001 / DG1002 / DG1003 | 422 | The customer declined consent (DG1001), their DigiLocker holds no eAadhaar (DG1002), or they did not select the Aadhaar document (DG1003). A failed verification on their side; issue a fresh Start if they want to try again. Not charged. |
| INVALID_INPUT | 422 | The request was rejected as invalid — either it failed OUR schema validation (malformed input; not charged), or the upstream source rejected the value you sent. NOTE: an identifier that is well-formed but simply has NO RECORD is no longer an error — it returns 200 with `verified: false` and is charged (see the result-code table below). FIX the input before retrying; retrying the same value will fail again. |
| INVALID_API_KEY | 401 | Missing, malformed, or revoked X-API-Key. |
| OUT_OF_SCOPE | 403 | API key is not scoped for this product. |
| INSUFFICIENT_BALANCE | 402 | Wallet balance is below the per-call sale price. Recharge and retry. |
| RATE_LIMITED | 429 | Per-key RPS or RPM limit exceeded. Back off and retry after the Retry-After header. |
| PRODUCT_DEPRECATED | 410 | This API has been retired and is no longer available. Stop calling it — it will not return. Check the catalog for the current equivalent. |
| ROUTER_NO_VENDOR | 503 | No healthy vendor is currently available for this product. Transient — safe to retry after a short backoff. Not charged. |
| VENDOR_AUTH_FAILED | 502 | Upstream vendor rejected our credentials (our config issue). Not charged. |
| VENDOR_ERROR | 502 | A genuine transient upstream error (the source was briefly unavailable). Safe to RETRY after a short backoff. Not charged. NOTE: this is NOT for bad input — invalid values return 422 INVALID_INPUT, not 502. |
| TIMEOUT | 504 | Upstream vendor did not respond within the SLA window. Safe to retry after a short backoff. Not charged. |
OpenAPI 3.1
Generated from this product's request/response JSON Schemas.
{
"openapi": "3.1.0",
"info": {
"title": "API Sathi — Aadhaar DigiLocker — Fetch Result",
"version": "1.0.0",
"description": "Collect the verified record once your customer has completed DigiLocker. Call it with the `transaction_id` from aadhaar-digilocker-init-v1.\n\nTHE AADHAAR NUMBER IS MASKED and always will be — the full number is never returned by this flow. You receive name, date of birth, gender, care-of, a structured address and a base64 photo.\n\nPOLL, DO NOT ASSUME. Until the customer finishes, this returns 422 with \"The given transaction id for digilocker is not success\". That is normal and is not an error on your side — it means they have not completed the UIDAI screens yet. Poll after your redirect fires, or on a sensible interval.\n\nThree outcomes are the CUSTOMER’s and not a fault: they declined consent, their DigiLocker account holds no eAadhaar, or they did not select the Aadhaar document. Treat those as a failed verification rather than a retryable error."
},
"servers": [
{
"url": "https://apisathi.in/gw/v1"
}
],
"components": {
"securitySchemes": {
"ApiKeyAuth": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key",
"description": "Your live or test key, e.g. `live_xxxxxxxxxxxx`."
}
}
},
"paths": {
"/aadhaar-digilocker-fetch-v1": {
"post": {
"operationId": "aadhaarDigilockerFetchV1",
"tags": [
"kyc"
],
"summary": "Aadhaar DigiLocker — Fetch Result",
"description": "Collect the verified record once your customer has completed DigiLocker. Call it with the `transaction_id` from aadhaar-digilocker-init-v1.\n\nTHE AADHAAR NUMBER IS MASKED and always will be — the full number is never returned by this flow. You receive name, date of birth, gender, care-of, a structured address and a base64 photo.\n\nPOLL, DO NOT ASSUME. Until the customer finishes, this returns 422 with \"The given transaction id for digilocker is not success\". That is normal and is not an error on your side — it means they have not completed the UIDAI screens yet. Poll after your redirect fires, or on a sensible interval.\n\nThree outcomes are the CUSTOMER’s and not a fault: they declined consent, their DigiLocker account holds no eAadhaar, or they did not select the Aadhaar document. Treat those as a failed verification rather than a retryable error.",
"security": [
{
"ApiKeyAuth": []
}
],
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"required": false,
"schema": {
"type": "string"
},
"description": "Optional. Same key returns the same response for 24h."
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"transaction_id"
],
"properties": {
"transaction_id": {
"type": "string",
"pattern": "^[0-9]{6,32}$",
"description": "The transaction_id returned by aadhaar-digilocker-init-v1 — a long number, e.g. 304842915616921275. Not the kyc_url, not the short link, not your uid."
}
}
},
"example": {
"transaction_id": "873585497344017339"
}
}
}
},
"responses": {
"200": {
"description": "Successful, normalized response.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"verified": {
"type": "boolean",
"description": "THE FIELD TO BRANCH ON. true = the customer completed DigiLocker and the record below is UIDAI-verified. Anything else is not a successful verification."
},
"status": {
"type": "string",
"description": "The source's own status code, passed through. On success this is the single letter \"s\" — not \"SUCCESS\". Do not string-match it; use `verified`."
},
"masked_aadhaar": {
"type": "string",
"description": "Masked. Never the full number."
},
"name": {
"type": "string"
},
"dob": {
"type": "string"
},
"gender": {
"type": "string"
},
"care_of": {
"type": "string"
},
"address": {
"type": "object",
"description": "house, street, loc, dist, state, pc and more."
},
"photo_base64": {
"type": "string",
"description": "Base64 photo from the Aadhaar record."
},
"documents": {
"type": "array",
"description": "The DigiLocker files behind the record — signed, time-limited links (`docLink`) with `docType` and `docExtension` (xml, pdf)."
}
}
},
"example": {
"verified": true,
"status": "s",
"masked_aadhaar": "XXXXXXXX1234",
"name": "RAHUL VERMA",
"dob": "1990-04-12",
"gender": "M",
"address": {
"house": "12",
"street": "MG Road",
"dist": "Jaipur",
"state": "Rajasthan",
"pc": "302001"
}
}
}
}
},
"400": {
"description": "You sent something other than the transaction_id — usually the kyc_url, the short link, or your own uid. The transaction_id is the long number in the Start response. Rejected before any lookup; not charged.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"401": {
"description": "Missing, malformed, or revoked X-API-Key.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"402": {
"description": "Wallet balance is below the per-call sale price. Recharge and retry.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"403": {
"description": "API key is not scoped for this product.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"404": {
"description": "Well-formed, but no verification exists with that id. Definitive — a typo, or an id from a different Start call. Not charged. Do not retry the same value.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"410": {
"description": "This API has been retired and is no longer available. Stop calling it — it will not return. Check the catalog for the current equivalent.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"422": {
"description": "The customer has NOT finished DigiLocker yet. This is the normal state between Start and completion, not a fault. Not charged. Poll again after your redirect fires, or on a sensible interval.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"429": {
"description": "Per-key RPS or RPM limit exceeded. Back off and retry after the Retry-After header.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"502": {
"description": "Upstream vendor rejected our credentials (our config issue). Not charged.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"503": {
"description": "No healthy vendor is currently available for this product. Transient — safe to retry after a short backoff. Not charged.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
},
"504": {
"description": "Upstream vendor did not respond within the SLA window. Safe to retry after a short backoff. Not charged.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"call_id": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
}
}