Deployment

Private services: keep an app off the public internet

A private app has no public address. Only your workspace's other apps can call it. Switch an app between private and public in seconds, with no rebuild or restart.

What a private app is

Every app you deploy gets a public address by default, such as shop.productecho.com. Anyone who has the link can open it.

A private app, also called a private service, is the same kind of app with the public address switched off. People on the internet cannot reach it. The other apps in your workspace can still call it, using an internal address that only works inside ProductEcho. Your workspace is the space that holds your apps, databases and team. Core concepts explains it.

Diagram of who can reach each app. Something outside your workspace, such as the internet or another workspace's app, can reach the public app through its public address, shop.productecho.com. It cannot reach the private app. The public app, which is inside your workspace, can call the private app through its internal address, http://ab12cd34-api-svc.
A public app answers anyone. A private app answers only the apps in its own workspace.
AboutPublic app (the default)Private app
Public addressYes. An HTTPS address anyone can open.None. The address is kept for the app but not served.
Who can call itAnyone who has the address.Only the other apps in your workspace.
How they call itThrough its public address.Through its internal address.
Typical useA website, or an API your customers use.An API, worker or service behind your public app.
Changing it laterMake it private in seconds.Make it public in seconds.

Private is a setting on a full-stack app, not a different kind of app. A private app is built and deployed like any other, and it counts toward your plan's app limit.

When a private app helps

Use one for any app that your other apps need and visitors never do:

  • An API that only your own web app calls. Nobody else can send requests to it.
  • A worker or job runner that your other apps trigger over HTTP.
  • An internal tool or admin service that your other apps use.
  • One of several small services that together make up a product, with a single public app in front.
When a private app will not work

A visitor's browser cannot open a private app, and neither can a service outside ProductEcho. A static site or single-page app runs in the visitor's browser, so it cannot call a private app directly. Services such as Stripe or GitHub that send you webhooks need a public address to send to, so keep the app that receives them public. To use a private app from the browser, put a public app in front: its server code calls the private app and returns the result.

How a call reaches a private app

01

A visitor opens the public app

The public app has a public address, so anyone can open it. Visitors only ever talk to this app.
02

The public app calls the private app

The public app's server code sends a request to the private app's internal address, for example http://ab12cd34-api-svc/orders.
03

ProductEcho checks where the call comes from

The call goes through because both apps are in the same workspace. A call from anywhere else, including the internet and other workspaces, does not get through.
04

The private app answers

The public app uses the answer to build its own response. The visitor never sees the private app or its address.

What an internal address looks like

An internal address is http://, then a short code for your workspace, then the app name, then -svc. For an app named api it looks like http://ab12cd34-api-svc. It uses plain HTTP on the default port, so it has no port number and no https://. Copy it from the console or ask your agent for it instead of typing it.

The address only works from inside ProductEcho. Opening it in a browser, or calling it from your own computer, fails.

Make an app private

Choose private when you first deploy an app, or switch an app that is already live. Only full-stack apps can be private. A static site cannot.

Deploy a new app as private

01

Start a new app

On the Applications page, choose Deploy container and fill in the source as you normally would.
02

Under Access, choose Private

The subdomain field disappears, because a private app has no public address.
03

Deploy, then copy the internal address

When the app is Ready, open it and choose the Domains tab. The Private service card shows the internal address with a Copy button.

Switch an app that is already live

01

Open the app's Settings tab

On the Applications page, choose the app, then Settings. The Visibility card shows whether it is Public or Private.
02

Choose Make private

Only workspace owners, admins and developers see the button. The row menu on the Applications page has the same Make private item.
03

Confirm

The dialog reminds you that visitors will get a not-found page and that other apps keep calling the app at its internal address. Choose Make private.

Within a few seconds the app shows a lock icon and a Private label in the Applications list.

Or ask your coding agent

To deploy a new app as private:

Claude Code
/productecho-plugin:productecho-deploy deploy the api folder as a private app

To switch an app that is already live:

Claude Code
/productecho-plugin:productecho-deploy make the api application private

The agent calls deploy_application with is_private set, or set_application_visibility for an app that is live. In another MCP client, leave off the /productecho-plugin:… part and ask in plain language.

Call a private app from another app

Your other apps need the private app's internal address. Give it to them as an environment variable, then call it from server code.

01

Copy the internal address

Open the private app, choose the Domains tab, and choose Copy on the Private service card. Or ask your agent for the internal address of the app.
02

Save it in the calling app

Open the calling app's Environment tab, add a variable such as API_URL with the address as its value, and choose Save & restart. Do not start the name with NEXT_PUBLIC_, VITE_ or REACT_: frameworks put those values in browser code, and changing one rebuilds the app.
03

Call it from server code

Read the variable in code that runs on the server, such as an API route, a server action or a background job.
Server code in the public app
const res = await fetch(`${process.env.API_URL}/orders`);
const orders = await res.json();

It is a normal HTTP request, so it works the same way in any language. Or ask your agent to wire the two apps together:

Claude Code
/productecho-plugin:productecho-deploy deploy the web folder as a public app and set API_URL to the internal address of the api application
Developing on your own computer?

The internal address only works inside ProductEcho. On your machine, point API_URL at your local server, such as http://localhost:8000, and set the internal address on the deployed app only.

Check the Environment tab after an agent update

An environment update replaces the stored list, so make sure your other variables are still there. Environment variables and secrets explains why.

What happens when you switch

  • It takes a few seconds. ProductEcho does not rebuild or restart the app, so the app keeps running and its internal address keeps working throughout.
  • Going private: the public address stops working at once. A visitor sees a not-found page, or a browser certificate warning over HTTPS, because nothing serves the address any more. Other apps in your workspace keep calling the app as before.
  • Going public: the same public address works again within seconds. ProductEcho keeps the address for the app while it is private, so nobody else can take it, and there is no new certificate to wait for. Anyone with the address can then open the app, so check that it does not expose anything meant to stay internal.
  • Redeploying keeps the setting. A private app stays private after a redeploy, and a deploy does not change visibility. Use the switch, or ask your agent.

What a private app does not do

  • Static sites cannot be private. A static site is served straight to visitors' browsers, so it is always public.
  • A private app cannot have a custom domain. To add one, make the app public first. To make an app that has custom domains private, remove the domains first.
  • You cannot choose which apps may call it. Every app in your workspace can, and no app outside it can. If an app holds data that not every app in your workspace should read, check who is calling in your own code.
  • The setting is for apps. It does not change who can reach your databases or your other resources.

Fix the common problems

The calling app cannot reach the private app

Check four things. The address is copied exactly and starts with http://, not https://. Both apps are in the same workspace. The private app is Ready. The call runs in server code and not in the visitor's browser: a browser cannot reach an internal address, and the usual error is that the name cannot be found.

The old public address shows a not-found page

That is expected for a private app. If visitors need the address again, make the app public.

Make private is refused

The app has custom domains. Remove them on its Domains tab, then try again.

Adding a domain to a private app fails

A private app cannot have a custom domain. Make it public first, then add the domain.

There is no Visibility card or Make private button

A static site has no switch because it is always public. For a full-stack app, only workspace owners, admins and developers can change it.

A webhook never arrives

The service sending the webhook is outside ProductEcho, so it cannot reach a private app. Keep the app that receives webhooks public.

Questions

What is a private service on ProductEcho?+

A full-stack app with no public address. The internet cannot reach it, and only the other apps in your workspace can call it, at an internal address.

Can I make an app private after it is live?+

Yes, and back to public again. It takes a few seconds and does not rebuild or restart the app. Open the app's Settings tab and use the Visibility card, or ask your coding agent.

Can another workspace's app call my private app?+

No. Only apps in your own workspace can reach a private app. Apps in other workspaces and visitors on the internet cannot.

Does making an app private change its address?+

No. ProductEcho keeps the public address for the app while it is private, so making it public again brings back the same address.

Can my static site or single-page app call a private app?+

Not directly. These run in the visitor's browser, and a browser cannot reach an internal address. Put a full-stack app in front of the private one and have its server code make the call.