Skip to main content

KTP OCR

Extract NIK, name, and address from a KTP photo.

Base URL​

https://use.api.co.id

Send a KTP photo to POST /ocr/ktp-extract as multipart/form-data (field file) with the x-api-co-id header. The response contains NIK, name, place/date of birth, address, RT/RW, kelurahan, kecamatan, city, province, religion, marital status, occupation, citizenship, and validity. OCR fields are always returned in full.

File format & limits​

RequirementValue
FormatsJPG, JPEG, PNG
Maximum size5 MB per file (file and selfie)
ContentIndonesian KTP photo

OCR only​

curl -X POST "https://use.api.co.id/ocr/ktp-extract" \
-H "x-api-co-id: YOUR_API_KEY" \
-F "file=@/absolute/path/to/ktp.jpg"
{
"is_success": true,
"message": "Success",
"data": {
"nik": "3201012345678901",
"nama": "JOHN DOE",
"tempat_lahir": "JAKARTA",
"tanggal_lahir": "01-01-1990",
"jenis_kelamin": "LAKI-LAKI",
"alamat": "JL. MERDEKA NO. 123",
"rt": "001",
"rw": "002",
"kelurahan": "GAMBIR",
"kecamatan": "GAMBIR",
"kota": "JAKARTA PUSAT",
"provinsi": "DKI JAKARTA",
"berlaku_hingga": "SEUMUR HIDUP"
}
}

OCR + KTP Check​

Set verify_result to "true" to verify the OCR result through KTP Check (ID Verification). Because the request uses multipart/form-data, send this value as the form-data string "true". The selfie field is optional.

curl -X POST "https://use.api.co.id/ocr/ktp-extract" \
-H "x-api-co-id: YOUR_API_KEY" \
-F "file=@/absolute/path/to/ktp.jpg" \
-F "verify_result=true" \
-F "selfie=@/absolute/path/to/selfie.jpg"

API.CO.ID uses the OCR result as the KTP Check input:

  • nik, name, and date_of_birth come from the OCR result;
  • identity uses the same KTP file;
  • selfie uses the customer's selfie file if sent;
  • reference_number, the account email, and the approved KYC phone are prepared server-side.

If selfie is sent, API.CO.ID forwards it to the provider and the verification response is used as is. If it is not sent, API.CO.ID uses an internal fallback selfie to stay compatible with older requests.

The customer needs id-verification access and approved eKYC. If the KTP Check requirements are not met, OCR still returns the full OCR fields and the verification billing entry is marked not_charged. Verification details are nested under verification_result, billing details under billing.

{
"is_success": true,
"message": "Success",
"data": {
"nik": "3201012345678901",
"nama": "JOHN DOE",
"tempat_lahir": "JAKARTA",
"tanggal_lahir": "01-01-1990",
"jenis_kelamin": "LAKI-LAKI",
"alamat": "JL. MERDEKA NO. 123",
"rt": "001",
"rw": "002",
"kelurahan": "GAMBIR",
"kecamatan": "GAMBIR",
"kota": "JAKARTA PUSAT",
"provinsi": "DKI JAKARTA",
"berlaku_hingga": "SEUMUR HIDUP",
"verification_result": {
"result_verified": true,
"result_verified_message": "verified",
"verification_reference_number": "KTP20260725103000"
},
"billing": {
"charged_products": [
{"product_code": "ktp-ocr", "status": "charged"},
{"product_code": "id-verification", "status": "charged"}
]
}
}
}

If verification is not processed (for example, KYC not yet approved), the OCR fields stay complete and the verification part becomes:

{
"verification_result": {
"result_verified": false,
"result_verified_message": "ID verification was not processed because KYC for id-verification is kyc_required.",
"verification_reference_number": "KTP20260725103000"
},
"billing": {
"charged_products": [
{"product_code": "ktp-ocr", "status": "charged"},
{"product_code": "id-verification", "status": "not_charged", "reason": "kyc_not_approved"}
]
}
}

Billing​

  • KTP OCR and KTP Check are two separate billing products.
  • KTP OCR is charged after OCR succeeds.
  • id-verification is charged only if the provider processes the KTP Check.
  • If KTP Check fails because of KYC, balance, OCR result validation, or a provider error, id-verification is not charged.

Common errors​

HTTPCondition
400Bad RequestFile missing, unsupported file type, file too large, invalid selfie, or verify_result is not a boolean
401UnauthorizedAPI key missing or wrong
402Payment RequiredInsufficient KTP OCR balance
429Too Many RequestsRate limit/quota exceeded
500Server ErrorOCR pipeline/internal provider failure
Was this page helpful?