Skip to main content

factorial-api-client (Python)

Official Python SDK for the Factorial API.

Versioning

The SDK uses 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

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

See the Factorial API versioning docs for details.

Installation

pip install factorial-api-client

Quick start

from factorial_api_client import FactorialClient

client = FactorialClient(api_key="YOUR_KEY")

# First page only
result = client.employees.employee.list()
employees = result.data

# Cursor-paginated iterator (sync)
for emp in client.employees.employee.paginate(max_items=100):
    print(emp.full_name)

# Collect all pages into a list
all_employees = client.employees.employee.all()

# Async iterator
import asyncio

async def main():
    async for emp in await client.employees.employee.paginate_async(max_items=100):
        print(emp.full_name)

asyncio.run(main())

Authentication

Pass your API key via api_key= or an OAuth2 bearer token via token=:

# API key (sent as x-api-key header)
client = FactorialClient(api_key="YOUR_KEY")

# OAuth2 bearer token
client = FactorialClient(token="YOUR_BEARER_TOKEN")

Environment variables

When an argument is omitted, the client falls back to environment variables. Explicit arguments always take precedence.

Variable Maps to Sent as
FACTORIAL_API_KEY api_key x-api-key header
FACTORIAL_TOKEN token Authorization: Bearer
FACTORIAL_BASE_URL base_url — (defaults to https://api.factorialhr.com)
# No arguments needed — reads FACTORIAL_API_KEY / FACTORIAL_TOKEN / FACTORIAL_BASE_URL
client = FactorialClient()

Error handling

The client fails loudly on non-2xx responses (bad/expired token, wrong base URL, 4xx/5xx) instead of silently returning None. These raise UnexpectedStatus:

from factorial_api_client.generated.errors import UnexpectedStatus

try:
    employees = client.employees.employee.list()
except UnexpectedStatus as e:
    print(e.status_code)  # e.g. 401
    print(e.content)      # raw response body (bytes)

Domain namespaces

The client is organised as client.{domain}.{resource}.{method}().

Domain Example
employees client.employees.employee.list()
ats client.ats.application.list()
attendance client.attendance.shift.list()
timeoff client.timeoff.leave.list()
contracts client.contracts.contract_version.list()
payroll client.payroll.supplement.list()
documents client.documents.document.list()
performance client.performance.review_process.list()
... 36 domains total

Available methods per resource: list, get, create, update, delete, paginate, paginate_async, all, plus any custom action endpoints.

Pagination

All list endpoints support cursor-based pagination via paginate() / paginate_async() / all():

# Stop after 50 items
for emp in client.employees.employee.paginate(max_items=50):
    ...

# Collect everything (use carefully on large datasets)
all_leaves = client.timeoff.leave.all()

High-volume retrieval

Pages are capped at 100 items — a server-side hard max (pagination docs); a larger limit has no effect. Cursor pagination is sequential, so all() on a large dataset issues one request per 100 records. For big pulls:

  • Filter with the endpoint's query params (date ranges, ids, employee_ids, …) instead of pulling everything.
  • Sync incrementally where updated_at-style filters exist, and cache locally.
  • Split one large query into filtered sub-queries (date windows, id chunks) and run them concurrently with paginate_async() — faster wall-clock, same total request count, so mind rate limits.
  • Pass max_items as a safety cap.

There is no server-side aggregation endpoint; compute totals client-side.

Webhooks

Manage subscriptions through the client, and type your handler payloads with the generated webhook catalog (re-exported from the package root).

from factorial_api_client import (
    FactorialClient,
    AtsApplicationCreateWebhook,
    WEBHOOK_CATALOG,
    WEBHOOK_PAYLOAD_TYPES,
)

client = FactorialClient(api_key="YOUR_KEY")

# Subscribe to an event. The `challenge` is a secret you choose; Factorial echoes
# it back in the `x-factorial-wh-challenge` header on every delivery so you can
# verify the request really came from Factorial.
client.api_public.webhook_subscription.create(body={
    "subscription_type": "ats/application/create",
    "target_url": "https://example.com/webhooks/factorial",
    "company_id": 55,
    "challenge": "a-random-secret-you-generate",
})

# Type a handler directly
def on_application_created(payload: AtsApplicationCreateWebhook) -> None:
    print(payload.id)

# Look up the payload model class for a subscription_type at runtime
model_cls = WEBHOOK_PAYLOAD_TYPES["ats/application/create"]
print(len(WEBHOOK_CATALOG), "webhook events available")

Factorial delivers the resource object at the top level of the POST body (no {type, data} envelope). A full event→payload reference and an SDK usage guide for coding agents are available as a skill:

npx skills add https://github.com/factorialco/factorial-api-sdks --skill factorial-api-sdks

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

factorial_api_client-2.0.3.tar.gz (457.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

factorial_api_client-2.0.3-py3-none-any.whl (1.7 MB view details)

Uploaded Python 3

File details

Details for the file factorial_api_client-2.0.3.tar.gz.

File metadata

  • Download URL: factorial_api_client-2.0.3.tar.gz
  • Upload date:
  • Size: 457.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for factorial_api_client-2.0.3.tar.gz
Algorithm Hash digest
SHA256 4b7fdab5b67a169172ba4bf53239641aa719e3de1afa2b7445b07dca730dafef
MD5 53e26803adb75ca742e08ece9bbceddf
BLAKE2b-256 3357608ae6e1f6c85faf0738c5f7dae30d0befe5606fb1ae510606a5c495f20f

See more details on using hashes here.

File details

Details for the file factorial_api_client-2.0.3-py3-none-any.whl.

File metadata

  • Download URL: factorial_api_client-2.0.3-py3-none-any.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for factorial_api_client-2.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 bee615e219cd29dabf809adf91b73adcd37a6461c87f3fd2d4857b4521db3a49
MD5 08d0c5fe8d1b08eb34ad270fe19d49bc
BLAKE2b-256 a0e0b42eed0b9fbae15baab63d656d9004580d0cfbddd1480287d8f5ec39701e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

2.0.3 This release

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.3.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

1.1.1

2 files

1.1.0

2 files

1.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page