Concepts
Idempotency
Retry HubFit API POST requests safely with an Idempotency-Key header, so a network error never sends a message or adds a client twice.
Send an Idempotency-Key header, any unique string up to 255 characters such as a UUID, on POST requests. Retrying with the same key within 24 hours returns the original response, with Idempotent-Replayed: true, instead of doing the write again.
- A retry while the first request is still running gets
409 idempotency_key_in_use. Wait a moment and retry. - The same key with a different request (another path or body) gets
422 idempotency_key_reused. - A
5xxisn't kept, nor a429from the message limit, so a retry with the same key runs again. - Creating a webhook endpoint replays its response with
secret: null: the API shows a signing secret once.
Make one key per action you mean to take, such as per message, and reuse it on every retry of that action. A new key on a retry is a new action.
POST /v1/clients/{clientId}/messages
curl -X POST https://api.hubfit.com/v1/clients/6ad6af41d3199442d31b2743/messages \
-H "Authorization: Bearer $HUBFIT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"text": "Nice work this week! Your new program is in the app."
}'const response = await fetch("https://api.hubfit.com/v1/clients/6ad6af41d3199442d31b2743/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HUBFIT_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
text: "Nice work this week! Your new program is in the app.",
}),
});
const { data } = await response.json();import os
import uuid
import requests
response = requests.post(
"https://api.hubfit.com/v1/clients/6ad6af41d3199442d31b2743/messages",
headers={"Authorization": f"Bearer {os.environ['HUBFIT_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"text": "Nice work this week! Your new program is in the app.",
},
)
data = response.json()["data"]