npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@kra-connect/node

v0.1.2

Published

Official Node.js/TypeScript SDK for KRA GavaConnect API - Tax compliance and verification for Kenya

Readme

@kra-connect/node

Official Node.js/TypeScript SDK for Kenya Revenue Authority's GavaConnect API

npm version License: MIT TypeScript

Repository

Features

  • Full TypeScript Support - Complete type definitions
  • PIN Verification - Verify KRA PIN numbers
  • TCC Verification - Check Tax Compliance Certificates
  • e-Slip Validation - Validate electronic payment slips
  • NIL Returns - File NIL returns programmatically
  • Taxpayer Details - Retrieve taxpayer information
  • Automatic Retry - Built-in retry logic with exponential backoff
  • Response Caching - Configurable caching for improved performance
  • Rate Limiting - Protect against rate limit errors
  • Axios-Based - Built on the popular Axios HTTP client

Installation

npm install @kra-connect/node

Or with Yarn:

yarn add @kra-connect/node

Or with pnpm:

pnpm add @kra-connect/node

Quick Start

Basic Usage

import { KraClient } from '@kra-connect/node';

// Initialize the client
const client = new KraClient({ apiKey: 'your-api-key' });

// Verify a PIN
const result = await client.verifyPin('P051234567A');

if (result.isValid) {
  console.log(`Taxpayer: ${result.taxpayerName}`);
  console.log(`Status: ${result.status}`);
} else {
  console.log(`Invalid PIN: ${result.errorMessage}`);
}

Using Environment Variables

Create a .env file:

KRA_API_KEY=your_api_key_here
KRA_API_BASE_URL=https://api.kra.go.ke/gavaconnect/v1
KRA_TIMEOUT=30000

Then use the client:

import { KraClient, KraConfig } from '@kra-connect/node';
import 'dotenv/config';

// Automatically loads from environment variables
const client = new KraClient(KraConfig.fromEnv());

const result = await client.verifyPin('P051234567A');

TypeScript Example

import { KraClient, PinVerificationResult, KraConfig } from '@kra-connect/node';

const config: KraConfig = {
  apiKey: process.env.KRA_API_KEY!,
  timeout: 30000,
  retryConfig: {
    maxAttempts: 3,
    initialDelay: 1000,
  },
};

const client = new KraClient(config);

async function verifySupplier(pin: string): Promise<void> {
  try {
    const result: PinVerificationResult = await client.verifyPin(pin);

    if (result.isValid) {
      console.log('✓ Valid supplier');
      console.log(`  Name: ${result.taxpayerName}`);
      console.log(`  Type: ${result.businessType}`);
    } else {
      console.log('✗ Invalid PIN');
    }
  } catch (error) {
    console.error('Verification failed:', error);
  }
}

API Reference

KraClient

The main client for interacting with the KRA GavaConnect API.

Constructor

new KraClient(config: KraConfig)

Methods

verifyPin(pinNumber: string): Promise<PinVerificationResult>

Verify a KRA PIN number.

Parameters:

  • pinNumber - The PIN to verify (format: P + 9 digits + letter)

Returns:

  • Promise<PinVerificationResult> - Verification result with taxpayer details

Example:

const result = await client.verifyPin('P051234567A');
verifyTcc(tccNumber: string, kraPin: string): Promise<TccVerificationResult>

Verify a Tax Compliance Certificate.

Parameters:

  • tccNumber - The TCC number to verify
  • kraPin - Taxpayer PIN associated with the certificate

Returns:

  • Promise<TccVerificationResult> - TCC verification result

Example:

const result = await client.verifyTcc('TCC123456', 'P051234567A');
console.log(`Valid until: ${result.expiryDate}`);
validateEslip(slipNumber: string): Promise<EslipValidationResult>

Validate an electronic payment slip.

Parameters:

  • slipNumber - The e-slip number to validate

Returns:

  • Promise<EslipValidationResult> - Validation result
fileNilReturn(data: NilReturnRequest): Promise<NilReturnResult>

File a NIL return for a taxpayer.

Parameters:

  • data.pinNumber - Taxpayer's PIN
  • data.obligationCode - Obligation code as defined by KRA
  • data.month / data.year - Tax period expressed as month/year

Returns:

  • Promise<NilReturnResult> - Filing result

Example:

const result = await client.fileNilReturn({
  pinNumber: 'P051234567A',
  obligationCode: 1,
  month: 1,
  year: 2024,
});
getTaxpayerDetails(pinNumber: string): Promise<TaxpayerDetails>

Retrieve detailed taxpayer information.

Parameters:

  • pinNumber - Taxpayer's PIN

Returns:

  • Promise<TaxpayerDetails> - Complete taxpayer information

Configuration

KraConfig

interface KraConfig {
  apiKey?: string;
  clientId?: string;
  clientSecret?: string;
  tokenUrl?: string;
  baseUrl?: string;
  timeout?: number;
  retryConfig?: RetryConfig;
  cacheConfig?: CacheConfig;
  rateLimitConfig?: RateLimitConfig;
}

RetryConfig

interface RetryConfig {
  maxAttempts?: number;       // Default: 3
  initialDelay?: number;      // Default: 1000ms
  maxDelay?: number;          // Default: 30000ms
  exponentialBase?: number;   // Default: 2
}

CacheConfig

interface CacheConfig {
  enabled?: boolean;          // Default: true
  ttl?: number;              // Default: 3600 seconds
  maxSize?: number;          // Default: 1000
}

Error Handling

import {
  KraClient,
  InvalidPinFormatError,
  ApiAuthenticationError,
  ApiTimeoutError,
  RateLimitExceededError,
  ApiError,
} from '@kra-connect/node';

try {
  const result = await client.verifyPin('P051234567A');
} catch (error) {
  if (error instanceof InvalidPinFormatError) {
    console.error('Invalid PIN format:', error.message);
  } else if (error instanceof ApiAuthenticationError) {
    console.error('Authentication failed:', error.message);
  } else if (error instanceof ApiTimeoutError) {
    console.error('Request timed out:', error.message);
  } else if (error instanceof RateLimitExceededError) {
    console.error(`Rate limit exceeded. Retry after ${error.retryAfter}s`);
  } else if (error instanceof ApiError) {
    console.error('API error:', error.message, error.statusCode);
  }
}

Advanced Usage

Batch Verification

const pins = ['P051234567A', 'P051234567B', 'P051234567C'];

const results = await Promise.all(
  pins.map(pin => client.verifyPin(pin))
);

results.forEach((result, index) => {
  console.log(`${pins[index]}: ${result.isValid ? '✓' : '✗'}`);
});

Custom Configuration

const client = new KraClient({
  apiKey: process.env.KRA_API_KEY!,
  baseUrl: 'https://api.kra.go.ke/gavaconnect/v1',
  timeout: 60000, // 60 seconds
  retryConfig: {
    maxAttempts: 5,
    initialDelay: 2000,
    maxDelay: 60000,
  },
  cacheConfig: {
    enabled: true,
    ttl: 7200, // 2 hours
  },
  rateLimitConfig: {
    maxRequests: 200,
    windowSeconds: 60,
  },
});

Middleware Integration

Express Middleware

import express from 'express';
import { KraClient } from '@kra-connect/node';

const client = new KraClient({ apiKey: process.env.KRA_API_KEY! });

app.post('/verify-supplier', async (req, res) => {
  try {
    const { pin } = req.body;
    const result = await client.verifyPin(pin);
    res.json(result);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

Fastify Plugin

import Fastify from 'fastify';
import { KraClient } from '@kra-connect/node';

const fastify = Fastify();
const client = new KraClient({ apiKey: process.env.KRA_API_KEY! });

fastify.post('/verify-pin', async (request, reply) => {
  const { pin } = request.body as { pin: string };
  const result = await client.verifyPin(pin);
  return result;
});

Examples

See the examples directory for more usage examples:

Development

# Install dependencies
npm install

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Build the package
npm run build

# Run linter
npm run lint

# Format code
npm run format

# Type check
npm run typecheck

Publishing

Publishing to NPM

# Update version in package.json
npm version patch  # or minor, or major

# Update CHANGELOG.md

# Build the package
npm run build

# Publish to NPM
npm publish --access public

# Or publish beta version
npm publish --tag beta

GitHub Release

# Tag the release
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0

# Create GitHub release
gh release create v1.0.0 --title "v1.0.0" --notes "Release notes here"

Contributing

Contributions are welcome! Please:

  1. Fork the repository: BerjisTech/kra-connect-node-sdk
  2. Create a feature branch
  3. Make your changes with tests
  4. Submit a pull request

License

MIT License - see LICENSE for details.

Support

Changelog

See CHANGELOG.md for version history.

Disclaimer

This is an independent project and is not officially affiliated with or endorsed by the Kenya Revenue Authority.