0.0
The project is in a healthy, maintained state
Official Ruby client for the Factorial public API. Provides typed models and methods to access ATS, attendance, contracts and other Factorial HR resources.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 1.0.1, < 3.0
~> 1.0
~> 2.0
 Project Readme

Factorial API SDKs

Official auto-generated SDKs for the Factorial API, available for TypeScript, Python and Ruby.

The SDKs are generated from the OpenAPI spec and wrapped with a handwritten or generated client layer providing clean resource access, auth handling and cursor pagination helpers.

SDKs

TypeScript · @factorialco/api-client

npm install @factorialco/api-client
import { FactorialClient } from "@factorialco/api-client";

const client = new FactorialClient({ apiKey: process.env.FACTORIAL_API_KEY });

const page = await client.employees.employees.list();
for await (const emp of client.employees.employees.paginate({ maxItems: 50 })) {
  console.log(emp.full_name);
}

→ Full docs


Python · factorial-api-client

pip install factorial-api-client
from factorial_api_client import FactorialClient

client = FactorialClient(api_key="YOUR_KEY")

result = client.employees.employee.list()
for emp in client.employees.employee.paginate(max_items=50):
    print(emp.full_name)

→ Full docs


Ruby · factorial_api

gem install factorial_api
require "factorial_api"

api = F::Api.new(api_key: "YOUR_KEY")

# only_active, only_managers (required query params become positional args)
page = api.employees_employee.employees_employees_get(true, false)
F::Api.paginate(max_items: 50) { |p| api.employees_employee.employees_employees_get(true, false, query_params: p) }
 .each { |emp| puts emp.full_name }

→ Full docs


Versioning

The TypeScript and Python SDKs use standard semver (MAJOR.MINOR.PATCH), independent of the Factorial API version date.

SDK version Factorial API version
1.x.y 2026-04-01
2.x.y 2026-07-01
3.x.y 2026-10-01

Factorial releases new API versions quarterly (Jan/Apr/Jul/Oct).

Releases are automated with release-please. Land Conventional Commits on main, then merge the Release PR it opens — that bumps the version, tags the commit, creates the GitHub Release, and publishes to npm / PyPI. You never tag or publish by hand. See RELEASING.md for the full flow.

When opening a PR, two things decide the release:

  • PRs are squash-merged, so the PR title must be a Conventional Commit (feat: → minor, fix: → patch, feat!:/BREAKING CHANGE: → major).
  • Which package bumps is decided by file path: changes under typescript/ bump the npm package, under python/ the PyPI package. For a change spanning both SDKs, use a bare feat:/fix: with no scope so both bump together.

The Ruby SDK follows the same semver + version_map.json model but is not wired into release-please yet: its version is computed by ruby/scripts/generate_sdk.rb for now — see ruby/DEVELOPMENT.md.

The release.ts / release.py scripts remain for regenerating the SDK from a new OpenAPI spec; see the per-SDK READMEs: TypeScript · Python

Regenerating for a new dated API version is a repeatable runbook, captured as the release-sdk agent skill (.agents/skills/release-sdk/) for coding agents to follow.

Development

TypeScript

Generate SDK from latest spec

cd typescript
npm run generate

Fetches the OpenAPI spec from https://api.factorialhr.com/oas/?version=<date> and regenerates all src/generated/*.gen.ts files. Override the URL with:

OPENAPI_SPEC_URL=./local-spec.json npm run generate

Test against the live API

FACTORIAL_API_KEY=your_key npm run test:api
# or with OAuth token:
FACTORIAL_TOKEN=your_token npm run test:api

Release a new version

npm run release                    # patch bump (default)
npm run release -- --bump minor    # minor bump
npm run release -- --bump major    # major bump
npm run release:dry-run            # preview only — no writes, no publish

The release script:

  1. Prompts for the API version date (yyyy-mm-dd).
  2. Fetches the spec from https://api.factorialhr.com/oas/?version=<date>.
  3. Regenerates src/generated/ (stage 1) and src/sdk.ts (stage 2).
  4. Bumps the SDK semver (--bump major|minor|patch, default patch).
  5. Builds the package, then asks whether to publish to npm.

Authentication

All SDKs support:

  • API key — via apiKey: / api_key= (sent as x-api-key header)
  • OAuth2 bearer token — via token: / token= (sent as Authorization: Bearer)

Environment variables

If you don't pass credentials (or a base URL) explicitly, the client reads them from the environment. Explicit arguments always take precedence.

Variable Maps to Sent as
FACTORIAL_API_KEY API key x-api-key header
FACTORIAL_TOKEN OAuth2 token Authorization: Bearer
FACTORIAL_BASE_URL Base URL — (defaults to https://api.factorialhr.com)
// TypeScript — picks up FACTORIAL_API_KEY / FACTORIAL_TOKEN / FACTORIAL_BASE_URL
const client = new FactorialClient();
# Python — same
client = FactorialClient()
# Ruby — same
api = F::Api.new

The TypeScript client reads process.env, so env-var fallback applies in Node-like runtimes; in the browser, pass credentials explicitly.

Error handling

All SDKs fail loudly on non-2xx responses (bad/expired token, wrong base URL, server errors) instead of silently returning empty data:

  • TypeScript throws — wrap calls in try/catch.
  • Python raises factorial_api_client.generated.errors.UnexpectedStatus (with .status_code and .content).
  • Ruby raises F::Api::ApiError (with .code and .response_body).