mcpField
F
factorial-api-sdks

factorial-api-sdks

github.com/factorialco开发7357 次安装4 天前更新
代码仓库

关于 factorial-api-sdks

用于在 TypeScript、Python 和 Ruby 中使用 Factorial 官方 API SDK,并处理 Factorial Webhook 的 Skill。内容涵盖命名空间客户端、身份验证、分页、错误及类型化 Webhook 负载。

主要功能

  1. 01支持三种语言的官方 SDK
  2. 02API 密钥与 OAuth 身份验证
  3. 03按命名空间组织的端点客户端
  4. 04分页辅助功能
  5. 05类型化 Webhook 负载

适用场景

  1. 01调用 Factorial API 端点
  2. 02逐页获取大型数据集
  3. 03管理 Webhook 订阅
  4. 04处理并为 Webhook 事件定义类型

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/factorial-api-sdks确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
ruby-methods.json
sdk-methods.md
webhooks.md

详细介绍

Factorial API SDK

官方 SDK 使用带有领域命名空间的客户端、分页辅助工具和简洁的身份验证来封装 Factorial 公共 API。本指南将教 Agent 如何使用这些 SDK,以及如何处理 Factorial Webhook。生成的参考资料位于 reference/(参见参考资料)。

  • TypeScript:@factorialco/api-client(npm)
  • Python:factorial-api-client(PyPI)
  • Ruby:factorial_api(RubyGems)

安装

npm install @factorialco/api-client     # TypeScript
pip install factorial-api-client          # Python
gem install factorial_api                 # Ruby

身份验证

提供一个 API 密钥或 OAuth 令牌(也可以两者都提供):

选项发送的标头
apiKeyx-api-key: <value>
tokenAuthorization: Bearer <value>

Factorial API 密钥采用 JWT 格式,但通过 x-api-key 发送,而不是作为 Bearer 令牌发送。

可以显式传入凭据,也可以从环境变量中读取(FACTORIAL_API_KEY、FACTORIAL_TOKEN,以及可选的 FACTORIAL_BASE_URL)。

import { FactorialClient } from "@factorialco/api-client";
const client = new FactorialClient({ apiKey: process.env.FACTORIAL_API_KEY });
from factorial_api_client import FactorialClient
client = FactorialClient(api_key="YOUR_KEY")   # or token="...", or from env
require "factorial_api"
api = F::Api.new(api_key: ENV["FACTORIAL_API_KEY"])   # or token:, or from env

调用端点

客户端按 client.<namespace>.<resource>.<method> 组织。命名空间和资源与 REST 路径 /api/<version>/resources/<namespace>/<resource> 对应。

方法命名规则明确:

HTTP / 形态SDK 方法
GET 集合list() / paginate() / all()
按 ID 执行 GETget(id)
POST 集合create(body)
按 ID 执行 PUT/PATCHupdate(id, body)
按 ID 执行 DELETEdelete(id)
自定义操作(如 apply)驼峰式操作名称,例如 apply()
const { data } = await client.employees.employees.list();
const created = await client.apiPublic.webhookSubscriptions.create({ /* body */ });
employees = client.employees.employee.list()
sub = client.api_public.webhook_subscription.create(body={...})

Ruby 使用相同的结构,但采用 snake_case。必需参数(路径、查询或表单参数)均作为具名关键字传入;可选查询参数放入 query_params: 哈希中,请求体则通过 *_request 关键字传入。(底层的原始低级访问器,例如 api.employees_employee.employees_employees_get(true, false),仍可继续使用。)

employees = api.employees.employee.list(only_active: true, only_managers: false).data
team = api.teams.team.create(teams_teams_post_request: { name: "Platform" })

要查找任何端点对应的准确命名空间、资源和方法,请查阅 reference/sdk-methods.md(按组列出每个端点及其 TS 和 Ruby 调用方式),或参阅在线 API 参考。

分页

列表端点返回 { data: T[], meta: { end_cursor?, has_next_page, ... } }。

  • list() — 获取一页原始数据
  • paginate() — 异步迭代器(TS)/ 同步或异步生成器(Python)
  • all()(TS)/ collect_all()(Python)— 获取所有页面并汇总到一个数组/列表中
  • Ruby:所有可列表资源都提供 paginate(惰性 Enumerator,可通过 limit:/max_items: 限制)和 all;F::Api.paginate { |page| ... } 用于封装原始调用
for await (const emp of client.employees.employees.paginate()) { /* ... */ }
const everyone = await client.employees.employees.all({ maxItems: 500 });
for emp in client.employees.employee.paginate(max_items=50): ...
everyone = client.employees.employee.all()
高容量检索

页面最多返回 100 项——这是服务端的硬性上限,并非默认值 (参见分页文档)。 传入更大的 limit 不会产生任何效果。游标分页按顺序进行(第 N+1 页需要第 N 页的 end_cursor),因此对大型数据集调用 all()(例如整整一个公司月的 attendance/worked_times)意味着需要顺序发送数十个请求。为合理控制请求数量和延迟:

  • 先筛选。 使用端点的查询参数(日期范围、ids、 employee_ids 等),而不是获取所有数据后再在本地筛选。
  • 增量同步。 如果端点支持 updated_at 一类的筛选条件,只获取自上次运行后发生变更的数据并在本地缓存—— 不要为每份报告重新获取整个数据集。
  • 拆分大型请求。 将一个大型查询拆分为多个带筛选条件的子查询(按 日期范围或 ID 分块),并发运行——每个子查询仍需顺序分页,但总耗时会缩短。请求总数 不变,因此请留意速率限制。
  • 设置防御性上限。 传入 max_items / maxItems,避免因错误或意外的数据量导致无限制抓取。

服务端没有聚合端点;总计值(例如每位员工在某个时段内的工时) 必须根据原始记录在客户端计算。

错误

所有 SDK 在收到非 2xx 响应(令牌错误或过期、基础 URL 错误、 服务器错误)时都会明确报错,而不会静默地返回空数据。每个 SDK 都会抛出包含状态码和响应正文的类型化 错误:

SDK类状态正文
TypeScriptFactorialApiError(扩展 Error)statusbody(已解析),以及 method、url
PythonUnexpectedStatusstatus_codecontent(字节)
RubyF::Api::ApiErrorcoderesponse_body
// TypeScript — results have no `error` field; failures throw.
import { FactorialApiError } from "@factorialco/api-client";
try {
  const { data } = await client.employees.employees.get({ path: { id: "42" } });
} catch (err) {
  if (err instanceof FactorialApiError) console.error(err.status, err.url, err.body);
  else throw err; // transport failure (DNS/connection), not an HTTP response
}
# Python
from factorial_api_client.generated.errors import UnexpectedStatus
try:
    employees = client.employees.employees.list()
except UnexpectedStatus as e:
    print(e.status_code, e.content)
# Ruby
begin
  api.employees.employee.list
rescue F::Api::ApiError => e
  puts e.code, e.response_body
end

API 版本管理

SDK 针对特定的 Factorial API 日期版本(例如 2026-04-01),并由 SDK 的主版本固定。 较新的 API 版本会随新的 SDK 主版本一同发布。

Webhook

Webhook 是 Factorial 在事件发生时发送到你的 target_url 的 HTTP POST 请求。

传递方式

  • 为某个 subscription_type(例如 ats/application/create)创建Webhook 订阅,指定 target_url 和你的 company_id。
  • 事件触发时,Factorial 会向 target_url 发送 POST。顶层负载就是资源对象—— 不会封装在 { type, data } 信封中。如果需要轻松区分事件,请为每种事件使用不同的 URL。
  • 如果订阅时设置了 challenge,Factorial 会通过 x-factorial-wh-challenge 请求标头原样返回该值,以便你验证来源。
  • 可选的作者标头 x-factorial-author-id / x-factorial-author-type (employee 或 company)会标识触发事件的人,前提是安全可公开此信息。
  • 重试策略:48 小时内最多重试 20 次;之后会禁用订阅并向你发送邮件。使用 PUT { enabled: true } 重新启用。

通过 SDK 管理订阅

await client.apiPublic.webhookSubscriptions.create({
  subscription_type: "ats/application/create",
  target_url: "https://example.com/webhooks/factorial",
  challenge: "a-secret-you-choose",
  company_id: 55,
});
client.api_public.webhook_subscription.create(body={
    "subscription_type": "ats/application/create",
    "target_url": "https://example.com/webhooks/factorial",
    "challenge": "a-secret-you-choose",
    "company_id": 55,
})

为处理程序负载添加类型,使用导出的 webhook 类型:

import type { AtsApplicationCreateWebhook, WebhookPayloadMap, WebhookSubscriptionType }
  from "@factorialco/api-client";

// Direct alias
function onApplicationCreated(payload: AtsApplicationCreateWebhook) { /* ... */ }

// Typed dispatch keyed on the runtime subscription_type
function handle<T extends WebhookSubscriptionType>(type: T, payload: WebhookPayloadMap[T]) { /* ... */ }
from factorial_api_client import AtsApplicationCreateWebhook, WEBHOOK_PAYLOAD_TYPES

def on_application_created(payload: AtsApplicationCreateWebhook) -> None: ...

# Runtime lookup of the model class for a subscription_type
model_cls = WEBHOOK_PAYLOAD_TYPES["ats/application/create"]

完整的事件列表、对应的 subscription_type 和负载字段见 reference/webhooks.md。

参考资料

生成的、特定于 SDK 的查阅表(请参阅以了解确切名称和结构):

  • reference/webhooks.md — 所有 Webhook 事件、对应的 subscription_type 和负载字段。
  • reference/sdk-methods.md — 按命名空间/资源分组的所有 REST 端点,以及对应的 SDK 调用。

有关文字说明指南(OAuth 流程、API 密钥、版本管理、Webhook 策略等),请参阅 在线文档——内容始终为最新版本,此处不包含副本:

评论

支持 Markdown