Apps

Deploy an app

An app is a site with server code: requests to /api and everything below it on the site go to your code, all other paths keep serving the site's static files. Same address, no CORS; the site's password, paid access and own domain apply to /api too. The code is one bundled ES module (plus optional extra modules) in the standard module worker format (export default { fetch, scheduled }); no build step runs here. fetch() only reaches allowed_hosts and the Hypamoon API (the project's own data, with a key Hypamoon adds). To use a secret from the vault, send the header x-hypamoon-secret: <name>; the code never sees its value. Each app runs isolated, with limits per request (CPU time, fetch calls) and an outbound budget per minute and per day. The first deploy for a site creates the app (201); a deploy for a site that already has one publishes a new version (200). On a new version, every setting you leave out (allowed_hosts, secrets, schedules, vars, auth, database, fetch_pages) keeps its current value, and the answer lists them in kept. Clear one explicitly: [] or {} for a list or vars, null for auth, false for fetch_pages. database: false on an app that has a database is refused (409): a deploy never disconnects a database. The code works the same way: leave main_module and modules out to keep the running code (to change only settings, or to move a test app to live), or send only the changed modules with keep_existing_modules: true. A new app always needs main_module and modules. The ten newest versions are kept for rollback. Before anything goes live the code is checked for mining, hidden or downloaded code and fake login pages; there is no option to skip that check. A live app needs a verified project. An app that runs in test mode moves to live when you deploy it with a live key once the project is verified: it keeps its database and its users. A live app cannot go back to test (key_mode_mismatch).

post/apps

Request

  • Base URL: https://api.hypamoon.com/api/v1
  • URL: https://api.hypamoon.com/api/v1/apps
  • Auth: one of:
    • HTTP bearer
    • OAuth 2 (authorization code, authorization URL https://app.hypamoon.com/oauth/authorize, token URL https://api.hypamoon.com/oauth/token, scopes: sites:write)

Request body

site_idstring uuid required

The site the app belongs to (from deploy_site or list_sites). Requests to /api and everything below it on that site go to the app; all other paths stay the site's static files.

namestring

A name for your own overview. Defaults to the site's name.

main_modulestring

The module with export default { async fetch(request, env, ctx) { ... } } (and optionally scheduled). Usually index.js.

allowed_hostsstring[]

Hosts the app may call with fetch(): exact names like api.example.com, or *.example.com for its subdomains. Everything else is blocked. At most 20. The Hypamoon API (for the project's data) is always allowed.

secretsstring[]

Names of secrets from the project's vault (request_secret) the app may use. The code never sees a value: it sends the header x-hypamoon-secret: <name> and Hypamoon puts the secret in the request, only to the hosts of that secret. At most 10.

varsobject

Plain settings in env, like {"CITY": "Delft"}. Never a key or password: use secrets. At most 20, names in UPPER_CASE.

databaseboolean

true gives the app its own SQL database (SQLite) as env.DB: env.DB.prepare(sql).bind(...).all(). Create and change tables with apply_app_migration. The database stays when you deploy a version without it; delete_app removes it.

fetch_pagesboolean

true turns on env.HYPAMOON.fetchPage(url) for this app (off by default; needs auth). It fetches one public web page for the signed-in user, for example to import a recipe or read a product page from any site, without listing that site in allowed_hosts: const page = await env.HYPAMOON.fetchPage(url) gives { url, status, contentType, body, truncated }, with url the final address after redirects. Only GET, http and https, text, HTML or JSON (also JSON-LD), at most 2 MB (truncated: true when cut off) and 10 seconds, at most 3 redirects. Private addresses and Hypamoon hosts are blocked. No cookies or x-hypamoon headers are sent. Each signed-in user can fetch 20 pages per hour, and the fetches count against the app's outbound budget. A refusal throws an Error with .status: 401 not signed in, 403 blocked address, 415 not text, 429 limit reached, 501 off for this app, 502 or 504 the page failed or was too slow. On an update, leave it out to keep the current setting; false turns it off.

keep_existing_modulesboolean

On an update: true keeps every running module you do not send, and replaces or adds only the modules you send (like keep_existing on deploy_site).

Response

A new version is live.

idstring uuid required
namestring required
site_idstring uuid required
urlstring required

The site; the app answers on url + /api.

api_urlstring required

Where the app's /api starts.

mode'live' | 'test' required
status'active' | 'offline' required

offline: Hypamoon took the site offline; the app does not run.

versioninteger required

The version that runs now.

allowed_hostsstring[] required
secretsstring[] required
keptstring[]

Only in the answer to a deploy of an existing app: the settings that were left out and kept from the running version, like "allowed_hosts (20)", "vars (2)", "database", "auth".

warningsstring[]

Only in the answer to a deploy: advice about the app's data, never a block. For example that export and delete per user won't cover the data (no table marked with set_table_owner_column), or tables that look like backups or copies. Tell the user in plain words and offer to fix it.

created_atstring required
updated_atstring required

Changes

No recorded changes to this operation across all 1 revision of this API.