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:
- your integration calls the Club API to create and manage a webhook subscription;
- Uptivo sends validation and business events to the public endpoint in that subscription.
Before you create a subscription
Section titled “Before you create a subscription”Prepare an endpoint that:
- is reachable from the public internet;
- accepts
POSTrequests 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.
Manage subscriptions
Section titled “Manage subscriptions”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.
Create a subscription
Section titled “Create a subscription”Send the public destination in Url and the exact Uptivo event names to receive
in EventTypes:
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.
Understand ProvisioningState
Section titled “Understand ProvisioningState”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.
List and read subscriptions
Section titled “List and read subscriptions”The list response is not paginated:
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:
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.
Update a subscription
Section titled “Update a subscription”PUT behaves as a partial update. Supply at least one property:
- omit
Urlto keep the current destination; - omit
EventTypesto keep the current event set; - when supplied,
EventTypesreplaces the complete set and cannot be empty.
This example changes only the events:
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.
Delete a subscription
Section titled “Delete a subscription”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.
Management errors
Section titled “Management errors”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.
Continue with the receiver
Section titled “Continue with the receiver”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.