Skip to main content

Overview

Raw payloads storage lets you capture the exact JSON payloads received from wearable providers before any processing. This is useful when you need to:
  • Debug data issues - inspect exactly what a provider sent when something doesn’t look right
  • Test ingestion changes - replay real payloads against updated parsing logic to make sure nothing breaks
  • Reproduce bugs - grab the original payload that caused a problem and use it in local development
The feature is disabled by default and adds zero overhead when turned off.

Configuration

Add these environment variables to your .env file:
Raw payloads can contain sensitive health data. Make sure your storage destination meets your organization’s data protection requirements.

Storage Backends

Disabled (default)

No payloads are stored. The store_raw_payload() call returns immediately with no overhead.

Log

Writes each payload as a structured JSON line to stdout. Useful for development, or when your infrastructure already captures application logs (e.g., CloudWatch, Datadog).
Example output:

S3

Uploads each payload as a JSON file to an S3 bucket (or any S3-compatible object store like MinIO or Railway Object Storage).
AWS credentials are reused from the existing application config (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION). See the AWS Setup guide for details.

S3 key format

Files are organized by provider, source, date, and user:
Example:
  • _unknown is used when a user ID is not available (e.g., Garmin webhooks)
  • file_id is a random 12-character hex string

S3 object metadata

Each object includes metadata for filtering and querying:

Supported Ingestion Points

Raw payloads storage is currently enabled at two ingestion points:

Error Handling

Raw payloads storage is designed to never break your data ingestion pipeline:
  • Oversized payloads - Payloads exceeding RAW_PAYLOAD_MAX_SIZE_BYTES are skipped with a warning log. Data processing continues normally.
  • S3 upload failures - Errors are logged but not propagated. The webhook or sync request continues processing.
  • Missing S3 bucket - If the S3 backend is configured but no bucket is available, it falls back to disabled with an error log.
  • S3 client failure - If the S3 client cannot be created (e.g., missing boto3 or invalid credentials), it falls back to disabled.

Example Setup

Then inspect payloads in Docker logs:

Replaying Stored Payloads

Use the replay_raw_payloads.py script to re-send S3-stored payloads through the SDK sync endpoint. This is useful for reproducing issues, re-processing data after a fix, or load testing.
The script reads AWS/S3 credentials from environment variables automatically.

Filtering

Narrow down which payloads to replay:

Replaying to a different user

Use --target-user-id to send one user’s payloads to a different user account:

Dry run

Preview which payloads would be sent without making any requests:

Options