Security and data handling

HC Sync stores health values as plain JSON in Postgres and uses HTTPS for API traffic. Secret keys are stored as SHA-256 hashes; signing secrets remain readable to the server. Health records expire 13 months after their start time. This page describes implemented controls and identifies provider settings the code cannot prove.

Last updated: 2026-11-04. Source for the 2026 service details: HC Sync page details.

What data is stored?

TableFields
hc_projectsid, name, SHA-256 hash of the secret key, a random token secret (used to sign user tokens and read keys), plan, webhook URL, webhook signing secret, billing subscription id, email (optional), created_at
hc_recordsproject_id, user_id (the id you assign), record id, type, start and end time, value (JSON, up to 64 KB), source app, received_at. This is the health data.
hc_user_genproject_id, user_id, a deletion counter. Kept after a user is deleted so old device tokens stay revoked.
hc_outboxWebhook events that failed to deliver, including the record payload, until delivered or 7 days old. Up to 500 per project.
hc_deliveriesWebhook attempt log: event type, event id, success, duration. No health values.
hc_uptime, hc_hits, hc_leadsUptime samples; page views (path and referring hostname only, no IP or user agent); contact-form entries (email, app link, answers, note).

Health values are stored as plain JSON in the database. The application does not add its own encryption layer on top of the database's.

Where does HC Sync run?

How is data encrypted in transit?

How do keys and tokens work?

How are webhooks signed?

Every delivery carries x-hcsync-timestamp and x-hcsync-signature: hex HMAC-SHA256 of {timestamp}.{raw body} with your webhook secret. Retries are signed again, so they pass a 5-minute freshness check. Each event has a unique id for de-duplication. See the docs for verification code.

How long is each data type retained?

A daily job (03:30 UTC) and a 5-minute job apply these windows:

DataKept
Health recordsDeleted once their start time is more than 13 months old (not 13 months from upload)
Sample data (sample_user)Deleted 7 days after upload
Queued webhook events and delivery log7 days
Uptime samples90 days
Page-view counts180 days
Project row, contact-form entriesUntil you delete the project; contact-form entries have no automatic expiry in code (deleted on request)

Database backups and their retention are a provider setting and are not described in this repository.

How does deletion work?

What limits apply?

PlanSynced users per calendar month (UTC)Stored records
free5200,000
starter100no cap in code
indie1,000no cap in code
studio20,000no cap in code

Also enforced: at most 1,000 records per sync call, values under 64 KB, and 500 queued webhook events per project. Anonymous project creation is limited to 20 requests per IP per hour; contact submissions to 10. Counters use hashed IPs in the database. These endpoints return 429 with Retry-After when limited. Other endpoints have no application rate limiter.

Which providers does the code use?

What does the server log?

Unexpected errors log the error code and message only, never the query or its values.

Which security features are unavailable?

How do you report a security problem?

To report a vulnerability or ask a security question, email shaharfrish6@gmail.com.

Describes the code as of 31 October 2026.

What else should you know?

Does the application encrypt health values itself?

Health values are stored as plain JSON in the database. The application does not add its own encryption layer on top of the database's.

Is there an independent audit report?

No SOC 2 report or other third-party audit.

How long is sample data kept?

Sample data is deleted 7 days after upload.