Authentication

Read the official documentation for more information about authentication: https://apidoc.factorialhr.com/docs/authentication

Authentication methods

The Factorial API client supports four authentication methods, each suited for different use cases:

factorialhr.ApiKeyAuth

Simple API key authentication using the x-api-key header. Best for server-to-server integrations and automated scripts.

Advantages:

  • Simple to use - just provide your API key

  • No token expiration to manage

  • Suitable for long-running processes and background jobs

Disadvantages:

  • Less secure than OAuth tokens (keys don’t expire automatically)

  • Requires manual key rotation for security

  • Not suitable for user-facing applications

When to use: Server-side integrations, CI/CD pipelines, scheduled scripts, or when you need a persistent authentication method without token management.

factorialhr.AccessTokenAuth

OAuth access token authentication. The token is used as-is without automatic refresh.

Advantages:

  • Simple OAuth integration

  • Full control over token lifecycle

  • Suitable for short-lived scripts or when you handle token refresh externally

Disadvantages:

  • Access tokens expire after 1 hour - you must manually refresh them

  • Requires implementing your own token refresh logic

  • Not ideal for long-running applications

When to use: Short-lived scripts, one-off operations, or when you’re managing token refresh through another system (e.g., a token management service).

factorialhr.RefreshTokenAuth

OAuth authentication with automatic access token refresh. Automatically refreshes expired access tokens using the refresh token.

Advantages:

  • Access tokens are refreshed seamlessly when expired (after 1 hour)

  • Automatic token refresh - no manual intervention needed

  • Refresh tokens last 1 week, providing longer-term access

  • Ideal for applications that run continuously

Disadvantages:

  • Requires storing refresh token, client ID, and client secret securely

  • More complex initialization (needs multiple parameters)

  • Refresh tokens expire after 1 week - you’ll need to re-authenticate

When to use: Long-running applications, services, or daemons that need continuous API access without manual token management.

factorialhr.RefreshTokenAuthFile

Extends factorialhr.RefreshTokenAuth with automatic persistence to a JSON file. Automatically saves refreshed tokens to disk and can load session data from a file.

Advantages:

  • All advantages of factorialhr.RefreshTokenAuth

  • Automatic session persistence - tokens are saved to disk after refresh

  • Can resume sessions after application restart using from_file()

  • Convenient for applications that need to survive restarts

Disadvantages:

  • Requires file system access and proper file permissions

  • Security consideration: tokens stored in plain JSON file (ensure proper file permissions)

  • File-based approach may not scale for multi-instance deployments

When to use: Desktop applications, local scripts, or single-instance services that benefit from session persistence across restarts.

Choosing the right authentication method:

  • API Key → Server integrations, automation, CI/CD

  • Access Token → Short scripts, external token management

  • Refresh Token → Long-running services, automated token refresh needed

  • Refresh Token File → Applications needing session persistence, single-instance deployments

class factorialhr.AccessTokenAuth(access_token: str, token_type: str = 'Bearer')[source]

Authorization using an access token. Not refreshing the session.

auth_flow(request: Request)[source]

Implement the authentication flow.

Parameters:

request (httpx.Request) – The HTTP request to authenticate.

Yield:

The authenticated request.

Return type:

httpx.Request

class factorialhr.ApiKeyAuth(api_key: str)[source]

Authorization using an api key.

auth_flow(request: Request)[source]

Implement the authentication flow.

Parameters:

request (httpx.Request) – The HTTP request to authenticate.

Yield:

The authenticated request.

Return type:

httpx.Request

class factorialhr.RefreshTokenAuth(refresh_token: str, client_id: str, client_secret: str, access_token: str, token_type: str, created_at: datetime)[source]

Authorization using a refresh token which refreshes the access key automatically.

property access_token_expiration: datetime

Get the expiration date of the access token.

Returns:

The expiration datetime of the access token.

Return type:

datetime.datetime

async async_auth_flow(request: Request) AsyncGenerator[Request, Response][source]

Implement the authentication flow.

Parameters:

request (httpx.Request) – The HTTP request to authenticate.

Yield:

The authenticated request.

Return type:

httpx.Request

is_access_token_expired() bool[source]

Determine whether the access token is expired or not.

Returns:

True if the access token is expired, False otherwise.

Return type:

bool

is_refresh_token_expired() bool[source]

Determine whether the refresh token is expired or not.

Returns:

True if the refresh token is expired, False otherwise.

Return type:

bool

async refresh_access_token(target_url: str)[source]

Refresh the access token.

Parameters:

target_url (str) – The base URL of the API (e.g. ‘https://api.factorialhr.com’).

Raises:
  • RuntimeError – When the refresh token is expired.

  • httpx.HTTPStatusError – When the token refresh request fails.

property refresh_token_expiration: datetime

Get the expiration date of the refresh token.

Returns:

The expiration datetime of the refresh token.

Return type:

datetime.datetime

class factorialhr.RefreshTokenAuthFile(file: str | PathLike[str], *args, **kwargs)[source]

Authorization using a refresh token and saves the refreshed session data in a specific json file.

classmethod from_file(file: Path) tuple[Self, str][source]

Load session data from a file.

Parameters:

file (pathlib.Path) – Path to the JSON file containing session data.

Returns:

A tuple of (RefreshTokenAuthFile instance, target_url).

Return type:

tuple[Self, str]

Raises:
  • json.JSONDecodeError – When the file contains invalid JSON.

  • KeyError – When required keys are missing from the file.

  • ValueError – When datetime parsing fails.

async refresh_access_token(target_url: str)[source]

Refresh the access token and save to file.

Parameters:

target_url (str) – The base URL of the API (e.g. ‘https://api.factorialhr.com’).

Raises:
  • RuntimeError – When the refresh token is expired.

  • httpx.HTTPStatusError – When the token refresh request fails.

to_file(target_url: str) None[source]

Save the current session data to the file.

Parameters:

target_url (str) – The base URL of the API (e.g. ‘https://api.factorialhr.com’).

Response models

class factorialhr.ListApiResponse(*, raw_data: Sequence[Mapping[str, Any]], model_type: type[T])[source]

Api response that returned a list of objects.

model_type: type[T]

Model type to validate the raw data against

raw_data: Sequence[Mapping[str, Any]]

Raw data sequence from the API response

class factorialhr.MetaApiResponse(*, raw_data: Sequence[Mapping[str, Any]], model_type: type[T], raw_meta: Mapping[str, Any])[source]

Response model that includes both data and meta.

raw_meta: Mapping[str, Any]

Raw pagination metadata from the API response

class factorialhr.PaginationMeta(*, limit: int | None, total: int, has_next_page: bool, has_previous_page: bool, start_cursor: str | None = None, end_cursor: str | None = None)[source]

Model for pagination metadata.

end_cursor: str | None

End cursor for cursor-based pagination

has_next_page: bool

Whether there is a next page

has_previous_page: bool

Whether there is a previous page

limit: int | None

Limit of items per page (can be None sometimes, e.g. when specifying employee_ids[] in shift request)

start_cursor: str | None

Start cursor for cursor-based pagination

total: int

Total number of items

Api client

class factorialhr.ApiClient(base_url: str = 'https://api.factorialhr.com', *, auth: Auth, **kwargs)[source]

Factorial api class.

property api_version: str

Get the API version.

Returns:

The API version string.

Return type:

str

async close()[source]

Close the client session.

Raises:

httpx.HTTPError – When closing the session fails.

async delete(*path: str | int | None, **kwargs) Any[source]

Perform a DELETE request.

Parameters:
  • path (str | int | None) – Path segments to append to the base URL.

  • kwargs (optional) – Optional keyword arguments (e.g. params for query string) forwarded to the HTTP request.

Returns:

The JSON response data.

Return type:

Any

Raises:

httpx.HTTPStatusError – When the API returns an error status code.

async get(*path: str | int | None, **kwargs) dict[str, Any][source]

Perform a GET request.

Parameters:
  • path (str | int | None) – Path segments to append to the base URL.

  • kwargs (optional) – Optional keyword arguments (e.g. params for query string) forwarded to the HTTP request.

Returns:

The JSON response data.

Return type:

dict[str, Any]

Raises:

httpx.HTTPStatusError – When the API returns an error status code.

async get_all(*path: str | int | None, **kwargs) Sequence[Mapping[str, Any]][source]

Get all data from an endpoint via offset pagination.

Depending on the amount of objects to query, you might want to increase the timeout by using timeout=httpx.Timeout(…). More information at https://apidoc.factorialhr.com/docs/how-does-it-work#offset-pagination.

Parameters:
  • path (str | int | None) – Path segments to append to the base URL.

  • kwargs (optional) – Optional keyword arguments (e.g. params for query string) forwarded to the HTTP request.

Returns:

A sequence of all records from all pages.

Return type:

Sequence[Mapping[str, Any]]

Raises:
  • httpx.HTTPStatusError – When the API returns an error status code.

  • TypeError – When the response data is not a list.

async post(*path: str | int | None, **kwargs) Any[source]

Perform a POST request.

Parameters:
  • path (str | int | None) – Path segments to append to the base URL.

  • kwargs (optional) – Optional keyword arguments (e.g. json, data, params for query string) forwarded to the HTTP request.

Returns:

The JSON response data.

Return type:

Any

Raises:

httpx.HTTPStatusError – When the API returns an error status code.

async put(*path: str | int | None, **kwargs) Any[source]

Perform a PUT request.

Parameters:
  • path (str | int | None) – Path segments to append to the base URL.

  • kwargs (optional) – Optional keyword arguments (e.g. json, data, params for query string) forwarded to the HTTP request.

Returns:

The JSON response data.

Return type:

Any

Raises:

httpx.HTTPStatusError – When the API returns an error status code.