Telemetry and outbound connections

What a self-hosted Future AGI install sends to Future AGI and to other hosts, what it never sends, and how to turn deployment telemetry off or block it.

In this page

A self-hosted install makes one kind of call home on its own: deployment telemetry to Future AGI, on by default. An install with an Enterprise licence makes a second: licence activation and a licence heartbeat, which carries the same instance id and usage counts. This page covers what it sends and when, what it never sends, how to turn it off, how to see what your install sent, and every other outbound connection the platform and the browser UI make. It applies to Standalone, Distributed and Helm. The exact payloads are under Registration and Heartbeat.

📝
TL;DR

After the first account is created, the install registers once with api.futureagi.com, including the email addresses of its owner, admin, staff and superuser accounts, then sends usage counts every 6 hours. It never sends traces, prompts, outputs, datasets or keys. Turn it off with ./bin/install --no-telemetry or FUTURE_AGI_TELEMETRY_DISABLED=true; one minimal registration without email addresses still goes out, so block api.futureagi.com to send nothing. The only other connections made by default are litellm’s price-list download, the model server’s downloads from the Hugging Face Hub, and the assets users’ browsers load from public hosts. An Enterprise licence adds its own heartbeat. Every other outside service stays off until you give it a key.

At a glance

ConnectionOn by default?DestinationControlled by
Deployment telemetryYesFUTURE_AGI_TELEMETRY_URL (default https://api.futureagi.com)FUTURE_AGI_TELEMETRY_DISABLED=true turns it off
HubSpot lead syncNoapi.hubapi.comHUBSPOT_API_TOKEN
Slack “new user” messageNoYour webhookSLACK_WEBHOOK_CHANNEL
Slack internal alertsNoYour webhookERROR_LOGS_WEBHOOK
Mixpanel (server)Noapi.mixpanel.comMIX_PANEL_TOKEN
PostHog (server)NoPOSTHOG_HOSTPOSTHOG_API_KEY
reCAPTCHANowww.google.com/recaptchaRECAPTCHA_SECRET_KEY, RECAPTCHA_ENABLED
SentryNoYour DSNSENTRY_DSN
EmailNo (printed to the app log)MailgunMAILGUN_API_KEY
Enterprise licence checkOnly with a licenceFUTURE_AGI_LICENSE_URLEE_LICENSE_KEY
Google Tag Manager (UI page)Nowww.googletagmanager.comVITE_GTM_ID at frontend build time
Browser UI: fonts and iconsYes, from each user’s browser, on every pagefonts.googleapis.com, fonts.gstatic.com, api.iconify.designNot switchable; see The browser UI
Browser UI: editor, previews, videos, logosYes, from the browser, on the screens that use themcdn.jsdelivr.net, unpkg.com, view.officeapps.live.com, Loom, Arcade, flagcdn.com, an S3 bucket, flaticon.comNot switchable; see The browser UI
Browser analytics, error reports, ad pixelsNoMixpanel, PostHog, Sentry, New Relic, Google, Reddit, XVITE_* keys at frontend build time; see The browser UI
Model price list (litellm)Yes, at each API and worker startraw.githubusercontent.comLITELLM_LOCAL_MODEL_COST_MAP=True in .env uses the list bundled with the image (prices as of the pinned litellm release)
Model downloads (serving)When serving runs, the first time each model loadsThe Hugging Face HubPre-seed the model cache, then HF_HUB_OFFLINE=1 and TRANSFORMERS_OFFLINE=1
Public-IP lookup (installer only)Noifconfig.io, then api.ipify.org./bin/install makes it only when VITE_HOST_API names a host other than localhost

Model providers, SSO providers and integrations you add in the product are called only when you configure them and use them. Other outbound connections has the details, the installer included.

What is sent

Future AGI uses deployment telemetry to count the installs that are running, which versions they run, and roughly how much they are used. It never includes anything you send through the product.

Registration, once per install. The app tries to register right after the first account is created, whether through the sign-up page or python manage.py create_user, which ./bin/install runs. It runs on a background thread, so the sign-up page returns without waiting for it. create_user waits for it before exiting, which takes a few seconds, longer if the telemetry URL does not answer: three tries, each bounded by FUTURE_AGI_TELEMETRY_TIMEOUT_SECONDS, which ./bin/install sets to 2 for that command unless you set it. If that attempt fails, the scheduled job below retries it. Registration is sent again only if you turn telemetry off or back on, or if the install loses the signing secret it received the first time.

Heartbeats, every FUTURE_AGI_TELEMETRY_INTERVAL_HOURS (6 by default), started by a recurring Temporal schedule with up to FUTURE_AGI_TELEMETRY_JITTER_SECONDS (30 minutes by default) of random delay. Each heartbeat covers the previous fixed UTC window, for example 06:00 to 12:00, and holds counts only, across the whole install.

Nothing is sent at startup or on login.

Registration

A registration payload, and what each field means:

{
  "schema_version": 1,
  "instance_id": "5b0c6a4e-8f0e-4c55-9d1a-2f5c1a7e9b3d",
  "version": "1.8.0",
  "deployment_type": "docker",
  "timestamp": "2026-09-25T10:15:00Z",
  "telemetry_disabled": false,
  "users": [
    {
      "email": "owner@example.com",
      "domain": "example.com"
    }
  ]
}
FieldMeaning
schema_versionVersion of this payload format.
instance_idA random UUID created on first run and stored in your database. It identifies the install, not a person.
versionThe first of FUTURE_AGI_VERSION, SERVICE_VERSION and GIT_SHA that names a release (unknown and latest are skipped), else unknown. FUTURE_AGI_VERSION is the image tag in .env; SERVICE_VERSION and GIT_SHA come from the image.
deployment_typeFUTURE_AGI_DEPLOYMENT_TYPE if set (docker in both compose files); otherwise kubernetes, docker or bare_metal, detected.
timestampWhen the payload was built (UTC).
telemetry_disabledfalse here. true on the opt-out registration.
usersOne entry for each active account that is an organization owner or admin, or a Django staff or superuser account (for example one made with manage.py createsuperuser), at the time of registration, most recent login first, at most 500. On a new install that is normally only the first account.
users[].emailThe account’s email address, lowercased.
users[].domainThe part of email after the @.

Heartbeat

A heartbeat payload, what its fields mean and what each count covers:

{
  "schema_version": 1,
  "instance_id": "5b0c6a4e-8f0e-4c55-9d1a-2f5c1a7e9b3d",
  "version": "1.8.0",
  "window_start": "2026-09-25T06:00:00Z",
  "window_end": "2026-09-25T12:00:00Z",
  "active_users_count": 3,
  "traces_count": 1520,
  "spans_count": 20417,
  "projects_count": 1,
  "eval_logger_count": 212,
  "model_hub_evaluations_count": 40,
  "dataset_eval_runs_count": 96,
  "total_evaluations_count": 348,
  "simulation_runs_count": 2,
  "simulation_calls_count": 18,
  "experiments_count": 1,
  "gateway_requests_count": 930,
  "datasets_count": 2
}
FieldMeaning
schema_versionSame as in registration.
instance_idSame as in registration.
versionSame as in registration.
window_startStart of the fixed UTC window the counts cover, included. A heartbeat covers the previous window, for example 06:00 to 12:00.
window_endEnd of that window, excluded.

Every count covers only that window, across the whole install:

FieldCounts
active_users_countDistinct users who created a project, dataset, evaluation or experiment, plus owners of projects that received spans.
traces_countDistinct traces received.
spans_countSpans received.
projects_countProjects created.
eval_logger_countEvaluation results logged on traces.
model_hub_evaluations_countEvaluations created.
dataset_eval_runs_countEvaluation cells written in datasets.
total_evaluations_countThe sum of the three evaluation counts above.
simulation_runs_countSimulation runs started.
simulation_calls_countCalls those simulation runs completed.
experiments_countExperiments created.
gateway_requests_countRequests through the Agent Command Center gateway.
datasets_countDatasets created.

A count is null when it could not be read (for example, ClickHouse was unavailable), so a failure is never reported as zero.

How it is sent

  • Each payload is an HTTPS POST of JSON to FUTURE_AGI_TELEMETRY_URL (https://api.futureagi.com by default) plus /telemetry/register/ or /telemetry/heartbeat/, with a FUTURE_AGI_TELEMETRY_TIMEOUT_SECONDS timeout (5 by default), tried up to 3 times. A payload over 512 KiB is not sent.
  • The registration response carries a per-install secret. Heartbeats are signed with it (HMAC-SHA256, in the X-FAGI-Telemetry-Signature header), so the receiver can reject forged ones.
  • A heartbeat that cannot be delivered is kept as a JSON file in FUTURE_AGI_TELEMETRY_BUFFER_DIR, a directory only the app’s user can read, and sent on a later run, oldest first. Files older than 30 days are deleted.
  • Telemetry failures are logged as warnings and never stop the app, a sign-up or a login.

The receiving server sees the IP address the request comes from, as any HTTPS server does; the payload does not contain it. On Future AGI’s side, the receiving service stores registrations and heartbeats and can pass registrations on to Future AGI’s own CRM, product-analytics and team-chat tools.

What is never sent

Prompts, model outputs, trace or span contents and attributes, dataset rows, evaluation inputs or results, API keys, provider keys, passwords, names, organization or project names, and the email addresses of members who are not owners, admins, staff or superusers.

Turn it off

  • At install: ./bin/install --no-telemetry (Windows: .\bin\install.ps1 -NoTelemetry) writes FUTURE_AGI_TELEMETRY_DISABLED=true to .env before anything starts, so even the first account’s registration is the minimal one. The installer prints what telemetry sends before it asks for the first account’s email.

  • Standalone or Distributed, after install: uncomment or add FUTURE_AGI_TELEMETRY_DISABLED=true in .env (1, yes and on also work), then recreate the containers. Both compose files pass the variable to every backend process.

    docker compose up -d
  • Helm: config.telemetry=false in your values sets the variable for the backend, the workers and the bootstrap job. global.airgap=true turns telemetry off too, along with the licence heartbeat (unless license.heartbeat is true), the price-list download and model serving’s downloads. Offline, the one opt-out registration below then fails the same harmless way and is retried. See Configure.

With telemetry off, no email addresses and no heartbeats are sent, and buffered heartbeats are deleted. One opt-out registration is still sent, so Future AGI can count installs that opted out. It contains only schema_version, instance_id, version, deployment_type, timestamp and telemetry_disabled: true, and is sent again only if you turn telemetry back on and off. Until one gets through, it is attempted at every telemetry run.

To make no connection to Future AGI at all, also block outbound traffic to api.futureagi.com (or the host in your FUTURE_AGI_TELEMETRY_URL) at your network. The failed attempts are logged as warnings and change nothing else.

Settings

Every setting of deployment telemetry, with its default in each setup (S Standalone, D Distributed, H Helm), as in the Configuration reference:

KeyDefaultSetupsWhat it does
FUTURE_AGI_TELEMETRY_DISABLEDfalseS D Htrue opts out (1, yes and on also work): no email addresses and no heartbeats are sent, and buffered heartbeats are deleted; one minimal registration remains (what it contains). ./bin/install --no-telemetry (.\bin\install.ps1 -NoTelemetry) writes it before anything starts. Helm: config.telemetry=false.
FUTURE_AGI_TELEMETRY_URLhttps://api.futureagi.comS D HWhere registrations and heartbeats go. Change it only to test against another receiver.
FUTURE_AGI_TELEMETRY_INTERVAL_HOURS6S D HHeartbeat interval: 1, 2, 3, 4, 6, 8, 12 or 24. Other values fall back to 6.
FUTURE_AGI_TELEMETRY_JITTER_SECONDS1800S D HMaximum random delay added to each scheduled run, so installs do not all send at once.
FUTURE_AGI_TELEMETRY_TIMEOUT_SECONDS5S D HTimeout of each request. ./bin/install runs its create_user with 2 unless this is set, so an unreachable telemetry URL delays the first account only briefly.
FUTURE_AGI_TELEMETRY_BUFFER_DIRS: /data/telemetry; D: /tmp/futureagi-deployment-telemetry; H: futureagi-deployment-telemetry under the system temp dirS D HWhere undelivered heartbeats wait for the next attempt, in a directory only the app’s user can read. Files older than 30 days are deleted.
FUTURE_AGI_DEPLOYMENT_TYPES D: docker; H: detected: kubernetesS D HReported as deployment_type in telemetry. Unset, it is detected: kubernetes, docker or bare_metal.

Telemetry reports FUTURE_AGI_VERSION, the image tag, as version: see the version field under Registration.

See what your install sent

  • On the first telemetry run, each process logs one deployment_telemetry_disclosure line saying what it sends, where, and how to turn it off.

  • The last registration payload is kept in your own database. This works for Standalone and Distributed alike:

    docker compose exec postgres sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -x -c \
      "SELECT instance_id, registration_kind, registered_at, registration_metadata, last_heartbeat_at FROM deployment_telemetry_state"'
  • Heartbeats waiting to be delivered are plain JSON files in FUTURE_AGI_TELEMETRY_BUFFER_DIR: /data/telemetry in Standalone, /tmp/futureagi-deployment-telemetry in Distributed.

Third-party services

Each of these stays off until you set its key, and none is needed to run Future AGI. With no key set, the app makes no request to that service, logs nothing about it above debug level, and never slows down or fails a sign-up or login because of it.

ServiceTurned on byWhat it does
HubSpotHUBSPOT_API_TOKENLead sync for Future AGI Cloud. Email and SSO sign-ups, and a user without an organization creating one, create or update a HubSpot contact, except while ENV_TYPE is local, the Compose default. Each login marks the contact as logged in, in the background, so HubSpot never delays or fails a login. Accounts created with a password chosen up front, as on the open-source sign-up page or with manage.py create_user, never create a contact, key or not. Without the key: no HubSpot request, no background thread, no log line above debug.
SlackSLACK_WEBHOOK_CHANNEL, ERROR_LOGS_WEBHOOKSLACK_WEBHOOK_CHANNEL posts a “new user joined” message after an email or SSO sign-up, except while ENV_TYPE is local. ERROR_LOGS_WEBHOOK posts internal alerts, for example a failed HubSpot update or an unavailable embeddings service, never while ENV_TYPE is local or test.
MixpanelMIX_PANEL_TOKENServer-side product analytics events (sign-up, login, SDK use). Each request has a 5-second timeout and is not retried, and a Mixpanel failure never fails a sign-up or login.
PostHogPOSTHOG_API_KEY, and POSTHOG_HOST (default https://us.i.posthog.com)Server-side product analytics events for API requests
reCAPTCHARECAPTCHA_ENABLED, RECAPTCHA_SECRET_KEYChecks sign-up, login and token refresh. See below.
SentrySENTRY_DSN, plus SENTRY_ENABLED=true while ENV_TYPE is localSends error reports to your Sentry project. SENTRY_ENABLED=false turns them off even with a DSN.
MailgunMAILGUN_API_KEYSends invites and password resets. Without it, emails are written to the app log.

reCAPTCHA. Off on a self-hosted install: the compose files set RECAPTCHA_ENABLED=false, while Future AGI Cloud checks sign-up, login and token refresh by default. To turn it on, set RECAPTCHA_SECRET_KEY and RECAPTCHA_ENABLED=true on the backend, and build the frontend with VITE_GOOGLE_SITE_KEY: the published frontend image has none, so leave it off with the published images. On Helm, config.recaptcha=true sets RECAPTCHA_ENABLED, and the chart refuses to render it without RECAPTCHA_SECRET_KEY (in secrets.extra or config.extraEnv) or a config.extraEnvFrom source. When RECAPTCHA_ENABLED is unset, outside Compose, the check runs only if RECAPTCHA_SECRET_KEY is set and ENV_TYPE is not local or development. RECAPTCHA_ENABLED=true without a secret is a misconfiguration: the check can never pass, so sign-ins that go through it are rejected.

The published UI images are built without browser analytics keys, so users’ browsers send nothing to Mixpanel, PostHog, Sentry, Google Tag Manager or ad networks: see The browser UI. USAGE_EVENTS_ENABLED stays false in both compose files and in the chart (config.usageEvents): only Future AGI Cloud drains that Redis stream, and turned on anywhere else it grows until it takes the memory Redis needs.

AWS and GCP Marketplace

The marketplace sign-up endpoints of Future AGI Cloud (/accounts/aws-marketplace/, /accounts/gcp-marketplace/) are not served by an open-source install. The AWS Marketplace client uses only AWS_MARKETPLACE_ACCESS_KEY_ID and AWS_MARKETPLACE_SECRET_ACCESS_KEY, never the default AWS credential chain, so your Bedrock keys or instance role are never used for it.

Other outbound connections

  • Model providers, SSO providers and integrations are called only when you configure them and use them.
  • litellm’s model price list. Each API and worker process downloads it from raw.githubusercontent.com when it starts. LITELLM_LOCAL_MODEL_COST_MAP=True in .env uses the list bundled with the image instead, with prices as of the pinned litellm release.
  • Model downloads from the Hugging Face Hub. The model server, serving, downloads each of its models the first time a feature asks for it. serving always runs on Distributed, and runs with the ml profile on Standalone and with serving.enabled on Helm. Pre-seed its model cache and set HF_HUB_OFFLINE=1 and TRANSFORMERS_OFFLINE=1 to stop the downloads.
  • The browser UI. Users’ browsers load the UI’s fonts from fonts.googleapis.com and fonts.gstatic.com and its icons from api.iconify.design on every page, and a few screens load a code editor, document previews, videos and logos from other public hosts. None of them is Future AGI. The browser UI lists each host and what an install without it loses.
  • The Enterprise licence. With EE_LICENSE_KEY set, the app activates the licence with https://api.futureagi.com (FUTURE_AGI_LICENSE_URL) when a licensed feature first needs it, and sends a licence heartbeat every 24 hours. The heartbeat carries the licence id, the instance id, the version, the deployment type, a timestamp, a nonce and a sequence number, and the same usage counts as a telemetry heartbeat, for the last 24 hours. It is separate from deployment telemetry: FUTURE_AGI_TELEMETRY_DISABLED does not stop it, and FUTURE_AGI_ENTERPRISE_HEARTBEAT_DISABLED=true does.
  • The installer. ./bin/install and .\bin\install.ps1 pull images from Docker Hub, and on Distributed also from ghcr.io (the MinIO and PeerDB images), or build the Future AGI images with --from-source. Apart from that and the lookup below, they talk only to the stack they start. Before they ask for the first account’s email, they print what deployment telemetry will send and how to opt out (--no-telemetry, -NoTelemetry).
  • The installer’s public-IP lookup. When VITE_HOST_API in .env names a host other than localhost or 127.0.0.1, the bash installer asks https://ifconfig.io (then https://api.ipify.org if that fails) for the host’s public IP address, to print a public URL in its final summary. Those services see the request’s IP address. With VITE_HOST_API unset or local, the default, it makes no such request, and the PowerShell installer never does.

The LLM gateway’s OpenTelemetry export, described in Observability, sends gateway traces to a collector you choose and is unrelated to deployment telemetry.

The browser UI

The UI runs in each user’s browser, so these requests come from the browser, not from your server. Each host sees the browser’s IP address; the UI sends no Referer to other sites (Referrer-Policy: same-origin). None needs a key, and none of them is Future AGI.

HostLoaded whenWithout it (an air-gapped install)
fonts.googleapis.com, fonts.gstatic.comEvery page: the stylesheet imports Inter and IBM Plex Sans from Google Fonts.Text uses the Inter bundled with the UI (weights 400 to 700) and system fonts. A firewall that drops these requests instead of refusing them can delay the first paint until the browser gives up.
api.iconify.design (then api.simplesvg.com, api.unisvg.com)Every page: each icon is fetched by name the first time it is shown, then kept in the browser’s local storage.Icons are blank, including icon-only buttons such as close, menus and show password.
cdn.jsdelivr.netThe code editor: code evals and their test playground, JSON eval results, Execute Code columns, tool schemas, a dataset’s Add Row.The editor stays on “Loading…”, so code evals, code columns and tool schemas cannot be written.
unpkg.comPreviewing a PDF in a dataset or experiment cell.PDF preview fails.
view.officeapps.live.comPreviewing a Word document in a dataset cell. Microsoft’s viewer receives the document’s URL and downloads the document from it.Word preview fails. It also fails online when the file is not reachable from the internet.
www.loom.com, cdn.loom.comTutorial videos: Get started, and the empty Agent definitions and Scenarios pages under Simulate.Empty video frames.
demo.arcade.software, app.arcade.softwareInteractive tours: the Knowledge base page while it has none, and some help links.Empty frames.
flagcdn.comThe country-code picker of a voice agent.No flags.
fi-image-assets.s3.ap-south-1.amazonaws.comModel-provider logos: model pickers, the API keys page, LLM spans.No logos.
cdn-icons-png.flaticon.comAnnotator avatars on a dataset’s Annotations tab.No avatars.

No setting serves these from the install itself yet. Without them an air-gapped install still works, apart from the code editor (and so code evals) and PDF and Word previews. Media URLs in your datasets and traces, a LiveKit server, and YouTube or Vimeo links load from wherever they point.

Analytics, error reports and ad pixels send nothing unless the UI was built with their keys, and the published images are built with none of them:

ServiceBuild-time key
MixpanelVITE_MIXPANEL_TOKEN
PostHogVITE_POSTHOG_KEY
SentryVITE_SENTRY_DSN
New RelicVITE_NEWRELIC_LICENSE_KEY and an application ID; without them the agent is not started
Google Tag ManagerVITE_GTM_ID
reCAPTCHAVITE_GOOGLE_SITE_KEY
Google, Reddit and X ad pixelsVITE_GOOGLE_ADS_ENABLED, VITE_REDDIT_ADS_ENABLED, VITE_TWITTER_ADS_ENABLED, each with its ID

Restricted networks

To run an install with no outbound access, or to keep it from trying to reach outside hosts:

  • Set FUTURE_AGI_TELEMETRY_DISABLED=true, and block api.futureagi.com so the one minimal registration fails harmlessly.
  • Set LITELLM_LOCAL_MODEL_COST_MAP=True so no process downloads the price list.
  • Leave the third-party keys above empty.
  • With an Enterprise licence, decide on the licence heartbeat: FUTURE_AGI_ENTERPRISE_HEARTBEAT_DISABLED=true stops it.
  • Set HF_HUB_OFFLINE=1 and TRANSFORMERS_OFFLINE=1 so the model server downloads no models, after pre-seeding its model cache.
  • Point LLM features at a model server on your network. One added in the UI on a private address needs AGENTCC_ALLOW_PRIVATE_PROVIDER_URLS=true: see Local and private model servers.
  • Route what must go out through a proxy with HTTP_PROXY, HTTPS_PROXY and NO_PROXY in a compose override. On Distributed, list the override in COMPOSE_FILE: see Move to managed data stores. The LLM gateway does not use a proxy yet.
  • Expect users’ browsers to lose the code editor, and with it the writing of code evals, and PDF and Word previews, when they cannot reach the public hosts in The browser UI.

On Helm, global.airgap=true covers telemetry, the licence heartbeat, the price list and model serving’s downloads in one value, and global.imageRegistry points every image at your mirror. See Install on Kubernetes with Helm. At a glance lists every connection and Settings every setting.

Dive deeper

Was this page helpful?

Questions & Discussion