
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
@sampuli/data
Advanced tools
Synthetic, format-true test data for countries worldwide — national IDs, tax numbers, IBANs & SWIFT/BIC, bank accounts, phone numbers and ready-made KYC/transfer/payment scenarios, each correct for its own country. For QA and CI at banks and fintechs anyw
Format-true synthetic test data for countries worldwide. National IDs, tax numbers, IBANs & SWIFT/BIC, bank accounts, phone numbers and ready-made KYC / transfer / payment scenarios — each in the correct format for its own country, generated on the spot.
One API, dozens of countries: Kenyan KRA PINs & M-Pesa numbers, Nigerian BVNs, German & Gulf IBANs, Italian Codice Fiscale, Brazilian CPF/CNPJ, Mexican CLABE, Turkish TCKN, Singapore NRIC — and many more, each shaped to its national rules (checksums, prefixes, bank codes).
Every value is entirely synthetic. It matches the real format only and corresponds to no real person, account, or registered number. Never present any output as a genuine ID, tax number, IBAN, or bank account.
Built for QA and CI at banks and fintechs anywhere — test data that passes your own format validation. Free, no volume caps. The engine behind Sampuli.
npm install @sampuli/data
import { generate, generateMany, listPacks } from '@sampuli/data'
listPacks() // every installed country, e.g.
// ['KE','NG','ZA','EG','DE','FR','IT','TR','SA','BR','MX','SG', …]
// One value — the spec is `country.field`:
generate('ke.phone') // Kenya → '0712345678'
generate('ng.bvn') // Nigeria → '22803022407'
generate('de.account') // Germany → 'DE19100900004650895069' (IBAN)
generate('it.id') // Italy → 'LNEFRC90M22F205G' (Codice Fiscale)
generate('sg.id') // Singapore → 'S6763250H' (NRIC)
// A whole coherent record — any country:
generate('de.person')
// → {
// name: 'Mia Zimmermann', phone: '0179 1480356', id: 'L0PYL465F',
// tax: '74259823954', bank: 'HypoVereinsbank', swift: 'HYVEDEMMXXX',
// account: 'DE68700202706388873556', amount: '€16.680,00'
// }
generateMany('br.person', 500) // → 500 coherent Brazilian records
Every pack uses the same spec shape — swap the country code. A pack's fields
and presets vary by country; discover them with listFields(code) /
listPresets(code). Records stay internally coherent (bank ↔ SWIFT, gender ↔
name, town ↔ region, email ↔ name).
CommonJS works too:
const { generate } = require('@sampuli/data')
generate(spec, settings?) — the spec is pack.selector:
| Spec | Returns |
|---|---|
'ke.phone', 'ke.kra_pin', 'ke.national_id', … | a single field value |
'ke.person' (or just 'ke') | a full coherent record (object) |
'ke.preset:kyc' | ordered [label, value] rows for a scenario |
Discover what a pack offers:
import { listFields, listPresets } from '@sampuli/data'
listFields('ke') // [{ key: 'phone', label: 'Phone', num: false, ... }, ...]
listPresets('ke') // [{ key: 'kyc', name: 'KYC customer profile', ... }, ...]
Kenya's field keys, for example: name, phone, id, kra, bank,
swift, account, amount, gender, dob, marital, occupation,
town, county, gps, address, business, paybill, till, plate,
email, avatar, ref. Presets: kyc, pesalink, schoolfees, fx,
merchant. Other countries share the common core (name/phone/id/tax/bank/
swift/account/amount) with locale-specific extras and presets — always check
listFields(code).
Every country also has payment-card and passport fields (off by default):
card (Luhn-valid PAN, scheme-correct BIN), card_scheme (Visa / Mastercard /
American Express), card_expiry (MM/YY), card_cvv, passport (number),
passport_expiry, and passport_mrz — a full ICAO-9303 TD3 machine-readable
zone with correct check digits, coherent with the record's name and gender.
generate('dk.card') // → '4536 3094 5269 0134' (Visa, Luhn-valid)
generate('gb.person', { fields: ['name', 'card', 'card_scheme', 'card_cvv', 'passport'] })
generate('za.passport_mrz') // → two 44-char MRZ lines with valid ICAO check digits
And a set of cross-country extras (also off by default): a transaction
(txn_datetime, txn_type, txn_status, txn_channel, txn_mcc with real
ISO-18245 codes), ip / ipv6, licence (driver's licence), income
(currency-magnitude-aware for the pack's currency), employer, and country.
generate('jp.income') // → '9,970,000 JPY' (scaled to the local currency)
generate('ke.person', { fields: ['name', 'txn_datetime', 'txn_type', 'txn_mcc', 'ip', 'income'] })
generate('ke.person') returns the on-by-default columns. To include the
optional PII — email, GPS, date of birth, address, occupation, avatar, plate,
and the rest — pass fields (the package equivalent of the app's column
toggles):
generate('ke.person', { fields: 'all' })
// → every field the pack has: name, phone, id, kra, …, gender, dob, gps,
// address, email, avatar, ref
generate('ke.person', { fields: ['name', 'phone', 'email', 'gps', 'dob'] })
// → { name, phone, email, gps, dob } — exactly those, in that order
generateMany('za.person', 500, { fields: ['name', 'said', 'phone', 'email'] })
Records stay coherent whichever fields you pick (e.g. email derives from the
generated name).
generate('ke.phone', { phoneFmt: 'plus' }) // '+254712345678'
generate('ke.phone', { network: 'safaricom' }) // Safaricom prefixes only
generate('ke.kra_pin', { pinType: 'P' }) // company PIN (P…)
generate('ke.amount', { amountStyle: 'number' }) // 12400 (number, not 'KES 12,400.00')
Records stay internally coherent: bank and swift describe the same bank,
gender matches the first name, county matches the town.
Pass a seed and you get the same data every time — ideal for CI snapshots:
generate('ke.person', { seed: 'test-42' }) // identical on every run
generateMany('ke.person', 100, { seed: 'batch' }) // identical batch every run
Ships every Sampuli country pack, free, with no volume caps — countries across
Africa, Europe, the Middle East, Asia-Pacific and the Americas, and growing.
Call listPacks() for the full set installed, or browse them at
sampuli.site. Additional packs can be plugged in at
runtime via registerPack(pack).
Every value is format-correct: it matches the real shape and passes standard format checks. It is entirely synthetic — invented at call time and corresponding to no real person, account, business, or registered number. It is for testing only; do not present any output as a genuine KRA PIN, national ID, tax number, IBAN, or bank account.
MIT.
FAQs
Synthetic, format-true test data for countries worldwide — national IDs, tax numbers, IBANs & SWIFT/BIC, bank accounts, phone numbers and ready-made KYC/transfer/payment scenarios, each correct for its own country. For QA and CI at banks and fintechs anyw
The npm package @sampuli/data receives a total of 13 weekly downloads. As such, @sampuli/data popularity was classified as not popular.
We found that @sampuli/data demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.