Sensors Data · AsyncAPI Specification
Sensors Data Webhooks
Version
View Spec
View on GitHub
CompanyEnterpriseAnalyticsCustomer Data PlatformProduct AnalyticsData CollectionSDKMarketingAsyncAPIWebhooksEvents
AsyncAPI Specification
generated: '2026-08-13'
method: searched
source: https://manual.sensorsdata.cn/sf/docs/webhook_integration
asyncapi_published: false
asyncapi_reason: >-
Sensors Data operates a real event surface but publishes no AsyncAPI document. This
artifact captures the webhook and streaming catalog from the provider's own integration
documentation instead. Nothing here is generated — every field name is quoted from the
published payload.
webhooks:
direction: provider-to-customer
product: Sensors Focus (神策智能运营)
docs: https://manual.sensorsdata.cn/sf/docs/webhook_integration
management_docs: https://manual.sensorsdata.cn/sf/docs/channels_webhook
transport: HTTP POST, Content-Type application/json;charset=UTF-8
protocols: [http, https]
configured_in: 项目设置 -> 触达方式管理 -> Webhook (Project Settings -> Reach Channel Management)
batching:
enabled: true
shape: >-
The request body is a JSON LIST, not a single object. Sensors Focus micro-batches
multiple triggered users into one request to raise throughput. A receiver that
assumes a single-object body will break on the first real delivery.
latency: >-
Several seconds, by design, because of micro-batching. "Webhook itself makes no
timeliness guarantee"; sub-second use cases are directed to the in-app popup product.
authentication:
mechanism: shared secret signature
parameter: secretTokenForSignatureCheck
detail: >-
A Secret Token is configured on the Sensors Focus server and verified by the
receiver. The first-party Java helper enforces the check whenever a token is
supplied. Optional — a webhook can be run unsigned.
events:
- name: user-triggered reach
trigger: a user satisfies the conditions of an operating plan (运营计划) or canvas (流程画布)
payload_fields:
project_name: Sensors project identifier (English identifier, not display name)
sf_version: Sensors Focus version string
user_profile.user_id: long integer, the Sensors Analytics unique user id
user_profile.first_id: usually the device id
user_profile.second_id: usually the login id
receipt_properties.sf_msg_id: uuid for this message
receipt_properties.sf_plan_id: plan id
receipt_properties.sf_plan_version: strategy version
receipt_properties.sf_plan_strategy_id: experiment group id
receipt_properties.sf_strategy_unit_id: strategy unit id
receipt_properties.sf_plan_type: plan type
receipt_properties.sf_channel_id: channel instance id
receipt_properties.sf_component_id: component id
receipt_properties.sf_channel_category: constant "WEBHOOK"
receipt_properties.sf_enter_plan_time: epoch millis the user entered the plan
receipt_properties.sf_send_time: epoch millis the message was sent
plan_info.cname: plan or canvas display name (optional, configured per channel)
plan_info.type: SIMPLE | RICH | CANVA
plan_info.schedule_type: FIXED_TIME | ROUTINE | TRIGGER
plan_info.finish_time: plan end time, epoch millis
plan_info.component_cname: strategy/component display name
params: operator-configured dynamic and static parameters
send_id: the delivery identifier for this user (phone number, push id, ...)
typing_caveat: >-
Every value in params is coerced to STRING regardless of its configured type —
integers, decimals, dates and percentages all arrive as strings, and a percentage
arrives as its numeric value with no % sign.
naming_caveat: >-
Payload field names are snake_case. The docs explicitly warn callers using
camelCase frameworks to configure deserialization mapping.
expected_response:
- condition: HTTP 200 with no body
meaning: every entry in the batch is treated as delivered successfully
- condition: HTTP 200 with a body
shape: '[{"succeed": true}, {"succeed": false, "fail_reason": "..."}]'
meaning: per-entry result, index-aligned with the request list
- condition: any non-200 status
meaning: the entire batch is treated as failed
dynamic_parameter_callback:
direction: provider-to-customer
method: GET
purpose: >-
Populates operator-facing dropdowns in the plan builder in real time (available
coupons, templates), including multi-level trees and search.
response_shape: '[{"name": str, "value": str|number, "children": [...], "detail": {"subtitle": str, "description": str, "others": [{"label": str, "value": any}]}}]'
guidance: keep option counts under about 500 for usability and speed
receipts:
direction: customer-to-provider
purpose: >-
Close the loop so delivery success/failure appears in the plan's analytics. Optional —
a webhook channel works without receipts, but plan reporting is blind without them.
mechanism: report a normal Sensors Analytics event through any server SDK
event:
name: $PlanMsgArrived
cname: Webhook 送达成功或失败回执
properties:
$sf_msg_status: RECEIPT_SEND_SUCCESS | RECEIPT_SEND_FAILED (must be upper case)
$sf_send_fail_code: string
$sf_fail_reason: string
$sf_enter_plan_time: long
$sf_send_time: long
$sf_channel_id: string
$sf_channel_category: constant "WEBHOOK" (must be upper case)
$sf_plan_type: plan type
$sf_strategy_unit_id: string
$sf_plan_strategy_id: string
$sf_plan_id: string
$sf_plan_version: string
note: >-
The receipt properties are exactly the receipt_properties block handed to the
receiver in the webhook payload — echo it back with a status.
streaming:
- name: real-time data subscription to Kafka
direction: provider-to-customer
transport: kafka
docs: https://docs.sensorsdata.com/sa/docs/subscribe_data_to_kafka
managed_by:
spec: openapi/sensors-data-horizon-data-subscription-v1-openapi.yml
operations:
- CreateDataSubscription
- ListDataSubscriptions
- AddSubscriptionApplication
- AppendSubscriptionApplicationConfig
- GetSubscriptionApplication
- DeleteSubscriptionApplication
- BatchDeleteDataSubscriptions
note: >-
This is the one part of the event surface that IS contract-managed — the subscription
lifecycle is seven real OpenAPI operations in the Horizon spec, even though the data
plane itself is Kafka and therefore outside the OpenAPI.
tooling:
- name: webhook-helper (Java)
repo: https://github.com/sensorsdata/sf-webhook-helper
official: true
docs: https://manual.sensorsdata.cn/sf/docs/webhook_api
provides:
- com.sensorsdata.webhook.processor.SfWebhookProcessor — handle a batch of entries
- com.sensorsdata.webhook.middleman.SfWebhookMiddleManProcessor — async forward to a downstream API
- Bootstrap — embedded Jetty server with localPort, processor selection and secretTokenForSignatureCheck
- name: kafka-consumer-sample
repo: https://github.com/sensorsdata/kafka-consumer-sample
official: true
purpose: reference consumer for the Kafka data subscription