Deploying

Push your app to inference shell.


Deploy

bash
1belt app deploy

Useful flags

FlagDescription
--dry-runRun validation, packaging, and upload checks without registering a new version
--metaUpdate listing fields from inf.yml only (no new version): title, description, category, and non-empty images (card, thumbnail, banner)
--stageDeploy as a staged version (not current)

After inf.yml is loaded, deploy prints a warning (not a hard error) when description is longer than the listing limit (200 characters). belt app deploy --dry-run shows the same warning; a dry run still builds and uploads the package and skips only registering the version (POST /apps). The API still rejects a new or changed description over the limit; an unchanged long description on an already-deployed app is kept until you edit the field.

Namespace

An app deploys into the namespace from inf.yml.

Namespace in inf.ymlResult
Empty, or your active workspaceDeploys into your workspace
Another namespace, and you are a memberDeploys into your own workspace (a copied inf.yml keeps its author's namespace)
Another namespace, and you are platform staffNeeds admin access. From the CLI, run belt admin elevate and approve it in the browser first; without it the deploy is refused with Deploying into namespace "…" needs admin access

Warnings

After the version is registered, the API can return warnings about the app's credentials and annotations. The CLI prints each one with ! after the deployment summary. The deploy still succeeds.

CodeWhen
readonly_broad_credentialA function marked readOnlyHint: true requires a capability that has a narrower read-only counterpart
unused_credentialEvery function declares its own credentials, and an inf.yml entry is used by none of them
missing_annotationsThe app uses credentials and a function sets neither readOnlyHint nor destructiveHint

→ Per-function credentials

JSON output

belt app deploy --json prints one result object (one per app with --all):

json
1{2  "success": true,3  "namespace": "myteam",4  "app": "my-app",5  "version": "2df033wcb89a83z8wq3hw2mkm3",6  "short_id": "2df033wc",7  "warnings": [8    { "code": "missing_annotations", "function": "delete_file", "message": "delete_file has no annotations; clients will treat it as destructive" }9  ]10}

warnings is [] when there are none. error is present only when the deploy failed.

Use --meta after editing store listing fields in Configuration, for example title, description, category, or images. Only non-empty values in your local inf.yml are sent. The app must already be deployed once.


What happens

  1. Validation — Checks required files and runs belt app doctor diagnostics (errors block deploy; warnings are shown but do not stop the build)
  2. Credential keys — For each credentials: entry with a key, the CLI checks that the capability exists (belt app credentials list). Provider-only entries (provider with secrets, no key) are not capabilities; the API validates those when the version is registered
  3. Dependencies — Installs packages locally
  4. Packaging — Bundles everything
  5. Upload — Sends to inference shell
  6. Registration — Makes it available

Run diagnostics manually before deploy:

bash
1belt app doctor          # list issues (exits 0 — report only)2belt app doctor fix      # auto-fix what it can (relative imports, missing __init__.py, GPU deps, ESM config, …)3belt app doctor --check   # exit 10 (config) when errors are found (CI gate)

Use --json with --check for machine-readable output in scripts. → CLI setup — App health

→ CLI setup


Output

code
1┌──────────────────────────────────────┐2│         deployment summary           │3├──────────────────────────────────────┤4│                                      │5│ final status: success                │6│ duration: 45s                        │7│ app: my-app                          │8│ link: https://app.inference.sh/...   │9│                                      │10└──────────────────────────────────────┘

View your app

After deploy:

  • Find it in the Grid
  • Run it from the workspace
  • Add it to agents

Update

Make changes, then deploy again:

bash
1belt app deploy

New version is created and becomes the active version unless you used --stage.

Staged deploys and promotion

belt app deploy --stage uploads a new version without making it current. Tasks and the store listing keep using the previous current version until you promote the staged one.

When you are ready to go live:

  • Workspace — open the app and set the active version under Versions
  • REST API (requires apps:write):
bash
1curl -X PUT "https://api.inference.sh/apps/{appId}/versions/{versionId}/current" \2  -H "Authorization: Bearer inf_your_api_key"

Returns the updated app object. appId and versionId are server IDs (from belt app my -l or the deploy response), not namespace/name refs.

JavaScript SDK:

typescript
1await client.apps.setCurrentVersion('app_xyz', 'ver_abc');

The Python SDK does not yet expose this helper; use the REST call above.

Runs and agent tools resolve namespace/name without a version pin to the current version.


List your apps

bash
1belt app my2belt app my -l  # Detailed list

Next

If you want programmatic access:

→ API Authentication

we use cookies

we use cookies to ensure you get the best experience on our website. for more information on how we use cookies, please see our cookie policy.

by clicking "accept", you agree to our use of cookies.
learn more.