niche-api-ts
v1.1.1
Published
Official TypeScript SDK for the Niche Partner API
Downloads
13
Maintainers
Readme
@niche-inc/niche-api
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-apiNote: 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_TOKENQuick 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/jsonx-niche-signature: HMAC-SHA256 hex digestx-niche-timestamp: ISO timestampx-niche-event-id: Event ID for idempotencyx-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
- Documentation:
- Issues: GitHub Issues
- Email: [email protected]
License
MIT © Niche, Inc.
