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 🙏

© 2026 – Pkg Stats / Ryan Hefner

niche-api-ts

v1.1.1

Published

Official TypeScript SDK for the Niche Partner API

Downloads

13

Readme

@niche-inc/niche-api

Version License TypeScript

Official TypeScript SDK for the Niche Partner API.

Features

  • Fully typed - Complete TypeScript support with automatic type inference
  • Tree-shakeable - Import only what you need
  • Generated from OpenAPI - Always in sync with the API specification
  • Native Fetch - No external HTTP client dependencies

Installation

npm install @niche-inc/niche-api

Note: This package is published to GitHub Packages. Configure authentication in ~/.npmrc:

@niche-inc:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN

Quick Start

import { client, getBusinesses, getBusiness } from '@niche-inc/niche-api';

// Configure client
client.setConfig({
  baseUrl: 'https://app.nicheandleads.com',
  headers: {
    Authorization: 'Bearer your-oauth-token',
  },
});

// Get businesses
const { data, error } = await getBusinesses({
  query: { page: 1, page_size: 10 },
});

if (error) {
  console.error('Error:', error);
} else {
  console.log('Businesses:', data);
}

// Get specific business
const { data: business } = await getBusiness({
  path: { businessId: 'your-business-id' },
});

Usage

Query Parameters

import { getBusinessLeads } from '@niche-inc/niche-api';

const { data: leads } = await getBusinessLeads({
  path: { businessId: 'your-business-id' },
  query: {
    page: 1,
    page_size: 20,
    sources: ['YELP', 'GOOGLE_LSA'], // Type-safe enums
  },
});

Path Parameters

import { getBusiness } from '@niche-inc/niche-api';

const { data: business } = await getBusiness({
  path: { businessId: 'your-business-id' },
});

Request Body

import { createBusiness } from '@niche-inc/niche-api';

const { data: newBusiness } = await createBusiness({
  body: {
    name: 'My Business',
    timezone: 'America/New_York',
  },
});

Error Handling

const result = await getBusiness({ path: { businessId: 'non-existent-id' } });

if (result.error) {
  const error = result.error as { error: string; message: string };
  console.error(`Error (${result.response.status}):`, error.message);
} else {
  console.log('Business:', result.data);
}

Response Format

All SDK functions return:

{
  data: T | undefined,    // Success response data
  error: unknown,          // Error response (if any)
  response: Response       // Raw Fetch Response object
}

Type Exports

import type {
  Business,
  GetBusinessesResponse,
  ErrorResponse
} from '@niche-inc/niche-api';

function processBusinesses(response: GetBusinessesResponse) {
  console.log(`Found ${response.total} businesses`);
}

Authentication

Get an OAuth token:

curl -X POST https://app.nicheandleads.com/api/partner/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "your-client-id",
    "client_secret": "your-client-secret"
  }'

Then configure the client:

client.setConfig({
  baseUrl: 'https://app.nicheandleads.com',
  headers: {
    Authorization: 'Bearer your-access-token',
  },
});

Webhooks

The main Niche app sends webhooks to marketplace apps when events occur (e.g., when a new lead is created). Your marketplace app must verify these webhooks to ensure they're authentic.

Receiving Webhooks

import { verifyWebhookSignature, getRawBody } from '@niche-inc/niche-api';

// Example: Next.js API route or similar
export async function POST(request: Request) {
  // Extract headers
  const signature = request.headers.get('x-niche-signature');
  const timestamp = request.headers.get('x-niche-timestamp');
  const eventId = request.headers.get('x-niche-event-id');
  const deliveryId = request.headers.get('x-niche-delivery-id');

  if (!signature || !timestamp) {
    return new Response('Missing required headers', { status: 400 });
  }

  // Get raw body (must be raw, not parsed JSON)
  const rawBody = await getRawBody(request);

  // Verify signature using your webhook secret
  const isValid = verifyWebhookSignature(
    webhookSecret,  // Your webhook secret (from app configuration)
    timestamp,      // From x-niche-timestamp header
    rawBody,        // Raw request body
    signature       // From x-niche-signature header
  );

  if (!isValid) {
    return new Response('Invalid signature', { status: 401 });
  }

  // Parse and process webhook
  const event = await request.json();
  console.log('Event:', event.type, event.id);

  // Process event based on type
  switch (event.type) {
    case 'lead.created':
      // Handle new lead
      break;
    case 'app.installed':
      // Handle app installation
      break;
  }

  // Use x-niche-event-id for idempotency (deduplicate events)
  // Use x-niche-delivery-id to track specific delivery attempts

  return new Response('OK', { status: 200 });
}

Webhook Format

HTTP Request:

  • Method: POST
  • Headers:
    • content-type: application/json
    • x-niche-signature: HMAC-SHA256 hex digest
    • x-niche-timestamp: ISO timestamp
    • x-niche-event-id: Event ID for idempotency
    • x-niche-delivery-id: Delivery ID for tracking attempts
  • Body: JSON event payload

Event Payload Structure:

{
  "id": "<eventId>",
  "type": "lead.created" | "app.installed" | ...,
  "createdAt": "2024-01-01T00:00:00.000Z",
  "data": {
    // Event-specific payload
  }
}

Signature Verification:

  • Algorithm: HMAC-SHA256(timestamp + "." + payload)
  • Format: Hex digest (no prefix)
  • Secret: Your webhook secret from app configuration

Response Codes:

  • 2xx: Success (webhook processed)
  • 4xx: Client error (webhook marked as failed, won't retry)
  • 5xx: Server error (webhook will retry up to 4 times with exponential backoff)
  • Timeout: 10 seconds

Idempotency:

Always use x-niche-event-id to dedupe events. The same event may be delivered multiple times due to retries, but the event ID will remain the same.

Support

License

MIT © Niche, Inc.