This SDK provides a unified interface to interact with Captain Data’s API using a single entry point: the CaptainData class. It simplifies authentication and gives access to the core API and multiple integrations such as LinkedIn and Sales Navigator.

Features

  • Unified CaptainData interface
  • Individual API clients: core, linkedin, salesnavigator, etc.
  • Auto-generated TypeScript types for safety and autocompletion
  • Built using OpenAPI Generator with the typescript-fetch generator and custom templates
  • Supports modern async/await and Fetch API
  • Supports ES6 Language level (es2019 and newer)
  • Supports CommonJS and ES6 module systems
  • Can be used in both TypeScript and JavaScript. In TypeScript, the definition will be automatically resolved via package.json.

Installation

npm install @captaindatatech/sdk --save
# or
yarn add @captaindatatech/sdk
# or for a specific version
npm install @captaindatatech/[email protected] --save

Authentication

Each user has their own unique API Key tied to their account. API Keys are not shared across the workspace. To get your API Key:

  1. Log into the Captain Data Platform
  2. Go to Developer Settings
  3. Copy your API Key

Usage

import { CaptainData } from '@captaindatatech/sdk';

// Initialize the SDK with your API Key
const CAPTAIN_DATA_API_KEY = "your_api_key"; // For production, use environment variables
const cd = new CaptainData({ apiKey: CAPTAIN_DATA_API_KEY });

// Example: Use the Core client
const workspaceResponse = await cd.core.getWorkspaces();
console.log(workspaceResponse.data);

// Example: Use the LinkedIn client
const { data: profile } = await cd.linkedin.extractPeople({ input: { linkedin_profile_url: "https://www.linkedin.com/in/guillaumeodier" } });
console.log(profile);

// Example: Use the Sales Navigator client
// ⚠️ You need a LinkedIn account with an active Sales Navigator subscription
const params = {
  input: {
    sales_navigator_profile_search_url: "https://www.linkedin.com/sales/search/people?query=(...)"
  },
  parameters: {
    exclude_crm_contacts: true,
    exclude_viewed_leads: true
  }
};
const searchResults = await cd.salesnavigator.searchPeople(params);
console.log(searchResults);

Responses

All SDK operations return an enhanced Response wrapper that provides access to the full HTTP response as well as convenience methods to work with its content and metadata.

This design allows you to:

  • Inspect HTTP status, headers, and success flags
  • Parse and access the response body easily
  • Handle paginated endpoints with built-in pagination helpers

The returned object includes:

PropertyDescription
rawThe native fetch Response object, with full access if needed
statusHTTP status code (e.g., 200, 404)
statusTextHTTP status text (e.g., “OK”, “Not Found”)
okBoolean indicating if status is in the range 200–299
headersThe native Response.headers object – use .get() to retrieve
previousPageThe value of the X-Pagination-Previous header, or null if absent
nextPageThe value of the X-Pagination-Next header, or null if absent
dataThe parsed body of the response (lazily evaluated on first access)
// Full response object with metadata and parsed body
const profileRes = await cd.linkedin.extractPeople({
  input: { linkedin_profile_url: "https://www.linkedin.com/in/guillaumeodier" }
});

// Accessing status information
console.log(profileRes.status);       // e.g., 200
console.log(profileRes.statusText);   // e.g., "OK"
console.log(profileRes.ok);           // true if status is 2xx

// Accessing response headers (native fetch Headers object)
console.log(profileRes.headers.get("Content-Type"));

// Using pagination headers
console.log(profileRes.previousPage);
console.log(profileRes.nextPage);

// Accessing parsed response body
console.log(profileRes.data);

// Convenient destructuring when you only need the data
const { data: profile } = await cd.linkedin.extractPeople({
  input: { linkedin_profile_url: "https://www.linkedin.com/in/guillaumeodier" }
});
console.log(profile);

Tip: Use the ok flag to easily gate logic on successful requests:

const res = await cd.linkedin.extractPeople({ input });
if (!res.ok) {
  throw new Error(`Request failed with status ${res.status}`);
}
console.log(res.data);

This gives you fine-grained control over both successful and unsuccessful responses, while keeping your codebase clean and predictable.

Error Handling

API calls can fail, and production-ready code should always handle errors properly. When an error occurs, the SDK throws a ResponseError, which extends the native Error object and adds:

  • response: the raw Fetch Response object
  • body: the decoded API error body (already parsed from JSON)
try {
  const profileRes = await cd.linkedin.extractPeople({ input: { linkedin_profile_url: "https://www.linkedin.com/in/john-doe" } });
  console.log(profileRes.data);
} catch(error) {
  console.error("[ERR] Extract People", error.message, error.response.status);
  console.error(error.body);
}

The API uses a consistent error response format across all endpoints. When an error occurs, you’ll receive a response with the following structure:

{
  "error_label": "INVALID_INPUT",
  "error_scope": "input",
  "error_ref": "ERR-12345",
  "message": "The provided input is invalid. Please check your request and try again.",
  "status_code": 400,
  "params": {}
}

Each error response includes:

  • error_label: A machine-readable identifier for the error type
  • error_scope: Indicates which part of the request caused the error (e.g., “input”, “auth”, “server”)
  • error_ref: A unique reference code for tracking and debugging
  • message: A human-readable description of the error
  • status_code: The HTTP status code
  • params: Additional error parameters (if any)

Common HTTP status codes:

  • 200: The request was successful (some API calls may return 201 instead)
  • 400: Bad Request - Invalid input or parameters
  • 401: Unauthorized - Invalid or missing API key
  • 403: Forbidden - Insufficient permissions
  • 404: Not Found - Resource doesn’t exist
  • 500: Internal Server Error - Server-side issue

Always check the error_label and error_scope fields to programmatically handle different types of errors in your application.

If you encounter an unusual error, such as a 500 or 503, feel free to reach out! These are internal errors on our end, and we’re happy to help resolve them.

SDK Structure

Captain Data API allows you to interact with several 3rd party services called integrations (linkedin, salesnavigator, …). The actions allowed for each integration are exposed under a scoped client for each integration.

const cd = new CaptainData({ apiKey: 'your_api_key_here' });

cd.core            // Core platform endpoints (users, workspaces, etc.)
cd.linkedin        // LinkedIn-specific actions
cd.salesnavigator  // Sales Navigator-specific actions
// More integrations to be added under the same predictable pattern.

Scopes are always lower case alpha identifiers.

The actions correspond to the action names you will find in the API Reference or in the Captain Data SaaS, stripped from the integration identifier prefixes.

FAQ

Q: Can I use this SDK in Node.js and browser environments? A: Yes! It supports both environments as it is based on fetch. For Node.js, make sure to install a polyfill like node-fetch.