Skip to content

Firewall and data residency

DXPR Builder stores your pages in your own Drupal database. It contacts DXPR services for licence checks, editor assets and AI requests. This page lists every connection, what each one carries, where the DXAI Kavya models run, how the product key is stored, and what works when outbound access is restricted.

Connections at a glance

Host Made by Purpose Needed for
dxpr.com Drupal server Licence status, domain check, licensed user sync Editing
cdn2.dxpr.com Editor's browser Editor JavaScript and CSS (primary) Editing
cdn.dxpr.com Editor's browser Editor JavaScript and CSS (fallback) Editing
kavya.dxpr.com Drupal server AI requests and AI credit balance AI features
html-extract.dxpr.com Editor's browser AI "clone from URL" AI features
r.jina.ai (third party) Editor's browser Reads web pages whose URLs appear in a prompt AI features
tuur.dxpr.com Editor's browser Editor usage analytics Optional

All connections use HTTPS on port 443. Site visitors never load anything from DXPR servers: published pages are rendered from HTML stored in the database, and the front-end script (dxpr_builder/dxpr_frontend.min.js) ships inside the module. app.dxpr.com appears only in links shown to administrators.

Licence checks (dxpr.com)

The Drupal server calls four endpoints defined in src/Service/DxprBuilderLicenseServiceInterface.php, each with the product key as an Authorization: Bearer header.

Endpoint When Data sent
GET /api/user-license Every 24 hours when authorised, every 30 minutes when not gba and users_tier (number of accounts with the edit with dxpr builder permission and the tier it falls in), values_count (content items using a builder field), site_base_url, site (an HMAC of the site's hash salt; the salt itself is not sent), site_mail (from system.site), project, version
GET /api/domain-blacklist/{hostname} Hourly The hostname only; no authorisation header
POST /api/central-user-storage/{add,remove,sync} When accounts, permissions or the product key change; follow-ups are queued and run on cron Hostname plus, for each account with the editing permission, its email address and role names. Accounts without a valid email address are skipped
GET /api/user-license/users When the User Licenses page is opened Nothing beyond the key

Page content is never part of a licence request. The module also prints a hidden <div> on the front page containing a fixed marker string, the licence tier, the editor count and the save count (dxpr_builder_page_bottom() in dxpr_builder.module). It is readable in the page source.

Editor assets (cdn2.dxpr.com, cdn.dxpr.com)

When Editor Assets is Cloud (the default), the editor's browser loads the builder JavaScript and CSS from https://cdn2.dxpr.com/<version>/, falling back to https://cdn.dxpr.com/<version>/ after a failed /health probe. The product key is appended to each asset URL as a jwt query parameter (dxpr_builder_library_info_build()). The CDN checks that key: a 401 response makes js/editor_validation.js show "Your product key is not valid".

The Local (minified) and Local (unminified) options only appear on the settings form when a built copy of the editor exists in the module's dxpr_builder/ directory, and such a copy is used automatically even when Cloud is selected. The git repository does not track these built files, so a release downloaded from drupal.org loads the editor from the CDN.

AI requests (kavya.dxpr.com)

The browser never contacts kavya.dxpr.com. The editor posts to routes on your own site (/dxpr_builder/ajax/ai/chat, /dxpr_builder/ajax/ai/image, /dxpr_builder/ajax/ai/image/edit; all require the edit with dxpr builder permission, a CSRF token and a licensed account). The site relays each request through the Drupal AI module's DXPR provider (ai_provider_dxpr) to https://kavya.dxpr.com/v1/chat/completions, /v1/images/generations or /v1/images/edits, authenticated with the DXPR API key stored in the Key module. The provider's host setting (ai_provider_dxpr.settings) can point requests at a different host. Separately, the AI settings page calls GET https://kavya.dxpr.com/v1/account/balance with the product key to show your credit balance.

What an AI request contains

Only AI features send page content off the site, and only when an editor triggers them (dxpr_builder/build/dxpr-global/ai-service.js).

Request Content sent
Text and page generation System prompt, the editor's prompt, chat history
With an element selected The element's outer HTML: whole if 500 characters or fewer, otherwise its first and last 200 characters
Page-level operations The existing page HTML, up to 50,000 characters; the complete page when the whole page is being replaced
Optional fields Model name, enabled provider order, a predicted HTML result, allowed tags and classes, a web_search flag, a response format
Image generation Prompt, size, quality, background
Image editing The same plus the source image, base64 encoded

Two conveniences fetch web pages from the editor's browser (ai-service-url-fetch.js): a URL in a prompt is requested with .md appended and, if that fails, through https://r.jina.ai/<url>, a third-party reader service not operated by DXPR; a prompt that asks to clone a page sends the URL to https://html-extract.dxpr.com/?url=.... In both cases only the URL is sent.

AI output is filtered on the way back. Allowed domains, blocked tags and allowed tags are set at /admin/dxpr_studio/dxpr_builder/ai_settings under AI Output Filtering.

Where the DXAI Kavya models run

DXPR Builder offers three models (src/Constants/AiModelConstants.php):

Model API name Description shown in the settings form
DXAI Kavya M1 kavya-m1 Best performance (OpenAI, Google Gemini, Anthropic)
DXAI Kavya M1 EU kavya-m1-eu Privacy-focused (MistralAI)
DXAI Kavya M1 Fast kavya-m1-fast Fastest responses, lower quality

There is no region setting in either module. Data residency is chosen by model and by which upstream providers you enable:

  • kavya-m1 fails over between five providers, listed with their country in the DXPR AI Provider settings form: Anthropic (United States), Google Gemini (United States), MistralAI (France), OpenAI (United States), XAI (United States). In Manual priority mode you drag providers between Enabled and Disabled and set their order.
  • kavya-m1-eu uses MistralAI only. The DXPR AI Provider README states it "keeps data within European boundaries (servers in Netherlands)"; its documentation states that the Kavya server runs in the Netherlands with a backup in Germany, that requests go through MistralAI servers in France, and that it never falls back to a non-EU provider. These locations are documented by DXPR, not enforced by anything in the Drupal code.

With ai_provider_dxpr installed, the model is chosen at /admin/config/ai/providers/dxpr, and its allowed_models setting controls which models editors may pick. Without it, model and provider order are set at /admin/dxpr_studio/dxpr_builder/ai_settings.

How the product key is stored

The License section of /admin/dxpr_studio/dxpr_builder/settings offers two Storage method options (src/Form/DxprBuilderSettingsForm.php, src/Service/DxprBuilderKeyService.php):

  • Key module: the key is read from the Key entity chosen under Key. dxpr_builder_update_9020() moves a key found in dxpr_builder.settings into the Key entity dxpr_builder_jwt, whose Configuration provider still exports it. Only the File or Environment provider keeps the key out of configuration exports.
  • Configuration storage: the key is saved in clear text as dxpr_builder.settings.json_web_token and is included in configuration exports.

The product key is a JSON Web Token that authenticates licence calls, the credit balance call and the CDN asset URLs; treat it as a credential.

Firewall configuration

From Allow outbound HTTPS to Notes
Drupal server dxpr.com Licence
Drupal server kavya.dxpr.com AI only
Editors' workstations cdn2.dxpr.com, cdn.dxpr.com Editor assets
Editors' workstations html-extract.dxpr.com, r.jina.ai AI only; blocking them only disables URL research and cloning
Editors' workstations tuur.dxpr.com Analytics; blocking has no effect on editing

Analytics (dxpr_builder/build/dxpr-analytics/, PostHog) identify events by the editor's email address and the site hostname. Turn them off with drush config:set dxpr_builder.settings record_analytics 0; the key has no form field. Two further keys without a form field are read from dxpr_builder.settings: cloud_url replaces the CDN base URL (VERSION is substituted with the module version) and license_endpoint replaces the central user storage endpoint. Set them with a configuration override in settings.php.

Proxy configuration

Licence and AI calls use Drupal's HTTP client, so a proxy is configured in settings.php:

$settings['http_client_config']['proxy'] = [
  'http' => 'http://proxy.example.com:8080',
  'https' => 'http://proxy.example.com:8080',
  'no' => ['localhost', '127.0.0.1'],
];

Editors' browsers load the CDN assets and call the analytics and reader services directly, so those requests follow the workstation's proxy settings.

Air-gapped and on-premise deployments

DXPR Builder runs on your own server; no content passes through a hosted component. When neither the server nor the editors can reach DXPR:

Capability Without any DXPR access
Serving published pages Works; nothing is loaded from DXPR
Content storage Works; pages are field values in your database
Loading the editor Fails unless a local build of the editor is present in dxpr_builder/
Licence validation Fails. The module logs the error, shows "We are having trouble connecting to the DXPR servers" to administrators and retries every 30 minutes. Editing is not blocked while a product key is configured
User Licenses page Empty; it needs dxpr.com
AI features Unavailable; every request goes through kavya.dxpr.com
Analytics, URL research, clone from URL Silently skipped

Without a product key at all, the module applies the free tier limits in code: one editor and 100 content items.

A fully on-premise deployment therefore works for serving and storing content; editing needs CDN access or a local editor build, and licence validation needs dxpr.com. Contact DXPR if you need an editor build to host internally.

What's next?

Something wrong or missing on this page? Report it or edit the page.