@i-coverservices/client-js-sdk
v1.0.5
Published
JS SDK for API-to-API integration with Customer REST API
Readme
Client JS SDK
TypeScript SDK for API-to-API integration with the iCover Services Customer REST API.
Provides a fully typed client for all endpoints including case management, candidate management, multimedia, service management, and more.
Table of Contents
- Installation
- Quick Start
- Authentication
- Namespace-based Type API
- API Reference
- Health Check
- Case Management — Customers
- Case Management — Drafts
- Case Management — Individual Drafts
- Case Management — Organisation Drafts
- Case Management — Screenings
- Case Management — Products
- Case Management — Additional Fees
- Candidate Management
- Multimedia Management
- Service Management
- Product Management
- Geolocation (Countries)
- Webhook Types
- Purchase Screening (Wrapper)
- Error Handling
- Logging
- Examples
- Development
Installation
npm install @i-coverservices/client-js-sdkRequirements: Node.js >= 18
Quick Start
import { ClientSDK } from '@i-coverservices/client-js-sdk';
const sdk = new ClientSDK({
accountApiUrl: 'https://account-api.example.com',
clientApiUrl: 'https://client-api.example.com',
apiKey: 'your-api-key',
});
// Check connectivity
const health = await sdk.clientApi.healthCheck();
console.log('API alive:', health.alive);Authentication
The SDK handles authentication automatically. Provide your API key during initialization, and the SDK will:
- Authenticate with the account API using the API key.
- Cache the JWT access token.
- Automatically re-authenticate when the token expires or gets a 401 response.
const sdk = new ClientSDK({
accountApiUrl: 'https://account-api.example.com',
clientApiUrl: 'https://client-api.example.com',
apiKey: 'your-api-key',
});No manual token management is required.
Namespace-based Type API
The SDK exposes all request/response types through a clean namespace hierarchy. You never need deep imports:
import type { CaseManagement } from '@i-coverservices/client-js-sdk';
// Access nested types via namespaces
type Req = CaseManagement.Drafts.AddServiceToScreening.AddServiceToScreeningRequest;
type Res = CaseManagement.Drafts.AddServiceToScreening.AddServiceToScreeningResponse;
// Other domain namespaces
import type { CandidateManagement } from '@i-coverservices/client-js-sdk';
import type { MultimediaManagement } from '@i-coverservices/client-js-sdk';
import type { ServiceManagement } from '@i-coverservices/client-js-sdk';
import type { HealthCheck } from '@i-coverservices/client-js-sdk';Available Namespaces
| Namespace | Sub-namespaces |
|------------------------|-------------------------------------------------------------------------------------------|
| CaseManagement | Customers, Drafts, IndividualDrafts, OrganisationDrafts, Products, Screenings |
| CandidateManagement | GetInvitations, ResendInvitation, SendInvitation |
| MultimediaManagement | Customers > UploadFile, ListFiles |
| ServiceManagement | Services > GetProductSources, GetProductRequirements |
| HealthCheck | HealthCheckResponse |
Shared / Base Types
Common types and enums are available as direct imports:
import type {
NamedEntity,
Country,
Screening,
ScreeningDetails,
FieldValue,
MultimediaFieldValue,
BaseValueType,
ApiResponse,
ApiListResponse,
FilterableQuery,
} from '@i-coverservices/client-js-sdk';
import { Platform, ExportStatus, SourceOrigin } from '@i-coverservices/client-js-sdk';API Reference
All methods are available on sdk.clientApi.
Health Check
| Method | Description |
|-----------------|------------------------------|
| healthCheck() | Returns { alive: boolean } |
Case Management -- Customers
| Method | Description |
|-----------------------------------------|--------------------------------------------|
| getCustomerScreenings(params) | List screenings for a customer (paginated) |
| generateCustomerScreeningsXLS(params) | Request XLS export of screenings |
| getScreeningDetails(params) | Get detailed screening information |
| getScreeningServiceStatuses() | List available screening statuses |
| submitDraftScreening(params) | Submit/purchase a draft screening |
| getProducts(params) | List products for a customer (paginated) |
| generateProductsXLS(params) | Request XLS export of products |
| getExport(params) | Get export file or status |
| getNoteTypes() | List available note types |
Case Management -- Drafts
| Method | Description |
|----------------------------------------------------------------|---------------------------------------|
| addServiceToScreening(screeningId, payload) | Add a service to a draft screening |
| updateServiceInScreening(serviceIndex, screeningId, payload) | Update a service in a screening |
| removeServiceFromScreening(serviceIndex, screeningId) | Remove a service from a screening |
| deleteScreeningDraft(screeningId) | Delete an entire draft screening |
| getOrderSummary(screeningId) | Get pricing/order summary for a draft |
Case Management -- Individual Drafts
| Method | Description |
|--------------------------------------------------------|--------------------------------------|
| addIndividualScreeningDraft(payload) | Create an individual screening draft |
| updateIndividualScreeningDraft(screeningId, payload) | Update an individual screening draft |
Case Management -- Organisation Drafts
| Method | Description |
|----------------------------------------------------------|----------------------------------------|
| addOrganisationScreeningDraft(payload) | Create an organisation screening draft |
| updateOrganisationScreeningDraft(screeningId, payload) | Update an organisation screening draft |
Case Management -- Screenings
| Method | Description |
|---------------------------------------------------------------------------|-------------------------------------------|
| getScreeningServicesActivityHistory(screeningId, componentId) | Activity history for a component |
| getScreeningServicesApplicationProcessHistory(screeningId, componentId) | Process history for a component |
| getScreeningServiceInformation(screeningId, componentId) | Provided vs verified info for a component |
| getScreeningServiceAdditionalInformation(screeningId, componentId) | Additional info for a component |
| getScreeningAttachments(screeningId) | List all attachments on a screening |
| getSingleAttachment(screeningId, attachmentId) | Download a single attachment (Blob) |
| addAttachmentToScreening(screeningId, payload) | Attach file(s) to a screening |
| deleteAttachmentFromScreening(screeningId, attachmentId) | Delete an attachment |
| listCustomerNotes(screeningId, componentId) | List customer notes on a component |
| createCustomerNote(screeningId, componentId, payload) | Create a customer note |
| getScreeningReport(screeningId, params?) | Get report as PDF or JSON |
| listScreeningNotifications(screeningId) | List notifications for a screening |
Case Management -- Products
| Method | Description |
|---------------------------------------|------------------------------------|
| getProductDetails(productId) | Get details for a specific product |
| requestProductActivation(productId) | Request product activation |
Case Management -- Additional Fees
| Method | Description |
|-----------------------------------------|---------------------------|
| approveAdditionalFee(additionalFeeId) | Approve an additional fee |
| denyAdditionalFee(additionalFeeId) | Deny an additional fee |
Candidate Management
| Method | Description |
|-----------------------------|------------------------------|
| sendInvitation(payload) | Send a candidate invitation |
| getInvitations(params) | List invitations (paginated) |
| resendInvitation(payload) | Resend an invitation |
Multimedia Management
| Method | Description |
|------------------------------------------------|-------------------------------------|
| uploadFile(customerId, screeningId, payload) | Upload a file (base64) |
| listFiles(customerId, screeningId) | List uploaded files for a screening |
| deleteFile(customerId, screeningId, fileId) | Delete a file |
Service Management
| Method | Description |
|---------------------------------------------|-----------------------------------------------|
| getProductSources(serviceId, params) | Get sources for a product |
| getProductRequirements(serviceId, params) | Get requirements for a product |
| getProductFactsheet(serviceId) | Download a product factsheet (Blob) |
| getRequirementSampleDocument(sampleId) | Download a requirement sample document (Blob) |
Product Management
| Method | Description |
|-------------------------------|----------------------------------|
| getServiceTypes(customerId) | Get service types for a customer |
Geolocation (Countries)
| Method | Description |
|------------------|------------------------------|
| getCountries() | List all available countries |
Webhook Types
The SDK provides fully typed webhook event payloads for all events the API can send. The types use a discriminated union on the action field, so switch(event.action) gives you full type narrowing in TypeScript.
Supported Events
| Action | Event Type | Description |
|----------------------------|---------------------------------|------------------------------------------|
| customerNoteAdded | CustomerNoteAddedEvent | A new customer note was added |
| screeningStateChange | ScreeningStateChangeEvent | Screening state changed (e.g. completed) |
| screeningReportGenerated | ScreeningReportGeneratedEvent | Screening report was generated |
| actionAdded | ActionAddedEvent | A new action was added to a service |
| newETA | NewETAEvent | Screening ETA has changed |
| additionalFeeRequest | AdditionalFeeRequestEvent | An additional fee approval is requested |
| attachmentAdded | AttachmentAddedEvent | An attachment was added to a service |
Usage (NestJS Example)
import type { WebhookEvent } from '@i-coverservices/client-js-sdk';
import { Controller, Post, Body, Headers } from '@nestjs/common';
@Controller('webhooks')
export class WebhookController {
@Post('api')
handleWebhook(
@Body() event: WebhookEvent,
@Headers('x-request-signature') signature: string,
) {
// TypeScript narrows the `data` type automatically
switch (event.action) {
case 'customerNoteAdded':
console.log('Note:', event.data.note.message);
break;
case 'screeningStateChange':
console.log('New state:', event.data.state);
break;
case 'screeningReportGenerated':
console.log('Report for:', event.data.soi.name.firstName);
console.log('Services:', event.data.services.length);
break;
case 'actionAdded':
console.log('Action needed:', event.data.action.actionNeeded);
break;
case 'newETA':
console.log('New ETA:', event.data.eta);
break;
case 'additionalFeeRequest':
console.log('Fee ID:', event.data.action.metadata.additionalFeeId);
break;
case 'attachmentAdded':
console.log('File:', event.data.attachment.filename);
break;
}
}
}Namespace Access
All webhook types are also available via the Webhooks namespace:
import type { Webhooks } from '@i-coverservices/client-js-sdk';
type Event = Webhooks.WebhookEvent;
type NoteEvent = Webhooks.CustomerNoteAddedEvent;Signature Verification
Webhook requests include an X-Request-Signature header for integrity verification. To validate:
import { createHmac } from 'crypto';
function verifyWebhookSignature(
body: object,
signature: string,
saltKey: string,
): boolean {
const decoded = Buffer.from(signature, 'base64').toString('utf8');
const computed = createHmac('sha256', saltKey)
.update(JSON.stringify(body))
.digest('hex');
return decoded === computed;
}Purchase Screening (Wrapper)
The SDK provides a convenience method that handles the full-screening purchase flow in a single call:
- Creates a draft screening (individual or organization)
- Adds services to the screening
- Uploads files and attaches them to services
- Submits/purchases the screening
import { ClientSDK } from '@i-coverservices/client-js-sdk';
import type { PurchaseScreeningRequest } from '@i-coverservices/client-js-sdk';
const sdk = new ClientSDK({ /* ... */ });
const request: PurchaseScreeningRequest = {
customerId: 1,
type: 'individual',
individual: {
clientReferenceId: 'IND-001',
soi: {
name: { firstName: 'Jane', lastName: 'Doe' },
otherNames: [],
dob: '1985-03-20',
addresses: [],
},
},
services: [
{
id: 42,
fields: { firstName: 'Jane', lastName: 'Doe' },
},
],
attachments: [
{
screeningServiceIndex: 0,
typeId: 1,
files: [
{
filename: 'id-card.pdf',
contents: '<base64-encoded-content>',
metadata: { type: 'application/pdf' },
},
],
},
],
};
const result = await sdk.clientApi.purchaseScreening(request);
console.log('Screening ID:', result.screeningId);
console.log('Status:', result.submission.status);Error Handling
API errors are wrapped in the ApiError class:
import { ClientSDK, ApiError } from '@i-coverservices/client-js-sdk';
try {
await sdk.clientApi.getScreeningDetails({ customerId: 1, screeningId: 999 });
} catch (error) {
if (error instanceof ApiError) {
console.error('API Error:', error.message);
console.error('Code:', error.code);
console.error('Resource:', error.resource);
console.error('Method:', error.method);
}
}Logging
Pass a custom logger to the SDK to capture debug output:
import { ClientSDK, SDKLogger } from '@i-coverservices/client-js-sdk';
const logger: SDKLogger = {
debug: (msg, meta) => console.log(`[DEBUG] ${msg}`, meta),
warn: (msg, meta) => console.warn(`[WARN] ${msg}`, meta),
error: (msg, meta) => console.error(`[ERROR] ${msg}`, meta),
};
const sdk = new ClientSDK({
accountApiUrl: 'https://account-api.example.com',
clientApiUrl: 'https://client-api.example.com',
apiKey: 'your-api-key',
logger,
});The default NoopLogger suppresses all output.
Examples
See src/examples/ for runnable examples covering every endpoint:
| File | Topics |
|------------------------------------|---------------------------------------------------|
| 01-authentication.ts | SDK init, custom logger, NoopLogger |
| 02-health-check.ts | API health check |
| 03-case-management-screenings.ts | List screenings, details, XLS export |
| 04-drafts-and-services.ts | Create drafts, add/update services, order summary |
| 05-purchase-screening-wrapper.ts | purchaseScreening() convenience method |
| 06-screening-attachments.ts | Upload files, attach, download, customer notes |
| 07-screening-reports.ts | PDF/JSON reports, activity history |
| 08-candidate-management.ts | Invitations: send, list, resend |
| 09-products-and-services.ts | Products, sources, requirements, factsheets |
| 10-additional-fees.ts | Approve/deny additional fees |
| 11-error-handling.ts | ApiError handling pattern |
Development
Build
npm run build # Builds both CJS and ESM
npm run build:cjs # CommonJS only
npm run build:esm # ES Modules onlyTest
npm test # Run all tests
npm run test:ci # Run tests sequentially (CI)Project Structure
src/
├── index.ts # Main barrel — SDK, types, namespaces
├── sdk.ts # ClientSDK class
├── auth/ # Authentication & token management
├── client/
│ ├── client-api.ts # All API methods + purchaseScreening wrapper
│ ├── types.ts # Shared base types & enums
│ └── types/ # Domain-specific request/response types
│ ├── case-management/
│ │ ├── customers/
│ │ ├── drafts/
│ │ ├── individual-drafts/
│ │ ├── organisation-drafts/
│ │ ├── products/
│ │ └── screenings/
│ ├── candidate-management/
│ ├── multimedia-management/
│ ├── service-management/
│ └── health-check/
├── examples/ # Usage examples
├── helpers/ # Query param helpers
├── http/ # HTTP client, error types
└── logger/ # Logger interface & NoopLogger
tests/
└── client/ # Unit tests (mirrors src structure)