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

bullhorn-api-helper

v2.0.0

Published

Authenticate with the Bullhorn REST API

Downloads

36

Readme

Bullhorn API Helper

A Node.js module for server-side authentication with the Bullhorn REST API. This package simplifies obtaining and managing Bullhorn authentication tokens for server-side applications.

Installation

npm install bullhorn-api-helper

Features

  • Server-side authentication with Bullhorn REST API
  • Token management with optional caching and automatic refresh
  • SimpleBullhornAuthClient: lightweight client with 30-minute credential cache and coalesced token fetches
  • BullhornServerSideAuthClient: event-based client with shared axios instance and optional cron-based refresh
  • Support for different Bullhorn clusters (US, EMEA, APAC, etc.)
  • Universal Login support
  • TypeScript support with full type definitions

Usage

Basic token functions

import { getBHToken, getSimpleBHToken, getCluster } from "bullhorn-api-helper";

// Full token with session expiry
const token = await getBHToken(
  "username",
  "password",
  "clientId",
  "clientSecret",
  "emea" // or "us", "apac", etc.
);
console.log("BhRestToken:", token.BhRestToken);
console.log("REST URL:", token.restUrl);
console.log("Session expires:", token.sessionExpires);

// Minimal token (restUrl + BhRestToken only)
const simpleToken = await getSimpleBHToken(
  "username",
  "password",
  "clientId",
  "clientSecret",
  "emea"
);

// Resolve cluster for a username
const cluster = await getCluster("username");

SimpleBullhornAuthClient (recommended for request-scoped usage)

Returns a fresh axios instance per call. Credentials are cached for 30 minutes; concurrent calls share a single in-flight token fetch.

import { SimpleBullhornAuthClient } from "bullhorn-api-helper";

const client = new SimpleBullhornAuthClient(
  "username",
  "password",
  "clientId",
  "clientSecret",
  "emea"
);

// Each call returns a new axios instance (cached credentials if still valid)
const api = await client.getBullhornAPIClient();
const response = await api.get("/entity/Candidate/5");

BullhornServerSideAuthClient (shared axios instance + cron refresh)

Use when you want one shared axios instance and optional automatic token refresh every 30 minutes.

import { BullhornServerSideAuthClient } from "bullhorn-api-helper";

const client = new BullhornServerSideAuthClient(
  "username",
  "password",
  "clientId",
  "clientSecret",
  "emea"
);

// Listen for authentication events
client.eventEmitter.on("login", (data) => {
  console.log("Logged in successfully!", data);
});
client.eventEmitter.on("loginFailed", (error) => {
  console.error("Login failed:", error);
});

// Login (skips if session still valid and not expiring within 6 hours)
await client.login();

// Use the shared axios instance
const response = await client.api.get("/entity/Candidate/5");

// Or use makeRequest
const data = await client.makeRequest({ method: "GET", url: "/entity/Candidate/5" });

// Optional: automatic token refresh every 30 minutes (throws if already started)
await client.startLoginCron();

// Later
client.stopLoginCron();

Universal Login

import { universalLogin } from "bullhorn-api-helper";

const { BhRestToken, restUrl } = await universalLogin("username", "password");

API Reference

Functions

getBHToken(username, password, clientId, clientSecret, cluster?, ttl?)

Full Bullhorn OAuth flow. Returns REST URL, BhRestToken, and session expiry (ISO string).

  • Parameters: username, password, clientId, clientSecret, cluster (default "emea"), ttl (minutes, default 2880)
  • Returns: Promise<{ restUrl, BhRestToken, sessionExpires }>

getSimpleBHToken(username, password, clientId, clientSecret, cluster?, ttl?)

Minimal OAuth flow. Returns REST URL and BhRestToken only (no session expiry check).

  • Parameters: same as getBHToken
  • Returns: Promise<{ restUrl, BhRestToken }>

getCluster(username)

Resolves the Bullhorn cluster for a given username.

  • Parameters: username
  • Returns: Promise<string> (e.g. "emea", "us")

getAuthorizationCode(username, password, clientId, cluster)

Exchanges credentials for an OAuth authorization code. Used internally by the token functions.

getAccessToken(authCode, clientId, clientSecret, cluster)

Exchanges an authorization code for an OAuth access token.

getRestTokenAndUrl(accessToken, cluster, ttl)

Uses an access token to obtain the REST base URL and BhRestToken.

universalLogin(username, password)

Authenticates via Bullhorn Universal Login. Returns { BhRestToken, restUrl }.

Classes

SimpleBullhornAuthClient

Lightweight client that returns a fresh axios instance per call. Caches credentials for 30 minutes and coalesces concurrent token fetches.

  • Constructor: new SimpleBullhornAuthClient(username, password, clientId, clientSecret, cluster?)
  • Methods:
    • getBullhornAPIClient(): Returns a Promise of an axios instance configured with Bullhorn REST URL and BhRestToken. Uses cache if still valid; otherwise fetches a new token (single in-flight fetch for concurrent callers).

BullhornServerSideAuthClient

Manages Bullhorn authentication with a shared axios instance and optional cron-based refresh.

  • Constructor: new BullhornServerSideAuthClient(username, password, clientId, clientSecret, cluster?)
  • Properties:
    • api: Axios instance (configured after login())
    • loggedIn: Boolean
    • restUrl, BhRestToken, sessionExpires: Set after login
    • eventEmitter: Node EventEmitter for "login" and "loginFailed" events
  • Methods:
    • login(): Authenticates and configures api. Skips if session still valid and not expiring within 6 hours.
    • ping(): Pings the REST API and returns the session expiry from the server.
    • startLoginCron(): Starts a cron that refreshes the token every 30 minutes. Calls login() immediately. Throws if cron already started.
    • stopLoginCron(): Stops the refresh cron.
    • makeRequest(config): Sends a request using the authenticated axios instance. Throws if not logged in.

Interfaces

LoginInfo

Bullhorn login info from the REST loginInfo endpoint (URLs and data center identifiers). Used by getCluster and related flows.

TypeScript

This package includes TypeScript definitions for all exported functions, classes, and interfaces.

License

MIT