- Home
- Manage the site
- Meet compliance requirements
- Firewall and data residency
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-m1fails 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-euuses 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 indxpr_builder.settingsinto the Key entitydxpr_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_tokenand 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?
- Installation: configure the product key and storage method
- AI features: enable AI and choose a model
- Security: permissions and output filtering
- Licence and product key: troubleshooting licence errors