Financial · API reference
Cards
Read a payment card
/v2/cards/readcards.readReads every card in a photo: number, expiry and holder with their confidences, the checks (Luhn, length for the network, expiry), the BIN record and the issuer in the bank directory. The full number is in this response only; the stored copy keeps the first six and last four digits, and the photo is never stored.
Price: 0.03 credits per successful call.
Form fields (multipart)
imagefilerequiredThe card photo: JPG, PNG or BMP, up to 10 MB. The photo is never stored.
Returns
The read ran; check status.
Show the CardResponse fieldsHide fields
idstringrequiredScan id,
crd_followed by 12 characters.objectstringrequiredAlways
card.created_atstring (date-time)requiredWhen it was created (ISO 8601, UTC).
sourcestringrequiredWhere the call came from, as shown in the console's logs.
apisdkplaygroundenvstringrequiredThe environment the read is recorded in: the credential's.
livetestprocessing_msintegerrequiredHow long the engine took, in milliseconds.
statusstringrequiredpartial: read, but something a caller relies on is missing or failed a check (issue_codesays what).unreadable: nothing to read.readpartialunreadableissue_codestringWhy a read is
partialorunreadable:no_micr_line,routing_checksum_failed,routing_prefix_invalid,layout_unrecognised,weak_characters,no_card,number_unreadable,luhn_failed,low_confidence.issuestringPlain-words reason, when not
read.imageobjectrequiredDimensions only: card photos are never stored.
Show 2 fieldsHide fields
widthintegerrequiredheightintegerrequired
cards_detectedintegerrequiredcardsarray of objectsrequiredEvery card found, strongest first.
Show 21 fieldsHide fields
indexintegerrequireddescriptionstringThe engine's label, for example
Card #1.fieldsarray of objectsEvery field the engine read, verbatim.
Show 3 fieldsHide fields
namestringrequiredField name:
number,valid_thru,holder_name…valuestringconfidencenumber0 to 100.
confidencenumberrequiredSummary confidence for the card, 0 to 100.
warpedBoxarray of numbersThe engine's own box, verbatim.
boxarray of numbersrequiredFour corners x1,y1 … x4,y4, in image pixels.
numberstringThe full number: in the read response only, never in stored copies.
first6stringlast4stringlengthintegerrequiredDigits in the number; 0 when it could not be read.
fingerprintstringKeyed hash of the number,
cf_+ 24 hex: stable across scans, safe to store.luhn_validbooleanrequiredscheme_validbooleanrequiredLuhn and a length that fits the network.
scheme_checksobjectrequiredShow 3 fieldsHide fields
luhnbooleanrequiredlengthbooleanrequirediin_knownbooleanrequiredThe BIN is in the tables.
network_from_prefixstringexpiredbooleanexpires_in_daysintegerNegative once expired.
expiry_statusstringrequiredexpiring_soon: 60 days or less left.validexpiring_soonexpiredunknownbinobjectWho issued a card. Fields that are unknown are absent.
Show 22 fieldsHide fields
binstringrequiredThe first 6 to 8 digits.
networkstringVisa, Mastercard, American Express, Discover…
typestringDebit, Credit…
levelstringClassic, Gold, World…
issuerstringThe issuing bank's name.
countrystringIssuing country, ISO 3166-1 alpha-2.
country_namestringcountry_code3stringflagstringFlag emoji.
flag_urlstringThe country's flag (SVG), relative to the API base.
bankobject or anyThe issuer in the bank directory, with logo. Returned by GET /v2/bin/{digits}.
currencystringISO 4217.
currency_namestringfundingstringcreditdebitprepaidchargeunknownis_prepaidbooleanis_commercialbooleanis_reloadablebooleancategorystringconsumercommercialissuer_countrystringphonestringIssuer contact, when known.
urlstringIssuer website, when known.
sourcestringWhich tier answered.
bankobject or anynumber_validbooleanThe engine's own card-level pass flag.
cardobjectOne payment card in a photo.
Show 21 fieldsHide fields
indexintegerrequireddescriptionstringThe engine's label, for example
Card #1.fieldsarray of objectsEvery field the engine read, verbatim.
Show 3 fieldsHide fields
namestringrequiredField name:
number,valid_thru,holder_name…valuestringconfidencenumber0 to 100.
confidencenumberrequiredSummary confidence for the card, 0 to 100.
warpedBoxarray of numbersThe engine's own box, verbatim.
boxarray of numbersrequiredFour corners x1,y1 … x4,y4, in image pixels.
numberstringThe full number: in the read response only, never in stored copies.
first6stringlast4stringlengthintegerrequiredDigits in the number; 0 when it could not be read.
fingerprintstringKeyed hash of the number,
cf_+ 24 hex: stable across scans, safe to store.luhn_validbooleanrequiredscheme_validbooleanrequiredLuhn and a length that fits the network.
scheme_checksobjectrequiredShow 3 fieldsHide fields
luhnbooleanrequiredlengthbooleanrequirediin_knownbooleanrequiredThe BIN is in the tables.
network_from_prefixstringexpiredbooleanexpires_in_daysintegerNegative once expired.
expiry_statusstringrequiredexpiring_soon: 60 days or less left.validexpiring_soonexpiredunknownbinobjectWho issued a card. Fields that are unknown are absent.
Show 22 fieldsHide fields
binstringrequiredThe first 6 to 8 digits.
networkstringVisa, Mastercard, American Express, Discover…
typestringDebit, Credit…
levelstringClassic, Gold, World…
issuerstringThe issuing bank's name.
countrystringIssuing country, ISO 3166-1 alpha-2.
country_namestringcountry_code3stringflagstringFlag emoji.
flag_urlstringThe country's flag (SVG), relative to the API base.
bankobject or anyThe issuer in the bank directory, with logo. Returned by GET /v2/bin/{digits}.
currencystringISO 4217.
currency_namestringfundingstringcreditdebitprepaidchargeunknownis_prepaidbooleanis_commercialbooleanis_reloadablebooleancategorystringconsumercommercialissuer_countrystringphonestringIssuer contact, when known.
urlstringIssuer website, when known.
sourcestringWhich tier answered.
bankobject or anynumber_validbooleanThe engine's own card-level pass flag.
binobjectWho issued a card. Fields that are unknown are absent.
Show 22 fieldsHide fields
binstringrequiredThe first 6 to 8 digits.
networkstringVisa, Mastercard, American Express, Discover…
typestringDebit, Credit…
levelstringClassic, Gold, World…
issuerstringThe issuing bank's name.
countrystringIssuing country, ISO 3166-1 alpha-2.
country_namestringcountry_code3stringflagstringFlag emoji.
flag_urlstringThe country's flag (SVG), relative to the API base.
bankobject or anyThe issuer in the bank directory, with logo. Returned by GET /v2/bin/{digits}.
currencystringISO 4217.
currency_namestringfundingstringcreditdebitprepaidchargeunknownis_prepaidbooleanis_commercialbooleanis_reloadablebooleancategorystringconsumercommercialissuer_countrystringphonestringIssuer contact, when known.
urlstringIssuer website, when known.
sourcestringWhich tier answered.
bankobject or any
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.415The file type is not accepted (JPG, PNG or BMP).429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v2/cards/read \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-F image=@card-visa.jpg{
"id": "crd_QVvX1lY05q56",
"object": "card",
"created_at": "2026-10-16T08:46:10.000Z",
"source": "api",
"env": "test",
"processing_ms": 1046,
"image": {
"width": 900,
"height": 1200
},
"status": "read",
"cards_detected": 1,
"cards": [
{
"index": 0,
"confidence": 99.61734,
"description": "Card #1",
"fields": [
{
"confidence": 92.40817,
"name": "number",
"valid": true,
"value": "4242424242424242",
"box": [
125,
621,
690,
621,
690,
669,
125,
669
]
},
{
"confidence": 89.78328,
"name": "valid_thru",
"value": "09/29",
"box": [
419,
696,
515,
696,
515,
726,
419,
726
]
},
{
"confidence": 84.54898,
"name": "holder_name",
"value": "KEZA AMANI",
"box": [
125,
758,
329,
758,
329,
788,
125,
788
]
}
],
"number_valid": true,
"warpedBox": [
70.1301,
360.1412,
830.0774,
359.9733,
830.102,
838.9948,
69.9964,
838.7739
],
"box": [
70,
360,
830,
360,
830,
839,
70,
839
],
"number": "4242424242424242",
"first6": "424242",
"last4": "4242",
"length": 16,
"fingerprint": "cf_f7423c941cbe11f80a824f3e",
"luhn_valid": true,
"scheme_valid": true,
"scheme_checks": {
"luhn": true,
"length": true,
"iin_known": true
},
"network_from_prefix": "Visa",
"expired": false,
"expires_in_days": 1080,
"expiry_status": "valid",
"bin": {
"network": "Visa",
"type": "Debit",
"level": "Classic",
"funding": "debit",
"issuer": "Aeron Fintech",
"country": "RW",
"currency": "RWF",
"is_commercial": false,
"is_prepaid": false,
"url": "https://aeron-fintech.example",
"source": "local+online",
"bin": "424242",
"category": "consumer",
"is_reloadable": true,
"country_name": "Rwanda",
"country_code3": "RWA",
"issuer_country": "RW",
"flag": "🇷🇼",
"currency_name": "Rwanda Franc",
"flag_url": "/v2/flags/rw.svg"
},
"bank": {
"read": {
"name": "Aeron Fintech",
"country": "RW"
},
"resolved": {
"profile_id": "bank_1d4e94dde9d17fc07f",
"name": "Aeron Fintech",
"country": "Rwanda",
"country_code": "RW",
"city": "Kigali",
"address": "Aeron House, 14 Innovation Way, Kigali",
"status": "active",
"logo_url": "/v2/banks/bank_1d4e94dde9d17fc07f/logo",
"flag_url": "/v2/flags/rw.svg"
},
"match_confidence": 1,
"name_match": 0.99,
"alternatives": []
}
}
],
"card": {
"index": 0,
"confidence": 99.61734,
"description": "Card #1",
"fields": [
{
"confidence": 92.40817,
"name": "number",
"valid": true,
"value": "4242424242424242",
"box": [
125,
621,
690,
621,
690,
669,
125,
669
]
},
{
"confidence": 89.78328,
"name": "valid_thru",
"value": "09/29",
"box": [
419,
696,
515,
696,
515,
726,
419,
726
]
},
{
"confidence": 84.54898,
"name": "holder_name",
"value": "KEZA AMANI",
"box": [
125,
758,
329,
758,
329,
788,
125,
788
]
}
],
"number_valid": true,
"warpedBox": [
70.1301,
360.1412,
830.0774,
359.9733,
830.102,
838.9948,
69.9964,
838.7739
],
"box": [
70,
360,
830,
360,
830,
839,
70,
839
],
"number": "4242424242424242",
"first6": "424242",
"last4": "4242",
"length": 16,
"fingerprint": "cf_f7423c941cbe11f80a824f3e",
"luhn_valid": true,
"scheme_valid": true,
"scheme_checks": {
"luhn": true,
"length": true,
"iin_known": true
},
"network_from_prefix": "Visa",
"expired": false,
"expires_in_days": 1080,
"expiry_status": "valid"
},
"bin": {
"network": "Visa",
"type": "Debit",
"level": "Classic",
"funding": "debit",
"issuer": "Aeron Fintech",
"country": "RW",
"currency": "RWF",
"is_commercial": false,
"is_prepaid": false,
"url": "https://aeron-fintech.example",
"source": "local+online",
"bin": "424242",
"category": "consumer",
"is_reloadable": true,
"country_name": "Rwanda",
"country_code3": "RWA",
"issuer_country": "RW",
"flag": "🇷🇼",
"currency_name": "Rwanda Franc",
"flag_url": "/v2/flags/rw.svg"
},
"bank": {
"read": {
"name": "Aeron Fintech",
"country": "RW"
},
"resolved": {
"profile_id": "bank_1d4e94dde9d17fc07f",
"name": "Aeron Fintech",
"country": "Rwanda",
"country_code": "RW",
"city": "Kigali",
"address": "Aeron House, 14 Innovation Way, Kigali",
"status": "active",
"logo_url": "/v2/banks/bank_1d4e94dde9d17fc07f/logo",
"flag_url": "/v2/flags/rw.svg"
},
"match_confidence": 1,
"name_match": 0.99,
"alternatives": []
}
}Read a card number
/v2/cards/numbercards.numberReads the card number from a photo, with its network and checks. Nothing is stored.
Price: 0.02 credits per successful call.
Form fields (multipart)
imagefilerequiredThe card photo: JPG, PNG or BMP, up to 10 MB. The photo is never stored.
Returns
The read ran; check status.
Show the CardNumber fieldsHide fields
objectstringrequiredAlways
card_number.statusstringrequiredpartial: read, but something a caller relies on is missing or failed a check (issue_codesays what).unreadable: nothing to read.readpartialunreadableissue_codestringWhy a read is
partialorunreadable:no_micr_line,routing_checksum_failed,routing_prefix_invalid,layout_unrecognised,weak_characters,no_card,number_unreadable,luhn_failed,low_confidence.issuestringprocessing_msintegerrequiredHow long the engine took, in milliseconds.
numberstringThe full number: in this response only, never stored.
first6stringlast4stringlengthintegernetworkstringluhn_validbooleanscheme_validbooleanconfidencenumber0 to 100.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.415The file type is not accepted (JPG, PNG or BMP).429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v2/cards/number \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-F image=@card-visa.jpg{
"object": "card_number",
"status": "read",
"processing_ms": 920,
"number": "4242424242424242",
"first6": "424242",
"last4": "4242",
"length": 16,
"network": "Visa",
"luhn_valid": true,
"scheme_valid": true,
"confidence": 92.4
}Read a card's expiry date
/v2/cards/expirycards.expiryReads the expiry date from a card photo and works out whether the card has expired and how many days it has left. Nothing is stored.
Price: 0.02 credits per successful call.
Form fields (multipart)
imagefilerequiredThe card photo: JPG, PNG or BMP, up to 10 MB. The photo is never stored.
Returns
The read ran; check status.
Show the CardExpiry fieldsHide fields
objectstringrequiredAlways
card_expiry.statusstringrequiredpartial: read, but something a caller relies on is missing or failed a check (issue_codesays what).unreadable: nothing to read.readpartialunreadableissue_codestringWhy a read is
partialorunreadable:no_micr_line,routing_checksum_failed,routing_prefix_invalid,layout_unrecognised,weak_characters,no_card,number_unreadable,luhn_failed,low_confidence.issuestringvalid_thrustringMM/YY as printed.
valid_fromstringMM/YY, when printed.
expiredbooleanexpires_in_daysintegerNegative once expired.
expiry_statusstringexpiring_soon: 60 days or less left.validexpiring_soonexpiredunknownconfidencenumber0 to 100.
processing_msintegerrequiredHow long the engine took, in milliseconds.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.415The file type is not accepted (JPG, PNG or BMP).429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v2/cards/expiry \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-F image=@card-visa.jpg{
"object": "card_expiry",
"status": "read",
"valid_thru": "09/29",
"expired": false,
"expires_in_days": 1080,
"expiry_status": "valid",
"confidence": 89.5,
"processing_ms": 1251
}Check a card number
/v2/cards/checkcards.checkChecks a typed card number, for example from a checkout form: the Luhn checksum, a length that fits the network, the expiry when sent, and the BIN record. Accept the card when scheme_valid is true and expired is not. Only the first six and last four digits come back; nothing is stored.
Price: 0.002 credits per successful call.
Body parameters
numberstringrequired12 to 19 digits; spaces are ignored. Never stored.
expirystringMM/YY.
Returns
The checks ran.
Show the CardCheck fieldsHide fields
objectstringrequiredAlways
card_check.first6stringrequiredlast4stringrequiredlengthintegerrequirednetworkstringluhn_validbooleanrequiredlength_validbooleanrequiredThe length fits the network.
scheme_validbooleanrequiredLuhn and length both hold.
expiredbooleanWhen an expiry was sent.
expires_in_daysintegerWhen an expiry was sent.
expiry_statusstringexpiring_soon: 60 days or less left.validexpiring_soonexpiredunknownbinobjectWho issued a card. Fields that are unknown are absent.
Show 22 fieldsHide fields
binstringrequiredThe first 6 to 8 digits.
networkstringVisa, Mastercard, American Express, Discover…
typestringDebit, Credit…
levelstringClassic, Gold, World…
issuerstringThe issuing bank's name.
countrystringIssuing country, ISO 3166-1 alpha-2.
country_namestringcountry_code3stringflagstringFlag emoji.
flag_urlstringThe country's flag (SVG), relative to the API base.
bankobject or anyThe issuer in the bank directory, with logo. Returned by GET /v2/bin/{digits}.
currencystringISO 4217.
currency_namestringfundingstringcreditdebitprepaidchargeunknownis_prepaidbooleanis_commercialbooleanis_reloadablebooleancategorystringconsumercommercialissuer_countrystringphonestringIssuer contact, when known.
urlstringIssuer website, when known.
sourcestringWhich tier answered.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v2/cards/check \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"number": "4242 4242 4242 4242",
"expiry": "09/29"
}'{
"object": "card_check",
"first6": "424242",
"last4": "4242",
"length": 16,
"network": "Visa",
"luhn_valid": true,
"length_valid": true,
"scheme_valid": true,
"expired": false,
"expires_in_days": 1080,
"expiry_status": "valid",
"bin": {
"network": "Visa",
"type": "Debit",
"level": "Classic",
"funding": "debit",
"issuer": "Aeron Fintech",
"country": "RW",
"currency": "RWF",
"is_commercial": false,
"is_prepaid": false,
"url": "https://aeron-fintech.example",
"source": "local+online",
"bin": "424242",
"category": "consumer",
"is_reloadable": true,
"country_name": "Rwanda",
"country_code3": "RWA",
"issuer_country": "RW",
"flag": "🇷🇼",
"currency_name": "Rwanda Franc",
"flag_url": "/v2/flags/rw.svg"
}
}Fingerprint a card number
/v2/cards/fingerprintcards.fingerprintTurns a card number into a fingerprint: always the same for the same card, and impossible to turn back into the number. Store it to recognise a card you have seen before; a card read from a photo carries the same fingerprint.
Price: 0.002 credits per successful call.
Body parameters
numberstringrequired12 to 19 digits; spaces are ignored. Never stored.
Returns
The fingerprint.
Show the CardFingerprint fieldsHide fields
objectstringrequiredAlways
card_fingerprint.fingerprintstringrequiredcf_+ 24 hex. The same card always gives the same value; it cannot be turned back into the number.first6stringrequiredlast4stringrequired
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v2/cards/fingerprint \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"number": "4242 4242 4242 4242"
}'{
"object": "card_fingerprint",
"fingerprint": "cf_f7423c941cbe11f80a824f3e",
"first6": "424242",
"last4": "4242"
}