iChek Services - Your key to right hire

iChek Developer Guide

One account and one set of API keys for every iChek product.

Address API

Make sure every customer gives you a delivery address that actually works. iChek fills in city and state from the PIN code, catches wrong or incomplete addresses while the customer is still typing, and returns a clean, standardized address you can ship to.

Create a free accountTry the live demo
PIN auto-fillCustomer types a 6-digit PIN code, and city and state fill in instantly from India Post data.
Fix-it hintsWrong state for the PIN, missing house number, test text or a vague "near temple" gets a clear hint before the order is placed.
Clean address outEach address gets a score from 0 to 100, one of three statuses (VERIFIED, NEEDS_REVIEW or INVALID) and a standardized one-line address.

Quick start

  1. Create an account. The free plan includes 1,000 checks a month.
  2. Open Install & settings in your dashboard. You get two keys:
    • pk_… is the publishable key. It's safe to put in web pages and is used by the widget.
    • sk_… is the secret key. It's for your server only. Never put it in a web page or app.
  3. Pick how you connect:
    You have…UseCoding needed
    Any website checkout (custom, Magento, OpenCart…)Checkout widget: one script tagPaste one line
    WooCommerceWordPress pluginNone
    Your own backend or mobile appREST APIA few lines
    A spreadsheet of existing addressesBulk upload in the dashboardNone
  4. Before going live, add your website domain under Allowed website domains so your publishable key only works on your site.

Checkout widget

Paste this on your checkout or address page, just before </body>. Use your own publishable key:

<script src="https://api.ichek.info/widget.js" data-key="pk_YOUR_KEY" async></script>

That's all. The widget finds the address fields on the page by itself, including forms that appear later, like WooCommerce's. Then it:

Options

AttributeWhat it does
data-block-invalid="true"If the address is INVALID, the customer must fix it or click "Continue anyway" before the form submits.
data-lang="hi"Shows the widget's own labels in Hindi.
data-auto="false"Turns off auto-detection. Tell the widget your fields yourself (below).

Point it at your fields (optional)

<script src="https://api.ichek.info/widget.js" data-key="pk_YOUR_KEY" data-auto="false"></script>
<script>
  iChek.attach({
    pincode: '#zip', city: '#city', state: '#state',
    line1: '#address1', line2: '#address2', landmark: '#landmark', phone: '#phone',
    onResult: function (r) { console.log(r.status, r.score, r.standardized.full); }
  });
</script>

Every check also fires an ichek:result event on the form, with the result in event.detail.

Shopify: Shopify doesn't allow outside scripts on its own checkout pages, so the widget can't run there. It still works on Shopify cart pages and custom COD forms. Pro customers can score every Shopify order through a webhook instead (see RTO risk scoring).

WooCommerce plugin

  1. Download ichek-woocommerce.zip.
  2. In WordPress, go to Plugins → Add New → Upload Plugin, choose the zip, then Install and Activate.
  3. Go to WooCommerce → iChek and paste your publishable key. The iChek URL is already filled in. Click Save.

The widget now runs on your checkout and cart pages. Each order stores the address check result, which shows in the order screen under the shipping address.

REST API

Base URLhttps://api.ichek.info/api/v1
AuthenticationHeader X-API-Key: sk_YOUR_SECRET_KEY
FormatJSON in, JSON out (UTF-8)
Interactive referencehttps://api.ichek.info/docs (try calls in the browser)

POST/address/verify

Checks one address and returns a score, the problems found, hints to show the customer and a standardized address.

FieldRequiredDescription
line1yesHouse / flat number, building, street
line2Area / locality
landmarkNearby landmark
cityCity / town (filled from the PIN if empty)
stateState name or code (KA, Karnataka…). Filled from the PIN if empty.
pincodeyes (India)6-digit PIN code
phoneMobile number. +91 and spaces are fine.
countryISO code. Defaults to IN. Other countries get basic checks only.
curl -X POST https://api.ichek.info/api/v1/address/verify \
  -H "X-API-Key: sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"line1":"flat 204 lotus towers, 5th cross","line2":"indiranagar",
       "city":"Bangalore","state":"KA","pincode":"560038","phone":"+91 98200 13457"}'

Response: a good address

{
  "score": 95,
  "status": "VERIFIED",
  "standardized": {
    "line1": "Flat 204 Lotus Towers, 5th Cross",
    "line2": "Indiranagar",
    "landmark": "",
    "city": "Bangalore",
    "state": "Karnataka",
    "pincode": "560038",
    "country": "IN",
    "full": "Flat 204 Lotus Towers, 5th Cross, Indiranagar, Bangalore, Karnataka 560038"
  },
  "issues": [
    { "code": "NO_LANDMARK", "severity": "info", "message": "No landmark given", "penalty": 5 }
  ],
  "suggestions": [ "Add a nearby landmark (helps the courier)" ],
  "pincode_info": { "pin": "560038", "found": true, "state": "Karnataka",
                    "districts": ["Bengaluru"], "offices": ["HAL II Stage", "Indiranagar"] },
  "location": null,
  "phone": "9820013457",
  "phone_valid": true,
  "country": "IN"
}

Response: an address that needs fixing ("line1": "near temple", "state": "Bihar", "pincode": "560038")

{
  "score": 40,
  "status": "INVALID",
  "issues": [
    { "code": "STATE_PIN_MISMATCH", "severity": "error", "message": "PIN 560038 belongs to Karnataka, not Bihar", "penalty": 25 },
    { "code": "LINE_SHORT",  "severity": "warn", "message": "Address is very short", "penalty": 20 },
    { "code": "NO_HOUSE_NO", "severity": "warn", "message": "No house / flat / plot number", "penalty": 15 }
  ],
  "suggestions": [
    "PIN and state don't match — is the PIN or the state wrong? (Karnataka)",
    "Add building, street and area",
    "Add house or flat number"
  ],
  ...
}

GET/pincode/{pin}

Looks up a PIN code and returns its state, districts and post offices. Useful for building your own auto-fill.

curl https://api.ichek.info/api/v1/pincode/560038 -H "X-API-Key: sk_YOUR_SECRET_KEY"

{ "pin": "560038", "valid_format": true, "found": true, "state": "Karnataka",
  "districts": ["Bengaluru"], "offices": ["HAL II Stage", "Indiranagar"], "source": "api" }

found is false when the PIN doesn't exist. It is null when only the PIN's range could be checked, because the lookup service was unreachable.

Response fields

FieldMeaning
score0–100. Starts at 100, and each problem subtracts its penalty.
statusVERIFIED (80+): ship it · NEEDS_REVIEW (50–79): show the hints · INVALID (<50): ask the customer to fix it
standardizedThe cleaned address: proper capitalization, abbreviations expanded (opp → Opposite, rd → Road), canonical state name, city/state filled from the PIN, and full as one line.
issues[]Each problem: code, severity (error / warn / info), message, penalty
suggestions[]Short, customer-friendly hints, ready to show on screen.
pincode_infoWhat we know about the PIN code (state, districts, post offices).
location{lat, lon, precision} when available, otherwise null.
phone, phone_validThe normalized 10-digit mobile number, and whether it's a valid Indian mobile.

Issue codes

CodeSeverityMeaning
PIN_MISSING / PIN_FORMATerrorNo PIN, or not 6 digits
PIN_NOT_FOUNDerrorThe PIN doesn't exist in India Post records
STATE_PIN_MISMATCHerrorThe state doesn't match the PIN code
JUNK_TEXTerrorTest or placeholder text ("test", "asdf", "xyz"…)
LINE_MISSINGerrorNo street address
CITY_PIN_MISMATCHwarnThe city isn't in the PIN code's area
LINE_SHORT / LINE_FEW_WORDSwarnThe address is too short to find
NO_HOUSE_NOwarnNo house / flat / plot number
STATE_UNKNOWN, CITY_MISSING, PHONE_INVALIDwarnUnrecognized state, empty city, or invalid mobile
NO_LANDMARK, STATE_FILLED, CITY_FILLED, PIN_UNVERIFIEDinfoHints and auto-fills

Bulk CSV / Excel

In the dashboard, go to Bulk upload → Addresses and upload a .csv or .xlsx file of up to 5,000 rows. Column names are matched flexibly ("Pin Code", "Mobile", "Address 1", Shopify/WooCommerce exports…). You get a score, status, standardized address and hints for every row, and can download the results as CSV.

From code: POST /api/v1/bulk/verify with multipart fields file and mode=addresses.

Errors & limits

HTTPMeaningWhat to do
401Missing or wrong keyCheck X-API-Key (server) or data-key (widget)
402Monthly quota used upUpgrade your plan, or wait for next month
403Domain not allowed, or Pro featureAdd your domain in Settings, or upgrade to Pro
429Too many requests from one IP (widget: 60 per minute)Slow down and retry
400 / 422Bad inputThe response body says which field
If iChek can't be reached, let the order through. Never block your checkout on the API. The widget already fails silently.

Identity verification (KYC)

Confirm that a customer is who they say they are, using a photo of their Aadhaar, PAN card, passport, driving licence or voter ID and a live selfie. iChek reads the card, checks the number rules, matches the selfie against the photo on the card and gives you a decision with the reasons. Every check records the customer's consent (time, IP address, device and, if allowed, location).

See what your customer sees: try the KYC demo with your own ID. Nothing is saved.

CheckWhat it does
Document numberAadhaar check digit (Verhoeff), PAN structure and holder type, passport MRZ check digits and expiry, driving licence and EPIC format
Aadhaar Secure QRReads the QR code on the card: name, date of birth and photo, signed by UIDAI. Only the last 4 digits of an Aadhaar number are stored.
Face matchCompares the live selfie with the photo on the card and returns a similarity score
Name & date of birthCompares what's printed on the card with the name and DOB you send
Photo qualityBlur, glare and darkness. Customers are asked to retake bad photos before they submit.
Re-used documentsWarns if the same document was already used in another of your verifications

Decisions: VERIFIED (all checks passed), REVIEW (a person should look: open it in the dashboard and Approve or Reject), FAILED (a critical check failed). After a review the status becomes APPROVED or REJECTED. Links that are never used become EXPIRED.

These are offline document checks. They do not query a government database, so for regulated KYC (banks, NBFCs) keep a person reviewing each case. ID photos and selfies are stored encrypted and deleted automatically after the retention period.

The easiest way. Create a link, then send it to the customer by SMS, WhatsApp or email (the dashboard has buttons for this). The customer opens it on their phone, gives consent, photographs their ID with the camera and takes a selfie. No app to install.

FieldRequiredDescription
referenceYour customer or application ID
full_nameName to match against the card
dobDate of birth to match, YYYY-MM-DD
id_typesDocuments the customer may use: aadhaar, pan, passport, dl, voter. Default: all.
purposeShown in the consent text, e.g. "opening your account"
phone, emailFor your records
callback_urlWebhook for the result (otherwise the one in Settings is used)
redirect_urlWhere the customer is sent when they finish
videotrue adds a recorded video call with an agent after the photos (video KYC)
curl -X POST https://api.ichek.info/api/v1/kyc/sessions \
  -H "X-API-Key: sk_YOUR_SECRET_KEY" -H "Content-Type: application/json" \
  -d '{"reference":"CUST-1042","full_name":"Asha Mehta","dob":"1990-04-12",
       "id_types":["aadhaar","pan"],"purpose":"opening your account"}'

{"id":"kyc_3f9c…","status":"CREATED","url":"https://api.ichek.info/verify/Xb7…","expires_at":"…"}

Links work for 72 hours and can be used once. The customer gets 3 tries at the photos.

POST/kyc/verify

If your own app already captures the photos, send them directly as multipart/form-data. You must have collected the customer's consent and send consent=true.

FieldRequiredDescription
id_typeyesaadhaar, pan, passport, dl or voter
frontyesPhoto of the ID (JPG/PNG, up to 8 MB)
backBack of the card (Aadhaar QR is usually here)
selfieLive photo of the customer, for face match
full_name, dob, id_number, referenceDetails to match against the card
consentyestrue
curl -X POST https://api.ichek.info/api/v1/kyc/verify -H "X-API-Key: sk_YOUR_SECRET_KEY" \
  -F id_type=pan -F consent=true -F full_name="Asha Mehta" \
  -F front=@pan.jpg -F selfie=@selfie.jpg

Results & webhook

EndpointUse
GET/kyc/sessions/{id}Full result: status, checks[] (code, label, pass/warn/fail, detail), extracted (details read from the card, such as number, name and DOB), face.similarity, consent record and history
GET/kyc/sessionsList, with ?status=REVIEW or ?q= name / reference
POST/kyc/sessions/{id}/review{"decision":"APPROVED | REJECTED","note":"…"}
GET/kyc/sessions/{id}/report.pdfVerification report with photos, checks and consent, for your files
GET/kyc/sessions/{id}/files/{front|back|selfie}The photos (until they are deleted)
DELETE/kyc/sessions/{id}/dataDelete the photos now, e.g. when a customer asks. The result and audit trail are kept.
WebhookWhen a customer finishes, iChek POSTs {"event":"kyc.completed","data":{…}} to your callback URL, signed with X-iChek-Signature (HMAC-SHA256 of the body using your secret key). Always confirm with GET /kyc/sessions/{id} before acting.

Video KYC with an agent

Create the link with "video": true. After the ID photo and selfie, the customer's status becomes VIDEO and the same link takes them to a video call: they join the queue when an agent is online during your working hours, or book a time (we email the booking and a reminder when you send their email). Calls are taken by your own team in the dashboard's agent console, or by the iChek team if that is switched on for your account.

On the call the agent sees the submitted photos, the automatic checks and the customer's live location; asks random questions (with the answers to check against), gives liveness instructions that appear on the customer's screen, and captures the face (compared with the selfie and ID photo) and the original ID / PAN held up to the camera (read and compared with the submitted number). Approval is only possible once the required checklist items, questions, captures and recording are in place. The whole call is recorded with a burnt-in time stamp, stored encrypted, and fingerprinted (SHA-256).

WhereWhat you get
GET /kyc/sessions/{id}video_calls[]: status, decision (APPROVED / REJECTED / RESCHEDULE / DISCONNECTED), agent, times and duration, location and whether it is in India, questions with the agent's marks, liveness prompts, checklist, capture results and recording (size, SHA-256)
GET/vkyc/calls/{call_id}/recordingThe recording (WebM), with your key or dashboard login
GET/vkyc/calls/{call_id}/captures/{face|doc|pan}Frames the agent captured
Webhookkyc.completed is sent after the call, with video_calls (decision, agent, duration, recording SHA-256)
Second checkIf you switch on "second check" in Video KYC settings, a video approval goes to REVIEW until another person approves it with {"decision":"APPROVED","reviewer":"Name"}
Video KYC follows the RBI V-CIP pattern (live, recorded, location-tagged call with random questions and the original PAN shown), but you remain responsible for your own KYC policy, including any government database checks your regulator requires.

Free accounts include 10 identity checks and 2 video calls a month; paid plans include more. A check is counted when photos are submitted. Over the limit, the API returns 402.

RTO risk scoring PRO

For COD-heavy stores. Every order gets a risk level (LOW / REVIEW / HIGH) with reasons. The score uses address quality, COD vs prepaid, order value, the customer's past RTOs and failed deliveries, one phone used with many addresses (or one address with many phones), the PIN code's RTO rate and bursts of orders. Your team works a review queue (call, then Verify or Reject) before dispatch. Courier outcomes flow back, so the rules can be tuned from real results.

EndpointUse
POST/order/scoreAddress fields plus order_id, customer_name, payment_method (COD/PREPAID) and order_value. Returns risk_level, risk_score and risk_reasons.
POST/order/outcome{"order_id":"1001","outcome":"delivered | ndr | rto | cancelled"}
POST/order/verify{"order_id":"1001","action":"verified | rejected","note":"called customer"}
GET/orders/riskOrders waiting for a decision, highest risk first
Shopify / WooCommerceNo code: paste the webhook URL from your dashboard into your store's webhook settings, and every new order is scored automatically.
AlertsSet a callback URL. REVIEW/HIGH orders are POSTed to it and signed with X-iChek-Signature (HMAC-SHA256 of the body using your secret key).

Downloads

PIN code data: India Post. Questions? Contact us through ichek.info.