Skip to main content

What Ever Gauzy sends to Ever Platform

Ever Gauzy has two optional modules that talk to Ever Platform: the anonymous usage statistics (@gauzy/plugin-ever-stats) and the connection (@gauzy/plugin-ever-connect). This page lists every call either of them can make. Nothing else in Gauzy calls Ever Platform.

This page is published at docs.gauzy.co from ever-co/ever-gauzy-docs. The copy in ever-co/ever-gauzy (tools/ever-platform/outbound-calls.md) is the one CI checks against the pinned contract; a change to it is copied to the published page.

When nothing is sentโ€‹

SettingEffect
EVER_STATS_ENABLED=falseThe statistics module is not loaded: no route (/api/ever-stats/* answers 404), no timer, no request.
Statistics switched off in Settings > Anonymous usage statisticsThe module stays loaded for the settings page; it sends nothing.
EVER_CONNECT_ENABLED unset (the default), or anything but trueThe connection module is not loaded: no route (/api/ever-connect/* answers 404), no timer, no request.
EVER_CONNECT_ENABLED=true, not connectedLoaded and idle: no request until the operator of the installation connects with a code.
ZITADEL_ENABLED=true with an issuer on an Ever host, the connection offThe sign-in plugin does not use that issuer on a self-hosted installation, so nothing is sent to it.

Every call below needs its module on, and every call of the connection needs a connection the operator made. A call that is listed but whose trigger never happens is never made.

Every callโ€‹

The table is generated from the outbound-call rows of the Ever Platform contract, at the exact version the modules pin; a check in CI fails when the table, the modules' READMEs or the egress audit drift from it. The row number is the contract's. Where Gauzy calls on a schedule of its own (row 8), the "When" and "How often" columns give Gauzy's.

Contract version: 1.0.0-rc.6 (@ever-co/connect-contracts and @ever-co/connect-tools at the same version).

#ModuleRequestWhenWhat it carriesHow oftenHow to stop it
1connectionGET /.well-known/ever-keys.jsonfirst signature verification; every 24 h; an unknown key idnone (read)at most every 24 h; at most once per 10 min on an unknown key iddisconnect, or leave EVER_CONNECT_ENABLED unset
3connectionPOST /v1/connect/redeemthe operator submits a connect code; EVER_CONNECT_CODE at first bootcode, product, version, install_source, kind (self_hosted; cloud on deployments Ever operates), serves_products[], public_jwk (the connect key), tenant {product_tenant_id, product_org_id?, display_name}? (absent values are omitted, never sent as null); never the installation's addressoncedo not connect
4connectionPOST /v1/instances/tokenwhile connected: before the token expires, and after a 401grant_type, client_assertion_type, client_assertion (issuer and subject are the Ever Platform instance id returned at connect, never the statistics instance id)every 50 min while connected (a token is kept for its hour; at most 60 an hour); on a 401disconnect
5connectionPOST /v1/instances/me/tenant-links, DELETE /v1/instances/me/tenant-links/{link}an organization admin submits a link code, removes a link, or a single-organization product moves its link to a new organization idlink_code, product, product_tenant_id, product_org_id?, display_name? of the tenanton actiondo not link
6connectionPOST /v1/instances/me/heartbeat, GET /v1/instances/mewhile connected; the status read also while an approval is pending and when an admin opens the connection pageversion, module_version?, serves_products[]? (heartbeat); none (status read)within 5 min of boot, then every 24 hdisconnect
7connectionGET /v1/instances/me/events, POST /v1/instances/me/events/ackwhile connectedcursor onlycontinuous long-poll (wait=25), or one read every 15 min with EVER_CONNECT_FEED_MODE=intervaldisconnect
8connectionGET /v1/instances/me/entitlement, GET /v1/instances/me/tenant-links/{link}/entitlementwhile connected: at connect and at each link, with each heartbeat, on an entitlement notice on the event feed, on demand (Refresh, at most 6 an hour)none (read; If-None-Match with the cached sequence number)with the heartbeat (every 24 h); on a notice; on demanddisconnect
9connectionGET /v1/instances/me/integrations, GET /v1/instances/me/consent-urlafter a consent notice; on return from app.ever.co; when an admin opens the integrations tabintegration, link, return (query)on action or noticedisconnect
10connectionPUT /v1/instances/me/integrations/{key}an admin disables an integration locally; an operator policy denies itenabled: false, reason (instance or policy), tenant_link_id?on actionnone needed: this call only ever disables
11connectionPOST /v1/instances/me/stats-linkintegration stats_link enabled (self-hosted installations only)stats_instance_id, stats_public_jwk, statement_sig: a statement signed with the separate statistics key, sent under the connect-key token, so app.ever.co can show the installation's last reportonce; again after Reset instance identitydisable stats_link
16connectionPOST /v1/instances/me/disconnect, POST /v1/instances/me/keysthe operator disconnects; the connect key is rotatednone (disconnect); public_jwk of the new connect key with two rotation proofs, one signed with the current connect key and one with the new key (rotation; the statistics key is never rotated by this call)on actionnone needed: operator action only
17statisticsPOST /v1/stats/reportsstatistics module loaded and enabledthe ever.stats.v1 document: statistics instance id, product, version, channel, install source, coarse country, month, allow-listed counts, feature flags and integer aggregatesonce a day at a jittered time; at boot when the last send is older than 24 h; a final re-send of the previous month on days 1-3EVER_STATS_ENABLED=false, or the settings toggle
31connectionPOST /v1/instances/me/integrations/{key}/acceptthe operator accepts or declines an installation-wide integration that waits for the local acceptconsent_id, acceptedon actionnone needed: operator action only

Every request goes to EVER_PLATFORM_API_URL (the statistics: EVER_STATS_API_URL), both https://api.ever.co by default. No request carries a person's name or e-mail address. The module READMEs say in detail what each request carries and when.

Calls of the contract that Gauzy does not makeโ€‹

The contract describes more calls for Gauzy than this release makes. These are never made:

#CallsWhy Gauzy does not make them
2Legal textsnot built in this release
14Ever ID sign-in clientnot served by version 1 of the Ever Platform API
18Installation addressnot built in this release
19Person linksnot served by version 1 of the Ever Platform API
20Receipt for a deletion or export requestnot served by version 1 of the Ever Platform API
22Identity resolutionnot served by version 1 of the Ever Platform API
23Signed-in person's contextnot built in this release
25Cloud billing linknot served by version 1 of the Ever Platform API
27Usage reportsnot served by version 1 of the Ever Platform API
30Webhook endpointnot built in this release
33In-product consentnot served by version 1 of the Ever Platform API

Older features that call Ever serversโ€‹

None of Gauzy's other features calls an Ever server by default. The egress audit (below) checks it on every published build, with both modules off: no Ever host is looked up or requested by the API or by the web app.

How it is checkedโ€‹

  • At run time, the egress audit runs the published API and web app images on Docker networks with no route out and records every DNS query and connection attempt, of the API and of a real browser that opens every page of the web app. With both modules off, or loaded but idle, there is none to an Ever host. With a module on, against a mock of Ever Platform, every call made is one of the table above.
  • In the code, node tools/egress-audit/static-hostnames.mjs fails when code outside the modules names an Ever host (or the Ever Platform address variables) it did not name before, in the sources and in the built web app; node tools/ever-platform/check-import-boundary.mjs fails when code outside the modules imports them.

How to verify yourselfโ€‹

Run the API with both modules off and capture its traffic (for example tcpdump -i any host api.ever.co, or a Compose network with internal: true): there is none to Ever Platform. Or run the egress audit locally, with Docker, at the root of a checkout of ever-co/ever-gauzy (the audit and its config live there; its README has the other modes and the route-list check):

npm ci --prefix tools/egress-audit --ignore-scripts
: > /tmp/api-empty.env
GAUZY_AUDIT_SECRET=$(openssl rand -hex 32) GAUZY_AUDIT_DOTENV=/tmp/api-empty.env \
GAUZY_API_IMAGE=ghcr.io/ever-co/gauzy-api-demo:latest GAUZY_WEBAPP_IMAGE=ghcr.io/ever-co/gauzy-webapp-demo:latest \
node tools/egress-audit/node_modules/@ever-co/connect-tools/dist/egress-audit/run.mjs \
--config tools/egress-audit/egress-audit.config.json --mode off