October 22, 2026
Multiple custom domains per application
An application can now have several custom domains, and adding, changing or removing one never restarts the application. Custom domains start at the Intermediary plan, and the number per application grows with the plan:- Automatic
www: addingexample.comalso addswww.example.com, and the other way around. The companion redirects to the main domain, doesn’t count toward your limit, and can be turned off. Either one can be made the main domain. - Port per domain: each domain can reach a different port of your application, from 1 to 65535, with up to 5 ports besides 80 per application.
- Path prefix: a domain can add a path such as
/apiin front of every request. Recommended for APIs. - Redirects: a domain can redirect to another domain of the same application with a
301,302,307or308(default308), keeping the path and the query string. - Status and cleanup: each domain shows its status and certificate state. A domain that stays without DNS for 14 days is removed automatically and you get an email. When a domain is removed, by you, by unpublishing or by this cleanup, delete its
CNAMEand validationTXTrecords at your DNS provider. Root domains show a warning, because aCNAMEon the root needs a DNS provider with CNAME flattening.
/v1/apps/{id}/domains: list, add, update, remove and DNS records. The SDKs, the CLI, the MCP server and the VS Code extension support them. See Connect custom domains.Breaking change: plans are identified by name in the API
The API identifies a plan by its name, such aspro or enterprise-8. The numeric plan ID is gone.GET /v1/users/meno longer returnsplan_idorplan.id. Readplan.nameinstead.planisnullwhen the account has no active plan.- Applications, databases and workspaces return
owner_plan(the plan name, ornull) instead ofowner_plan_id. - Accounts without an active plan get
PLAN_REQUIREDwhen they create applications or databases or publish a site.FREE_PLAN_SUSPENDEDandFREE_PLAN_NO_WEB_PUBLISHare no longer returned. - The full list of names is in the knowledge base.
Breaking change: custom domain routes replaced
GET, POST and DELETE /v1/apps/{id}/network/custom and GET /v1/apps/{id}/network/dns are replaced by the domain routes above.- Application payloads return
domains, a list, instead ofcustom_domain.public_urlpoints to the main domain. The publish routes return the hostnames indomains. NO_CUSTOM_DOMAINis no longer returned: an application without domains has an empty list.DOMAIN_ALREADY_IN_USEnow answers409andCUSTOM_DOMAIN_REGISTRATION_FAILEDanswers502.- New error codes:
DOMAIN_NOT_FOUND,DOMAIN_LIMIT_REACHED,DOMAIN_PORT_LIMIT_REACHED,INVALID_DOMAIN_PORT,INVALID_PATH_PREFIX,INVALID_REDIRECT_TARGETandDOMAIN_CONNECT_UNAVAILABLE. See Errors.
plan_id, owner_plan_id or custom_domain.SDKs, CLI, MCP server and VS Code extension 0.3.0
New versions of the SDKs (JavaScript, Python and Go), the CLI, the MCP server and the VS Code extension support multiple custom domains per application and plans by name. They follow the breaking changes above, so update them together.- CLI: new
vertra app domainscommands (see CLI). Stopping an application or a database and removing an environment variable now ask for confirmation; declining any confirmation exits with code 1. - MCP server: new domain tools. Tools that delete, overwrite, stop, restart or change access are marked destructive, so the client asks before running them. Logs, files and other content from your applications are marked as untrusted. See MCP.
- VS Code extension: manage all of an application’s custom domains and see plan names.
- Your API key stays on the Vertra Cloud API: the MCP server and the VS Code extension no longer follow redirects, and the SDKs drop the key when a redirect leaves the API. The SDKs and the MCP server also reject invalid request paths before sending anything.
- GitHub Action v1.0.4 uses CLI 0.3.0 by default. See GitHub Actions.
Environment variable limit raised to 256
An application can now have up to 256 environment variables, up from 25. Keys can have up to 255 characters and values up to 3,072. See Configuration.Malformed JSON now returns 400
A request with malformed JSON in the body now gets400 with INVALID_JSON, where it used to get 500. Other request problems also answer with their own status and a stable code: UNSUPPORTED_MEDIA_TYPE (415), BAD_REQUEST (400) and REQUEST_TIMEOUT (408). A request with content-type: application/json and an empty body still returns 400 EMPTY_BODY. See Errors.