API Sathi docs
← All products

Aadhaar DigiLocker — Start

kyc

Start a consented Aadhaar verification. Returns a `kyc_url` — send your customer there and they authenticate with UIDAI directly, entering their Aadhaar number and OTP on the government screen. YOU NEVER SEE THE AADHAAR NUMBER OR THE OTP. That is the difference between this and raw OKYC, and it is why this flow is usually the easier one to get signed off internally. What you get back at the end is a masked Aadhaar number plus the verified demographics. TWO STEPS, TWO CALLS. This one issues the link. Once the customer finishes, call aadhaar-digilocker-fetch-v1 with the `transaction_id` returned here to collect the result. Store that id against your application record — without it you cannot retrieve the verification. `uid` is YOUR reference and must be unique. A repeat is rejected, which is what makes retries safe. Supply `mobile` or `emailId` (at least one); `redirectionUrl` is where the customer lands afterwards, and receives `txnId` plus either `success=true` or `error_code` and `errMsg`. Billed per link issued. The verification itself is billed on the fetch call.

POST /gw/v1/aadhaar-digilocker-init-v1/SLA p95: 1500 ms

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.

X-API-Key: live_xxxxxxxxxxxx

Request

Endpoint: POST https://apisathi.in/gw/v1/aadhaar-digilocker-init-v1/

The trailing slash is required. /v1/aadhaar-digilocker-init-v1/ works; /v1/aadhaar-digilocker-init-v1 returns 404 Not Found. This applies to every product.

FieldTypeRequiredConstraints
uidstringrequiredYour own unique reference, max 80 chars. Word characters, dots, @ and hyphens only. A repeat is rejected.
mobilestringoptionalCustomer mobile, exactly 10 digits starting 6-9. Supply this or emailId.
emailIdstringoptionalCustomer email. Supply this or mobile.
firstNamestringoptionalOptional, max 45 chars.
lastNamestringoptionalOptional, max 45 chars.
isSendOtpbooleanoptionalHave the link delivered to the customer directly.
isHideExplanationScreenbooleanoptionalSkip the explanation page.
redirectionUrlstringoptionalWhere the customer lands after finishing or failing. Max 512 chars.

Code snippets

curl -X POST https://apisathi.in/gw/v1/aadhaar-digilocker-init-v1/ \
  -H "X-API-Key: $API_SATHI_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"uid":"loan-application-48213","mobile":"9876543210","redirectionUrl":"https://yourapp.example/kyc-done"}'

Response

FieldTypeRequiredConstraints
transaction_idstringoptionalPass this to aadhaar-digilocker-fetch-v1. Store it.
kyc_urlstringoptionalSend the customer here.
short_urlstringoptionalShortened form of the same link.
verifiedbooleanoptionalThe link was issued.

Sample response

{
  "verified": true,
  "transaction_id": "873585497344017339",
  "kyc_url": "https://digilocker.example/?token=eyJhbGciOiJSUzI1NiJ9...",
  "short_url": "https://smler.example/UA1UhGHvwi"
}

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

CodeHTTPWhen
INVALID_INPUT422The 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_KEY401Missing, malformed, or revoked X-API-Key.
OUT_OF_SCOPE403API key is not scoped for this product.
INSUFFICIENT_BALANCE402Wallet balance is below the per-call sale price. Recharge and retry.
RATE_LIMITED429Per-key RPS or RPM limit exceeded. Back off and retry after the Retry-After header.
PRODUCT_DEPRECATED410This 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_VENDOR503No healthy vendor is currently available for this product. Transient — safe to retry after a short backoff. Not charged.
VENDOR_AUTH_FAILED502Upstream vendor rejected our credentials (our config issue). Not charged.
VENDOR_ERROR502A 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.
TIMEOUT504Upstream 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 — Start",
    "version": "1.0.0",
    "description": "Start a consented Aadhaar verification. Returns a `kyc_url` — send your customer there and they authenticate with UIDAI directly, entering their Aadhaar number and OTP on the government screen.\n\nYOU NEVER SEE THE AADHAAR NUMBER OR THE OTP. That is the difference between this and raw OKYC, and it is why this flow is usually the easier one to get signed off internally. What you get back at the end is a masked Aadhaar number plus the verified demographics.\n\nTWO STEPS, TWO CALLS. This one issues the link. Once the customer finishes, call aadhaar-digilocker-fetch-v1 with the `transaction_id` returned here to collect the result. Store that id against your application record — without it you cannot retrieve the verification.\n\n`uid` is YOUR reference and must be unique. A repeat is rejected, which is what makes retries safe. Supply `mobile` or `emailId` (at least one); `redirectionUrl` is where the customer lands afterwards, and receives `txnId` plus either `success=true` or `error_code` and `errMsg`.\n\nBilled per link issued. The verification itself is billed on the fetch call."
  },
  "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-init-v1": {
      "post": {
        "operationId": "aadhaarDigilockerInitV1",
        "tags": [
          "kyc"
        ],
        "summary": "Aadhaar DigiLocker — Start",
        "description": "Start a consented Aadhaar verification. Returns a `kyc_url` — send your customer there and they authenticate with UIDAI directly, entering their Aadhaar number and OTP on the government screen.\n\nYOU NEVER SEE THE AADHAAR NUMBER OR THE OTP. That is the difference between this and raw OKYC, and it is why this flow is usually the easier one to get signed off internally. What you get back at the end is a masked Aadhaar number plus the verified demographics.\n\nTWO STEPS, TWO CALLS. This one issues the link. Once the customer finishes, call aadhaar-digilocker-fetch-v1 with the `transaction_id` returned here to collect the result. Store that id against your application record — without it you cannot retrieve the verification.\n\n`uid` is YOUR reference and must be unique. A repeat is rejected, which is what makes retries safe. Supply `mobile` or `emailId` (at least one); `redirectionUrl` is where the customer lands afterwards, and receives `txnId` plus either `success=true` or `error_code` and `errMsg`.\n\nBilled per link issued. The verification itself is billed on the fetch call.",
        "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": [
                  "uid"
                ],
                "properties": {
                  "uid": {
                    "type": "string",
                    "description": "Your own unique reference, max 80 chars. Word characters, dots, @ and hyphens only. A repeat is rejected."
                  },
                  "mobile": {
                    "type": "string",
                    "description": "Customer mobile, exactly 10 digits starting 6-9. Supply this or emailId."
                  },
                  "emailId": {
                    "type": "string",
                    "description": "Customer email. Supply this or mobile."
                  },
                  "firstName": {
                    "type": "string",
                    "description": "Optional, max 45 chars."
                  },
                  "lastName": {
                    "type": "string",
                    "description": "Optional, max 45 chars."
                  },
                  "isSendOtp": {
                    "type": "boolean",
                    "description": "Have the link delivered to the customer directly."
                  },
                  "isHideExplanationScreen": {
                    "type": "boolean",
                    "description": "Skip the explanation page."
                  },
                  "redirectionUrl": {
                    "type": "string",
                    "description": "Where the customer lands after finishing or failing. Max 512 chars."
                  }
                }
              },
              "example": {
                "uid": "loan-application-48213",
                "mobile": "9876543210",
                "redirectionUrl": "https://yourapp.example/kyc-done"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful, normalized response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction_id": {
                      "type": "string",
                      "description": "Pass this to aadhaar-digilocker-fetch-v1. Store it."
                    },
                    "kyc_url": {
                      "type": "string",
                      "description": "Send the customer here."
                    },
                    "short_url": {
                      "type": "string",
                      "description": "Shortened form of the same link."
                    },
                    "verified": {
                      "type": "boolean",
                      "description": "The link was issued."
                    }
                  }
                },
                "example": {
                  "verified": true,
                  "transaction_id": "873585497344017339",
                  "kyc_url": "https://digilocker.example/?token=eyJhbGciOiJSUzI1NiJ9...",
                  "short_url": "https://smler.example/UA1UhGHvwi"
                }
              }
            }
          },
          "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"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "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 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.",
            "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"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}