
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
Format-true synthetic test data for 27 countries (Kenya first) — valid KRA PINs & M-Pesa numbers, Nigerian BVNs, South African IDs, banks & SWIFT/BIC, KYC/transfer/payment scenarios. Free, no caps. The engine behind Sampuli.
Format-true synthetic test data — 27 countries, Kenya first. Valid KRA PINs and M-Pesa numbers, Nigerian BVNs, South African IDs, real bank SWIFT/BIC codes, and ready-made KYC / transfer / payment / merchant scenarios per country — generated on the spot, never real people.
Built for QA and dev teams at African banks and fintechs (and beyond) who need test data that passes their own format validation. Free, no volume caps. The engine behind Sampuli.
npm install @sampuli/data
import { generate, generateMany, listPacks } from '@sampuli/data'
listPacks() // ['KE','DZ','AO', … 'FR','NL','BR', …] — every Sampuli country
generate('ke.phone') // → '0712345678' (a real Safaricom/Airtel/Telkom prefix)
generate('ke.kra_pin') // → 'A123456789Z' (valid KRA PIN format)
generate('ng.person') // → a coherent Nigerian record
generate('za.person') // → a coherent South African record
generate('ke.person')
// → {
// name: 'Mercy Achieng', phone: '0748163920', id: '27380011',
// kra: 'A661044820Q', bank: 'Equity Bank', swift: 'EQBLKENA',
// account: '830155120774', amount: 'KES 12,400.00'
// }
generateMany('ke.person', 200) // → 200 coherent 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). (Kenya's tax id field is kra; most other packs use tax.)
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).
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 all 27 Sampuli country packs, free, with no volume caps — Africa
(Kenya, Nigeria, South Africa, Egypt, Ghana, Tanzania, Uganda, Rwanda,
Algeria, Angola, Morocco, Ethiopia, Côte d'Ivoire, DR Congo, Tunisia,
Cameroon, Mauritius), plus Germany, Switzerland, UK, Canada, US, UAE,
Australia, China, India, Japan. Try them at sampuli.site.
Additional packs can be plugged in at runtime via registerPack(pack).
Every value is format-valid: it matches the real shape and passes standard format checks. It is entirely synthetic — invented at call time, corresponding to no real person, account, or business.
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.