← Back to home

Security & Data Flow

How Zoody handles your data, what permissions it needs, and how to evaluate it for your security review.

How data flows through Zoody

Zoody sits between your product and HubSpot. Your engineering team sends usage events to Zoody, and Zoody writes aggregated data into HubSpot properties. Here is the full path:

  1. 1

    Your product sends events

    A single POST request from your backend to api.zoody.io/v1/events. Events include an event name, a user email or company domain, and optional properties (e.g., feature name, duration). No SDK installation is required - a curl or fetch call works.

  2. 2

    Zoody validates and stores

    Events are validated server-side, deduplicated, and stored in a PostgreSQL database. Invalid events are rejected immediately with specific error messages. Events are never modified or enriched - Zoody stores exactly what you send.

  3. 3

    Zoody matches and aggregates

    Based on your mapping configuration, Zoody matches events to HubSpot contacts (by email) or companies (by domain) and computes aggregated values like counts, last-seen dates, or sums.

  4. 4

    Zoody writes to HubSpot

    Aggregated values are written to HubSpot contact or company properties via the HubSpot API using OAuth tokens you authorize during setup. Zoody only writes to properties you configure - it never modifies other HubSpot data.


What data Zoody receives

You control exactly what you send. A typical event contains:

FieldExamplePurpose
eventName"feature_used"Identifies the action
email"user@acme.com"Match to HubSpot contact
domain"acme.com"Match to HubSpot company
properties{ "feature": "reports" }Optional metadata you define
timestampISO 8601 datetimeWhen the event occurred

Zoody does not require access to your application database, source code, or internal systems. It receives only the events you explicitly send.


Security details

Authentication

All API requests require a Bearer token (zo_live_...). Keys are created in your dashboard and can be revoked at any time. Each key is validated server-side against your workspace on every request.

Encryption

All data in transit is encrypted via TLS 1.2+. Data at rest is encrypted using AES-256. HubSpot OAuth refresh tokens are stored encrypted and never logged or exposed.

Infrastructure

Zoody runs on Railway (US region) with PostgreSQL and Redis. The infrastructure is isolated per service (API, worker, dashboard) with no shared runtime. Environment variables and secrets are managed through Railway's encrypted secret store.

Data retention

Events are retained for the duration of your subscription. You can delete individual events or all workspace data from the dashboard at any time. Account deletion removes all associated data.


HubSpot permissions

When you connect HubSpot, Zoody requests only the scopes it needs. Here is what each scope is used for:

ScopeWhat Zoody does with it
crm.objects.contacts.readSearch contacts by email to match incoming events
crm.objects.contacts.writeWrite aggregated usage data to contact properties
crm.objects.companies.readSearch companies by domain to match incoming events
crm.objects.companies.writeWrite aggregated usage data to company properties
crm.objects.owners.readLook up record owners for mapping context
crm.schemas.contacts.readList available contact properties for mapping configuration
crm.schemas.contacts.writeCreate custom contact properties for synced data
crm.schemas.companies.readList available company properties for mapping configuration
crm.schemas.companies.writeCreate custom company properties for synced data
crm.lists.readRead HubSpot lists for audience targeting
crm.lists.writeAdd contacts to lists based on usage data

Zoody does not request access to deals, tickets, emails, conversations, or any other HubSpot objects. You can revoke access at any time from HubSpot Settings > Integrations > Connected Apps.


Integration footprint

For security teams evaluating what Zoody requires from your engineering side:

  • One outbound HTTPS call from your backend to api.zoody.io. No inbound connections, webhooks, or open ports required.
  • No SDK required. A simple POST request with an API key works from any language or environment. The optional TypeScript SDK adds convenience (batching, retries) but is not necessary.
  • No database access. Zoody never connects to your database, application servers, or internal network.
  • No client-side code. Zoody is a server-to-server integration. Nothing is added to your frontend or user-facing application.
  • Fire-and-forget. The API call is non-blocking. If Zoody is unavailable, your product is unaffected - events are simply not recorded until service resumes.

Testing in pre-production

You can fully test Zoody without touching your production HubSpot or production application.

  1. 1

    Create a HubSpot developer test account

    Go to app.hubspot.com/signup-hubspot/developers and create a free test account. This gives you a sandbox HubSpot portal with no production data.

  2. 2

    Sign up for Zoody (free plan)

    Create a Zoody account at app.zoody.io and connect your test HubSpot portal. The free plan includes 1,000 events per month, enough for evaluation.

  3. 3

    Send test events from staging

    Point your staging or pre-prod environment at Zoody using a test API key. Or send events manually with curl to validate the integration before writing any code.

  4. 4

    Configure mappings and verify

    Set up a mapping in the Zoody dashboard (e.g., count of "feature_used" events to a HubSpot contact property). Send a few test events and confirm the values appear in your test HubSpot portal.

When you are ready to move to production, swap in your production HubSpot portal and a live API key. The integration code stays the same.


Questions for your security team?

If your team needs additional detail - SOC 2 status, a data processing agreement, or a technical walkthrough - reach out at zoody.io/contact or email security@zoody.io.