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-expensify

v0.29.2

Published

Rawdash connector for Expensify — expense reports, expenses, and category spend

Readme

@rawdash/connector-expensify

npm version license

Sync Expensify expense reports, individual expenses, and daily category spend for finance-ops dashboards: reports pending, recent spend, and spend by category.

Install

npm install @rawdash/connector-expensify

Authentication

Expensify API partner credentials (partnerUserID + partnerUserSecret). Both are sent in the credentials block of every Integration Server request over HTTPS.

  1. In the Expensify web app, open Settings → Account → API and generate a partnerUserID / partnerUserSecret credential pair.
  2. Set the partnerUserID as the partnerName config field.
  3. Store the partnerUserSecret as a secret and reference it from config as partnerPassword: secret("EXPENSIFY_PARTNER_PASSWORD").

Configuration

| Field | Type | Required | Description | | ----------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | partnerName | string | Yes | The Expensify API partnerUserID. Generate a credential pair in the Expensify web app under Settings → Account → API, and use the partnerUserID here. | | partnerPassword | secret | Yes | The Expensify API partnerUserSecret paired with the partnerUserID. Store it as a secret. | | lookbackDays | number | No | How many calendar days of reports (by submit/created date) to fetch on a full sync. Defaults to 180. | | resources | array | No | Which Expensify resources to sync. Omit to sync all of them. |

Resources

  • expensify_report (entity) - Expense reports with total, currency, workflow status (OPEN, SUBMITTED, APPROVED, REIMBURSED, ...), submitter, and submit/approve timestamps.
    • Endpoint: POST /ExpensifyIntegrations (combinedReportData)
    • reportName: Report title.
    • total (cents): Report total in the smallest currency unit.
    • currency: ISO currency code of the report.
    • status: Workflow status (OPEN, SUBMITTED, APPROVED, REIMBURSED, CLOSED, ...), uppercased.
    • submitterEmail: Email of the report submitter.
    • submittedDate: Submission timestamp, if any.
    • approvedDate: Approval timestamp, if any.
    • policyName: Expense policy the report is under.
    • expenseCount: Number of expenses on the report.
  • expensify_expense (event) - Individual expenses (one event per transaction) timestamped at the expense creation date, carrying merchant, amount, currency, category, and parent report.
    • Endpoint: POST /ExpensifyIntegrations (combinedReportData)
    • Derived from the transactionList of every report in the lookback window and rewritten on every sync, so resyncs are idempotent.
    • expenseId: Expensify transaction id.
    • reportId: Parent report id.
    • merchant: Merchant name.
    • amount (cents): Expense amount in the smallest currency unit.
    • currency: ISO currency code of the expense.
    • category: Expense category, if categorized.
    • created: Expense creation date (YYYY-MM-DD).
    • comment: Free-text comment on the expense.
    • reimbursable: Whether the expense is reimbursable.
  • expensify_category_spend (metric) - Daily expense spend bucketed by category and currency: the summed expense amount per (creation day, category, currency).
    • Endpoint: POST /ExpensifyIntegrations (combinedReportData)
    • Unit: cents
    • Granularity: day
    • Dimensions: date, category, currency
    • Measures: expenseCount
    • Aggregated in the connector from the same combinedReportData export used for reports and expenses. The metric value is the summed amount (smallest currency unit) for the bucket.

Example

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

const expensify = {
  name: 'expensify',
  connectorId: 'expensify',
  config: {
    partnerName: 'your_partnerUserID',
    partnerPassword: secret('EXPENSIFY_PARTNER_PASSWORD'),
    lookbackDays: 180,
  },
};

export default defineConfig({
  connectors: [expensify],
  dashboards: {
    finance: defineDashboard({
      widgets: {
        spend_30d: {
          kind: 'stat',
          title: 'Spend (30d)',
          window: '30d',
          metric: defineMetric({
            connector: expensify,
            shape: 'metric',
            name: 'expensify_category_spend',
            field: 'value',
            fn: 'sum',
          }),
        },
        daily_spend: {
          kind: 'timeseries',
          title: 'Daily spend',
          window: '90d',
          metric: defineMetric({
            connector: expensify,
            shape: 'metric',
            name: 'expensify_category_spend',
            field: 'value',
            fn: 'sum',
          }),
        },
      },
    }),
  },
});

Rate limits

Expensify does not publish a fixed per-credential request rate limit. The connector issues at most two requests per sync (a report-export generate call followed by a download call) and relies on the shared HTTP client to honor 429 responses with backoff.

Limitations

  • Reports and expenses are fetched over a rolling lookback window (lookbackDays) and rewritten on every sync, so reports and expenses older than the window age out of storage. Category-spend metric history outside the window is preserved across incremental syncs.
  • Amounts are reported in the smallest unit of each expense currency (e.g. cents for USD), matching the Expensify Integration Server output.
  • The connector reads report data via the combinedReportData export (reports plus their transaction lists). Line-item receipt images and audit-log detail are out of scope.
  • Category-spend is bucketed per (created day, category, currency); expenses without a category are grouped under "Uncategorized".

Links

License

Apache-2.0