跳到导航

Webhooks

以 Markdown 格式查看

Fern 支持两种在 OpenAPI 规范中定义 webhooks 的方法:

  1. 使用 OpenAPI 3.1 的原生 webhook 支持(推荐)
  2. 使用 Fern 的 x-fern-webhook 扩展

OpenAPI 3.1 webhooks

对于 OpenAPI 3.1 规范,使用 webhooks 顶级字段来定义您的 webhook 操作。每个 webhook 都需要一个 operationId 才能被 Fern 正确处理。

openapi.yml
webhooks:
newPlant:
post:
operationId: newPlantWebhook # Defines webhook
summary: New Plant Added
description: Information about a new plant that was added to the store
tags:
- Plants # Creates dedicated page
requestBody:
description: The plant data when a new plant is added
content:
application/json:
schema:
description: The Webhook payload for when a new plant is added to the store
properties:
triggerType:
description: The type of event that triggered the request
type: string
example: "new_plant"
payload:
type: object
description: The payload of data sent from the plant store
properties:
plantId:
type: string
description: The unique identifier for the plant
example: "64f1a2b3c5d6e7f8a9b0c1d2"
name:
type: string
description: The name of the plant
example: "Monstera Deliciosa"
price:
type: number
format: float
description: The price of the plant in dollars
example: 29.99
addedAt:
type: string
format: date-time
description: The timestamp when the plant was added
example: "2024-01-15T10:30:00.000Z"
example: # Full payload example for docs
triggerType: "new_plant"
payload:
plantId: "64f1a2b3c5d6e7f8a9b0c1d2"
name: "Monstera Deliciosa"
price: 29.99
addedAt: "2024-01-15T10:30:00.000Z"
responses:
'200':
description: Return a 200 status to indicate that the data was received successfully

Fern webhook 扩展

对于 OpenAPI 3.0,使用 x-fern-webhook: true 扩展来定义 webhooks。Fern 会将 requestBody 视为 webhook 负载。

openapi.yml
paths:
/payment/updated/:
post:
summary: Payment Initiated
operationId: initiatePayment
tags:
- Payments # Creates dedicated page
x-fern-webhook: true # Defines webhooks
requestBody:
content:
application/json:
schema:
type: object
properties:
amount:
type: number
example: 99.99
currency:
$ref: '#/components/schemas/Currency'
required:
- amount
- currency
example: # Full payload example for docs
amount: 99.99
currency: "USD"

定义 webhook 时选择的路径可以是任意的。由于 webhooks 可以发送到任何服务器,Fern 会忽略路径。

生成 webhook 参考

Fern Docs 可以从您的定义中自动生成 webhook 参考文档。在您的 docs.yml 文件中进行设置。

您的 webhook 参考可以是单个文档页面:

docs.yml
navigation:
- api: Webhook Reference # Display name for this page
api-name: webhooks-v1 # Name of webhook definition directory

或者您可以为每个 webhook 事件配置单独的文档页面:

docs.yml
navigation:
- subpackage_plants.newPlantWebhook # subpackage_{tag}.{webhook-event-name}

有关如何在 docs.yml 中配置 webhook 参考的更多信息,请参阅生成 webhook 参考

SDK 签名验证

使用 x-fern-webhook-signature 扩展来配置 webhook 签名验证。配置后,Fern 会生成 SDK 工具,允许用户验证 webhook 签名并确保事件来自您的 API。

配置可以在文档级别(适用于所有 webhook 端点)或每个端点(覆盖文档级别的默认设置)设置。两个级别都接受相同的配置选项。

Fern 支持两种验证方法:HMAC(使用共享密钥的对称密钥验证)和非对称(使用 RSA、ECDSA 或 Ed25519 密钥的公钥验证)。

openapi.yml
x-fern-webhook-signature:
type: hmac
header: x-webhook-signature
algorithm: sha256
encoding: hex
paths:
/webhooks/payment:
post:
x-fern-webhook: true
# Inherits document-level signature config
/webhooks/order:
post:
x-fern-webhook: true
# Inherits document-level signature config

配置选项

These fields apply to both HMAC and asymmetric verification.

type
'hmac' | 'asymmetric'Required

The signature verification method. Use hmac for symmetric key verification with shared secrets, or asymmetric for public key verification.

stringRequired

The HTTP header containing the signature. For example, x-webhook-signature or x-hub-signature-256.

encoding
'base64' | 'hex'Defaults to base64

The encoding format of the signature value in the header.

signature-prefix
string

A prefix to strip from the signature header value before verification. For example, "sha256=" or "rsa=".

timestamp.header
string

HTTP header containing the delivery timestamp. Required when timestamp is configured.

timestamp.format
'unix-seconds' | 'unix-millis' | 'iso8601'Defaults to unix-seconds

Format of the timestamp value in the header.

timestamp.tolerance
integerDefaults to 300

Allowed clock skew in seconds. Requests with timestamps outside this window are rejected.

These fields apply when type is set to hmac.

algorithm
'sha256' | 'sha1' | 'sha384' | 'sha512'Defaults to sha256

The HMAC hash algorithm for signature computation. sha256 is recommended. sha1 is deprecated and should only be used for legacy compatibility.

payload-format.components
list of strings

Ordered list of payload components to concatenate before hashing. When omitted, only the raw request body is signed. Available components:

ComponentDescription
bodyRaw request body
timestampTimestamp value from timestamp header
notification-urlThe webhook/callback URL
message-idProvider-assigned message identifier
payload-format.delimiter
string

String used to join the components. Use "." for timestamp-prefixed payloads or "" for direct concatenation. Required when payload-format.components is set.

body-hash-binding.algorithm
'sha256' | 'sha1' | 'sha384' | 'sha512'Required

Hash algorithm applied to the raw request body. Independent of algorithm, which applies to the signature itself. Set body-hash-binding when the provider transmits a hash of the body alongside a signature computed over the notification URL.

body-hash-binding.encoding
'base64' | 'hex'Defaults to base64

Encoding of the transmitted body hash.

body-hash-binding.location.type
'query-parameter'Required

Where the body hash is transmitted. Query parameters on the notification URL are the only supported location.

body-hash-binding.location.name
stringRequired

Name of the query parameter carrying the body hash.

These fields apply when type is set to asymmetric.

asymmetric-algorithm
'rsa-sha256' | 'rsa-sha384' | 'rsa-sha512' | 'ecdsa-sha256' | 'ecdsa-sha384' | 'ecdsa-sha512' | 'ed25519'Required

The asymmetric signing algorithm. rsa-sha256 and ecdsa-sha256 are widely supported defaults. ed25519 is a modern, efficient option.

payload-format.components
list of strings

Ordered list of payload components to concatenate before signing. When omitted, only the raw request body is signed. Available components:

ComponentDescription
bodyRaw request body
timestampTimestamp value from timestamp header
notification-urlThe webhook/callback URL
message-idProvider-assigned message identifier
Without timestamp in the components list, the timestamp.tolerance check can’t protect against replay attacks because the timestamp is unauthenticated. Include timestamp to ensure replay protection.
payload-format.delimiter
string

String used to join the components. Use "." for timestamp-prefixed payloads or "" for direct concatenation. Required when payload-format.components is set.

jwks-url
string

JSON Web Key Set (JWKS) endpoint URL of the key retrieval service. Required when using JWKS-based key rotation; omit for static key verification.

key-id-header
string

HTTP header containing the key ID used to select the correct key from the JWKS endpoint.