A JavaScript SDK for interacting with the Index Solutions External API. This SDK provides contact monitoring, entity resolution, matter classification, and webhook management capabilities.
- Clone or download this repository
- Install dependencies:
npm install
The fastest way to explore the API is using our interactive CLI demo:
Create a .env
file in the root directory:
# Required credentials (obtain from Index Solutions)
CLIENT_ID=your_client_id_here
CLIENT_SECRET=your_client_secret_here
# Optional configuration
SCOPE=bch.external/contact.read bch.external/contact.write bch.external/organization.read bch.external/organization.write bch.external/matter.read bch.external/matter.write
node src/demo/interactiveCLI.js
The interactive CLI will:
- Show all available API methods
- Provide reasonable defaults for testing
- Let you input custom parameters as JSON or JavaScript objects
- Display formatted responses
- Allow you to repeat the last request easily
Welcome to the ExternalApiClient CLI Tool!
Available API methods:
1. createContact
2. getContact
3. deleteContact
4. createOrganization
5. getOrganization
6. updateOrganization
7. deleteOrganization
8. createMatter
9. getMatter
10. listEvents
11. listWebhooks
12. deleteWebhook
13. testAuthentication
Enter the number of the API method you want to call: 13
Calling method with parameters:
API Response:
{
"message": "Authentication successful"
}
const ExternalApiClient = require('./src/ExternalApiClient');
const client = new ExternalApiClient({
clientId: 'your_client_id',
clientSecret: 'your_client_secret',
scope: 'bch.external/contact.read bch.external/organization.write', // optional
// Optional configuration
maxRetries: 3,
retryDelay: 1000,
timeout: 30000,
tokenEndpoint: 'https://auth.external.index.io/oauth2/token', // optional
apiBase: 'https://external.index.io' // optional
});
Option | Type | Default | Description |
---|---|---|---|
clientId |
string | Required | OAuth client ID from Index Solutions |
clientSecret |
string | Required | OAuth client secret from Index Solutions |
scope |
string | All scopes | Space-separated OAuth scopes |
maxRetries |
number | 3 | Maximum retry attempts for failed requests |
retryDelay |
number | 1000 | Delay between retries (milliseconds) |
timeout |
number | 30000 | Request timeout (milliseconds) |
tokenEndpoint |
string | Default endpoint | Custom OAuth token endpoint |
apiBase |
string | Default API base | Custom API base URL |
bch.external/contact.read
- Read contact informationbch.external/contact.write
- Create and monitor contactsbch.external/organization.read
- Read organization informationbch.external/organization.write
- Create and update organizationsbch.external/matter.read
- Read matter informationbch.external/matter.write
- Create and classify matters
const contact = await client.createContact({
id: 'unique-contact-id',
firstName: 'John',
lastName: 'Doe',
emails: [{ type: 'work', value: '[email protected]' }],
organization: { id: 'org-1', name: 'Acme Corp' },
config: {
action: 'clean' // or 'save'
}
});
const contact = await client.getContact('unique-contact-id');
await client.deleteContact('unique-contact-id');
const organization = await client.createOrganization({
id: 'unique-org-id',
name: 'Acme Corporation',
config: {
action: 'resolve', // or 'save'
dataSource: 'sp' // 'dnb' or 'sp'
}
});
const organization = await client.getOrganization('unique-org-id');
const updated = await client.updateOrganization('unique-org-id', {
name: 'Updated Company Name',
config: { action: 'save' }
});
await client.deleteOrganization('unique-org-id');
const profiles = await client.listOrganizationProfiles('org-id');
// Returns: { dnb: {...}, sp: {...}, web: {...}, etc. }
const dnbProfile = await client.getOrganizationProfileForDataSource('org-id', 'dnb');
const parentProfiles = await client.listParentOrganizationProfiles('org-id', 'global-parent');
const parentDnbProfile = await client.getParentOrganizationProfileForDataSource('org-id', 'global-parent', 'dnb');
Available Data Sources: dnb
, sp
, web
, naics
, sali
, customTaxonomy
, linkedin
const matter = await client.createMatter({
id: 'unique-matter-id',
title: 'Acquisition Agreement Review',
description: 'Review and classification of legal agreement...',
department: 'Mergers & Acquisitions',
players: [
{ id: 'attorney-1', name: 'Jane Smith', type: 'attorney' },
{ id: 'client-1', name: 'Acme Corp', type: 'client' }
],
config: {
action: 'classify',
dataSource: 'sali'
}
});
const matter = await client.getMatter('unique-matter-id');
// Returns matter with SALI classifications array
// Get all events
const allEvents = await client.listEvents();
// Filter by event type
const contactEvents = await client.listEvents('contact-updated');
// Filter by multiple event types
const events = await client.listEvents(['contact-updated', 'organization-updated']);
Event Types: contact-updated
, contact-profile-updated
, organization-updated
, workflow-failed
, matter-updated
// List all webhooks
const webhooks = await client.listWebhooks();
// Delete a webhook
await client.deleteWebhook('webhook-id');
const result = await client.testAuthentication();
// Returns: { message: "Authentication successful" }
The SDK throws ExternalApiError
for API-related errors:
const { ExternalApiError } = require('./src/ExternalApiClient');
try {
const contact = await client.getContact('nonexistent-id');
} catch (error) {
if (error instanceof ExternalApiError) {
console.log('API Error:', error.message);
console.log('Status Code:', error.statusCode);
console.log('Response Body:', error.responseBody);
} else {
console.log('Network or other error:', error.message);
}
}
clean
- Clean and standardize contact datasave
- Save contact for monitoring
resolve
- Resolve organization to database entity (DUNS/S&P)save
- Save organization data
classify
- Classify matter using SALI taxonomysave
- Save matter data
The SDK automatically handles:
- Rate limiting: Respects
429
responses andRetry-After
headers - Retries: Configurable retry logic for transient failures
- Timeouts: Configurable request timeouts with abort signals