Skip to content

Webhook subscriptions

Webhooks notify your application when data changes in Uptivo. They reduce the need for frequent polling and usually deliver changes with low latency, but they do not replace an initial import or periodic reconciliation. This guide covers subscription management. See Receiving events for endpoint validation, handler behavior, retries, and security.

For Contact synchronization, include Contact.Created, Contact.Updated, and Contact.Deleted in EventTypes. The Contact events guide explains their payloads and relationship transitions. Existing subscriptions must be updated to receive these event types.

There are two distinct HTTP flows:

  1. your integration calls the Club API to create and manage a webhook subscription;
  2. Uptivo sends validation and business events to the public endpoint in that subscription.

Prepare an endpoint that:

  • is reachable from the public internet;
  • accepts POST requests with a JSON body;
  • implements the synchronous validation handshake;
  • persists or queues events before returning a successful response;
  • can process duplicate and out-of-order events safely.

Use HTTPS for production endpoints. You can create more than one subscription, but one subscription per club is normally enough. When an integration manages multiple clubs, create a separate subscription with each club’s Club API Key. Those subscriptions may all use the same destination URL. Match the event topic against the exact Club mapping stored by your integration, but do not use it as proof that Uptivo sent the request.

Subscription management uses the same two credentials as every other Club API operation. The Club API Key selects the club, so the API only lists and accepts subscription identifiers belonging to that club.

Need API reference Required Club API permission
List subscriptions GET /Webhooks/Subscriptions Read
Create a subscription POST /Webhooks/Subscriptions ReadWrite
Read one subscription GET /Webhooks/Subscriptions/{subscriptionId} Read
Replace its URL and/or event set PUT /Webhooks/Subscriptions/{subscriptionId} ReadWrite
Delete a subscription DELETE /Webhooks/Subscriptions/{subscriptionId} ReadWrite

The club profile’s Club API tab also has a read-only Webhooks section for operational monitoring. It shows each destination, event selection, provisioning state, and aggregate delivery statistics for the last 24 hours, 7 days, and 30 days. It does not create or edit subscriptions. See Manage Club API access for the displayed counters and fallback behavior when statistics are unavailable.

Send the public destination in Url and the exact Uptivo event names to receive in EventTypes:

Terminal window
curl --request POST \
--url https://api-gw.uptivo.fit/club/Webhooks/Subscriptions \
--header "X-Sub-Key: <subscription-key>" \
--header "Authorization: Bearer <club-api-key>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '{
"Url": "https://integration.example.com/webhooks/uptivo",
"EventTypes": [
"Athlete.Created",
"Athlete.Updated",
"Training.Created"
]
}'

Url and EventTypes are required. EventTypes must contain at least one supported value and cannot contain unknown names. Event names are case-sensitive; copy them from the event catalog.

Creating the subscription starts endpoint validation immediately. Your handler must therefore already be deployed and able to return the validation response. A successful request returns 200 OK and the created resource:

{
"Url": "https://integration.example.com/webhooks/uptivo",
"EventTypes": [
"Athlete.Created",
"Athlete.Updated",
"Training.Created"
],
"SubscriptionId": "example-webhook-subscription",
"ProvisioningState": "Succeeded"
}

Store SubscriptionId; it is the opaque identifier used by read, update, and delete operations. Do not construct or interpret it.

ProvisioningState reports the lifecycle of a subscription:

Value Meaning
Creating Creation is still in progress.
Updating A requested change is still in progress.
Deleting Deletion is still in progress.
Succeeded The subscription is active.
AwaitingManualAction Endpoint validation requires the asynchronous validation URL.
Failed Provisioning or endpoint validation failed.
Canceled Provisioning was canceled.

Do not assume that receiving a subscription object means it can already deliver events: only Succeeded is the normal active state. When the state is AwaitingManualAction, complete the asynchronous handshake. For Failed, fix the endpoint and create a new subscription.

The list response is not paginated:

Terminal window
curl --request GET \
--url https://api-gw.uptivo.fit/club/Webhooks/Subscriptions \
--header "X-Sub-Key: <subscription-key>" \
--header "Authorization: Bearer <club-api-key>"

Read the latest state of one subscription with its returned identifier:

Terminal window
curl --request GET \
--url https://api-gw.uptivo.fit/club/Webhooks/Subscriptions/<subscription-id> \
--header "X-Sub-Key: <subscription-key>" \
--header "Authorization: Bearer <club-api-key>"

Both operations return 200 OK. The list returns an array; reading one returns one subscription object. A subscription created with another club’s key is out of scope and is treated as not found.

PUT behaves as a partial update. Supply at least one property:

  • omit Url to keep the current destination;
  • omit EventTypes to keep the current event set;
  • when supplied, EventTypes replaces the complete set and cannot be empty.

This example changes only the events:

Terminal window
curl --request PUT \
--url https://api-gw.uptivo.fit/club/Webhooks/Subscriptions/<subscription-id> \
--header "X-Sub-Key: <subscription-key>" \
--header "Authorization: Bearer <club-api-key>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '{
"EventTypes": [
"Athlete.Created",
"Athlete.Updated",
"Athlete.Deleted",
"Training.Created"
]
}'

The response is 200 OK with the updated subscription. Changing Url can trigger validation of the new endpoint, so deploy its handshake handler first.

Terminal window
curl --request DELETE \
--url https://api-gw.uptivo.fit/club/Webhooks/Subscriptions/<subscription-id> \
--header "X-Sub-Key: <subscription-key>" \
--header "Authorization: Bearer <club-api-key>"

A successful deletion returns 200 OK with no response body. Treat a later Microsoft.EventGrid.SubscriptionDeletedEvent only as a lifecycle notification, not as the response to the Club API request.

In addition to the common authentication and permission responses, subscription operations use these status codes:

Status Meaning
400 Bad Request The URL, event set, or update body is invalid.
404 Not Found The identifier does not exist in the selected club.
409 Conflict The operation conflicts with the current subscription state.
502 Bad Gateway The webhook service returned an unexpected error.
503 Service Unavailable The webhook service is temporarily unavailable, timed out, or throttled the request.

See Errors for common Club API errors and retry guidance.

After creating a subscription, implement and validate the destination before processing production events. The Receiving events guide covers the JSON envelope, a minimal TypeScript handler, endpoint validation, delivery guarantees, retries, and security requirements.