Building Integrations
This guide explains how to build integrations that log activities into Strive goals using the REST API. The built-in Strava integration serves as a reference implementation.
Overview
An integration connects an external service (like Strava, Garmin, or a custom app) to Strive so that activities are automatically logged as posts on a goal. The flow is:
- Create an API key with the
posts:writescope - Listen for events from the external service (e.g., via webhooks)
- Call
POST /api/v1/goals/:goalId/poststo log each activity
Step 1: Create an API Key
Each integration needs its own API key scoped to the minimum required permissions. For posting activities, you need the posts:write scope.
Create a key using the Create API Key endpoint or programmatically:
curl -X POST \
-H "Authorization: Bearer sk_live_your_admin_key" \
-H "Content-Type: application/json" \
-d '{"name": "My Integration", "scopes": ["posts:write"]}' \
https://api.strivejournal.com/api/v1/keys
Store the returned key securely. It is only shown once.
Step 2: Create Posts
When your external service reports a new activity, create a post:
curl -X POST \
-H "Authorization: Bearer sk_live_integration_key" \
-H "Content-Type: application/json" \
-d '{
"description": "Morning run - 5km",
"date": "2026-02-28T08:00:00.000Z",
"url": "https://external-service.com/activity/123"
}' \
https://api.strivejournal.com/api/v1/goals/abc123/posts
Response Codes
| Status | Meaning |
|---|---|
| 201 | Post created successfully |
| 401 | API key is invalid or revoked |
| 403 | Insufficient permissions or not a stakeholder |
Example: Strava Integration
The built-in Strava integration (apps/functions/src/https/strava.ts) demonstrates this pattern:
- On connect: Creates an API key with
posts:writescope, encrypts and stores it in the user's secure profile - On webhook: Decrypts the stored API key, creates a
StriveApiClient, and callscreatePost()to log the activity - On disconnect: The API key is automatically revoked via a Firestore trigger
This same pattern can be applied to any external service that supports webhooks or polling.
Security Best Practices
- Scope minimally: Only request
posts:writeunless you need other permissions - Encrypt stored keys: If storing API keys in a database, encrypt them at rest
- Revoke on disconnect: When a user disables an integration, revoke the associated API key
- Handle 401 gracefully: If the API returns 401, the key has been revoked — disable the integration and notify the user