How it works

Read-only, and specific about it.

Tendal asks for the narrowest set of scopes that can answer one question: is each person on the cheapest seat that still lets them do their job.

Posture

It never writes.

Not as a setting you could switch: there is no code in Tendal that changes anything. It asks for no permission to create, alter or delete a record, a property or a user. Recommendations are for you to act on in HubSpot, by hand, if you agree with them.

One honest exception, because you will see it on HubSpot's approval screen. Reading your workflows needs the scope HubSpot calls automation, and HubSpot publishes no read-only version of it, so approving it grants write as well. Tendal only ever reads. It is optional: decline it and you lose the automation signals, nothing else. Every scope is listed with its reason on the shared data page.

Nothing is installed in your portal. No agent, no embedded card, no background job running inside HubSpot. Tendal is an outside reader that connects, counts, and disconnects.

Disconnecting is done from your own HubSpot account, under connected apps. It takes effect immediately and needs nothing from us.

Scopes

Everything it asks for, and why.

Required scopes are the ones without which there is no audit. Optional scopes sharpen it: if your plan does not include one, Tendal runs without it and names what it could not measure.

Required

crm.objects.users.read · The list of users and the seat assigned to each. This is the audit.
settings.users.read · Whether a user is active or deactivated, and their permission set.
crm.objects.owners.read · Joins users to record ownership, including owners of deactivated users.
crm.objects.contacts.read · How many contacts each user touched in the window, as an activity signal.
crm.objects.deals.read · How many deals each user worked, as an activity signal.

Optional

automation.sequences.read · Who sends sequences. A sender needs a paid seat, so this protects users from a wrong downgrade.
automation · Which workflows enrol sequences, and who they send as. HubSpot publishes no read-only version of this scope, so granting it also grants write. Tendal only ever reads. Decline it and every other pillar still works.
settings.users.teams.read · Who is in each team. A workflow notification can be addressed to a team rather than a named person, so without this Tendal cannot tell a team that still has members from one that has none. It then says the check was incomplete instead of reporting a clean result.
scheduler.meetings.meeting-link.read · Personal versus round-robin links, as an activity signal.
crm.objects.forecasts.read · Whether a user submits forecasts, which is a Sales Hub seat signal.
crm.objects.leads.read · How many leads a user owns, so prospecting counts as work. Without it a prospector reads as idle and the seat recommendation is wrong.
crm.objects.quotes.read · How many quotes a user builds, which is Sales Hub work the seat question turns on.
tickets · How many tickets a user owns and works, so Service work counts. Without it a support agent reads as idle, because none of the other signals can see a ticket.
crm.schemas.custom.read · Which custom object types exist, so activity on them is not missed.
crm.objects.custom.read · How many custom-object records each user touched.
account-info.security.read · When a user last logged in. Enterprise-only: on smaller plans the result says the signal is missing rather than counting those users as inactive.
What is stored

Counts, not your CRM.

Tendal reads records to count them. It does not copy them. What persists between scans is deliberately thin.

Kept: your portal id, an encrypted token that lets Tendal reconnect, and one snapshot per scan holding derived figures: seat counts, the saving, how many users fell in each category. That is what makes a trend possible.

Not kept: your contacts, companies, deals or tickets. The trend history is built so it cannot carry personal data: the audit names users by email while it runs, and the stored snapshot does not, so neither the history nor the alerts derived from it can leak one.

Access tokens are never stored. Only the refresh token is, encrypted at rest. Every scan mints a short-lived access token and discards it.

Alert destinations are encrypted the same way: a Slack webhook because it is a credential, an email address because it is personal data.

Read the output before you connect anything.

The sample runs against a synthetic portal. Every figure in it is invented and no real account is contacted.

See a sample