Convex Wearables
Guides

Webhooks and Routes

Mount Garmin, Strava, and SDK ingestion routes with the standard helpers.

Garmin routes

Register Garmin routes directly from the package:

// convex/http.ts
import { httpRouter } from "convex/server";
import { registerRoutes } from "@clipin/convex-wearables";
import { components } from "./_generated/api";

const http = httpRouter();

registerRoutes(http, components.wearables, {
  garmin: {
    clientId: process.env.GARMIN_CLIENT_ID,
    clientSecret: process.env.GARMIN_CLIENT_SECRET,
    oauthCallbackPath: "/oauth/garmin/callback",
    successRedirectUrl: process.env.NEXT_PUBLIC_APP_URL,
    webhookPath: "/webhooks/garmin/push",
    healthPath: "/webhooks/garmin/health",
  },
});

export default http;

The Garmin route helper:

  • handles the Garmin OAuth callback redirect
  • validates the garmin-client-id header
  • forwards push payloads into the component ingestion path
  • exposes an optional health-check route

If you customize oauthCallbackPath, the redirect URI used in your OAuth flow must match it exactly.

Strava webhooks

The package exports standalone HTTP handlers for Strava's webhook API:

EndpointHandlerPurpose
GET /webhooks/stravastravaWebhookVerifySubscription verification
POST /webhooks/stravastravaWebhookEventActivity create/update/delete events

Example:

// convex/http.ts
import { httpRouter } from "convex/server";
import { stravaWebhookEvent, stravaWebhookVerify } from "@clipin/convex-wearables";

const http = httpRouter();

http.route({
  path: "/webhooks/strava",
  method: "GET",
  handler: stravaWebhookVerify,
});

http.route({
  path: "/webhooks/strava",
  method: "POST",
  handler: stravaWebhookEvent,
});

export default http;

SDK ingestion route

For Apple Health, Samsung Health, and Google Health Connect, use the SDK route helper:

// convex/http.ts
import { httpRouter } from "convex/server";
import { getSdkSyncUrl, registerRoutes } from "@clipin/convex-wearables";
import { components } from "./_generated/api";

const http = httpRouter();

const routeConfig = {
  sdk: {
    syncPath: "/sdk/sync",
    authToken: process.env.WEARABLES_SDK_AUTH_TOKEN,
  },
};

registerRoutes(http, components.wearables, routeConfig);

const sdkSyncUrl = getSdkSyncUrl(process.env.CONVEX_SITE_URL!, routeConfig);

export default http;

If you are building a mobile integration, continue with SDK Push.

On this page