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

@rawdash/connector-greenhouse

v0.29.2

Published

Rawdash connector for Greenhouse — syncs candidates, applications, jobs, and offers from the Greenhouse Harvest API into the six-shape storage model

Readme

@rawdash/connector-greenhouse

npm version license

Sync jobs, candidates, applications, and offers from the Greenhouse Harvest API for hiring-funnel, time-to-hire, and offer-rate analytics.

Cost & frequency. Greenhouse Harvest is rate-limited to 50 requests / 10 seconds per key; on large hiring funnels the full backfill spans many pages, so syncing more often than the recommended interval can starve other integrations on the same key. Recommended sync interval: 1 hour. Minimum sensible interval: 15 minutes.

Install

npm install @rawdash/connector-greenhouse

Authentication

A Harvest API key with read-only access to candidates, applications, jobs, and offers. Greenhouse authenticates via HTTP Basic with the key as the username and an empty password.

  1. Open Greenhouse -> Configure -> Dev Center -> API Credential Management.
  2. Create a new Harvest API key with Get / List permissions for the resources you intend to sync (Candidates, Applications, Jobs, Offers).
  3. Copy the key once on creation - Greenhouse never shows it again.
  4. Store the key as a secret and reference it from config as apiKey: secret("GREENHOUSE_API_KEY").

Configuration

| Field | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | apiKey | secret | Yes | Greenhouse Harvest API key with read-only access. Create one at Configure -> Dev Center -> API Credential Management. | | resources | array | No | Which Greenhouse resources to sync. Omit to sync all resources. The Harvest key only needs Get / List permissions for the resources listed here. |

Resources

  • greenhouse_job (entity) - Open, draft, and closed requisitions with department, office, and timestamps for opened / closed transitions.
    • Endpoint: GET /v1/jobs
    • name: Job title.
    • status: Greenhouse job status (open / closed / draft).
    • requisitionId: External requisition id.
    • departments: Flat list of department names attached to the job.
    • offices: Flat list of office names attached to the job.
    • openedAt: When the job was opened (Unix ms).
    • closedAt: When the job was closed (Unix ms).
    • confidential: Whether the job is confidential.
  • greenhouse_candidate (entity) - Candidate records with name, title, company, and the count of attached applications.
    • Endpoint: GET /v1/candidates
    • firstName: Candidate first name.
    • lastName: Candidate last name.
    • title: Candidate current job title.
    • company: Candidate current company.
    • applicationCount: Number of applications attached to the candidate. Useful for spotting repeat applicants.
    • isPrivate: Whether the candidate is marked private.
    • createdAt: When the candidate was created (Unix ms).
    • lastActivityAt: Last activity timestamp on the candidate (Unix ms).
  • greenhouse_application (entity) - Applications with status (active / hired / rejected), current stage, source, and the linked candidate / job.
    • Endpoint: GET /v1/applications
    • candidateId: Candidate the application belongs to.
    • jobId: Primary job the application is attached to.
    • jobName: Primary job name at sync time.
    • status: Application status (active / hired / rejected).
    • currentStage: Name of the current stage (e.g. "Phone Screen").
    • source: Public source name where the application originated (e.g. "LinkedIn").
    • appliedAt: When the application was submitted.
    • rejectedAt: When the application was rejected (null if not).
    • hiredAt: When the application was hired (derived from last_activity_at when status=hired).
    • lastActivityAt: Last activity timestamp on the application (Unix ms).
  • greenhouse_application_event (event) - Application lifecycle events (applied / hired / rejected) derived from each application timestamps. The scope is cleared and rewritten on every sync (including incremental runs).
    • Endpoint: GET /v1/applications
    • Derived from each application's applied_at / rejected_at / last_activity_at fields, not from a separate API call.
    • applicationId: Application the event belongs to.
    • candidateId: Candidate id, denormalised.
    • jobId: Job id, denormalised.
    • transition: "applied", "hired", or "rejected".
    • source: Application source name at the time of the event.
  • greenhouse_offer (entity) - Offers with status (pending / accepted / rejected), linked to their application, candidate, and job.
    • Endpoint: GET /v1/offers
    • applicationId: Linked application.
    • candidateId: Linked candidate.
    • jobId: Linked job.
    • status: Offer status (pending / accepted / rejected).
    • sentAt: When the offer was sent (Unix ms).
    • resolvedAt: When the offer was accepted or rejected (Unix ms; null while pending).
    • startsAt: Proposed start date on the offer (Unix ms).

Example

import {
  defineConfig,
  defineDashboard,
  defineMetric,
  secret,
} from '@rawdash/core';

const greenhouse = {
  name: 'greenhouse',
  connectorId: 'greenhouse',
  config: {
    apiKey: secret('GREENHOUSE_API_KEY'),
  },
};

export default defineConfig({
  connectors: [greenhouse],
  dashboards: {
    hiring: defineDashboard({
      widgets: {
        open_roles: {
          kind: 'stat',
          title: 'Open roles',
          metric: defineMetric({
            connector: greenhouse,
            shape: 'entity',
            entityType: 'greenhouse_job',
            fn: 'count',
            filter: [{ field: 'status', op: 'eq', value: 'open' }],
          }),
        },
        offers_extended: {
          kind: 'stat',
          title: 'Offers extended',
          metric: defineMetric({
            connector: greenhouse,
            shape: 'entity',
            entityType: 'greenhouse_offer',
            fn: 'count',
          }),
        },
      },
    }),
  },
});

Rate limits

Greenhouse Harvest enforces 50 requests per 10 seconds per key and surfaces remaining quota via the X-RateLimit-* headers; the shared HTTP client backs off on 429, preferring the Retry-After header.

Limitations

  • Application stage-transition history is derived from each application's built-in timestamps (applied_at, hired_at, rejected_at, last_activity_at) rather than the per-application /activity_feed endpoint, which avoids an N+1 sync.
  • Greenhouse Onboard data and Recruiting custom fields are out of scope.

Links

License

Apache-2.0