1. Use the API, not this site
Discover api_base from the Binding. The compiled default is https://api.events.sylphx.com/v1. Events does not mint Binding.
export SYLPHX_PROJECT_BINDING='<sylphx-project-binding+jwt>'
export SYLPHX_DELEGATION='<short-lived-identity-delegation>'
BINDING="x-sylphx-project-binding: $SYLPHX_PROJECT_BINDING"
AUTH="Authorization: Bearer $SYLPHX_DELEGATION"
BASE_URL="https://api.events.sylphx.com/v1"
Do not post events to https://events.sylphx.com. This host is the product site. Health probes live outside /v1 and are not first success.
2. Admit one immutable event
Every mutation has a caller-owned idempotency key. Same key, same digest: replay. Same key, different digest: conflict.
curl --fail-with-body -X POST "$BASE_URL/events" \
-H "$BINDING" -H "$AUTH" -H 'Content-Type: application/json' \
-H 'Idempotency-Key: example-event-01' \
--data '{
"specversion": "1.0",
"id": "order-123.created",
"source": "https://shop.example.test/orders",
"type": "com.example.order.created",
"subject": "order-123",
"dataContentType": "application/json",
"data": {"orderId": "order-123"}
}'
Keep event.eventId. The response is admission, not delivery.
3. Bind a webhook connector
Secrets are write-only and never return on readback. Endpoints are HTTPS only.
curl --fail-with-body -X POST "$BASE_URL/connectors" \
-H "$BINDING" -H "$AUTH" -H 'Content-Type: application/json' \
-H 'Idempotency-Key: example-connector-01' \
--data '{
"name": "orders-webhook",
"webhook": {
"endpointUrl": "https://hooks.example.test/events",
"signingSecretRef": "secret:orders-webhook-signing"
}
}'
Keep connector.connectorId.
4. Submit a delivery
curl --fail-with-body -X POST "$BASE_URL/deliveries" \
-H "$BINDING" -H "$AUTH" -H 'Content-Type: application/json' \
-H 'Idempotency-Key: example-delivery-01' \
--data '{
"intent": {"webhook": {"connectorId": "<connector-id>", "eventId": "<event-id>"}},
"retryPolicy": {
"maximumAttempts": 3,
"initialBackoffSeconds": 5,
"maximumBackoffSeconds": 300,
"perAttemptTimeoutSeconds": 30,
"expiresAt": "<future-rfc3339>",
"multiplier": 2,
"maximumJitterSeconds": 5
}
}'
delivery.deliveryId is the durable operation identity. HTTP 202 is admission, not provider acceptance.
5. Read attempts and the receipt
First success is exact readback: GET /v1/deliveries/{id}, then attempts and receipts under the same project. A provider acceptance id is evidence from that provider. Transport ambiguity remains immutable evidence. Do not “fix” it with a manual resend of the same delivery.
curl --fail-with-body "$BASE_URL/deliveries/<delivery-id>" -H "$BINDING" -H "$AUTH"
curl --fail-with-body "$BASE_URL/deliveries/<delivery-id>/attempts?limit=20" -H "$BINDING" -H "$AUTH"
curl --fail-with-body "$BASE_URL/deliveries/<delivery-id>/receipts?limit=20" -H "$BINDING" -H "$AUTH"
If a request is unavailable, retry is an Events-owned state-machine decision. A new customer attempt after a terminal result is a new delivery with a new idempotency key.