---
title: "get app by path"
method: GET
path: "/w/{workspace}/apps/get/p/{path}"
tags: ["app"]
---

# get app by path

`GET /w/{workspace}/apps/get/p/{path}`

## Path parameters

- `workspace` string, required
- `path` string, required

## Query parameters

- `with_starred_info` boolean
- `get_draft` boolean
- `raw_app` boolean

## Response `200`

app details

- object — Overlay fields added to every "get by path" response that accepts the `get_draft` query parameter. The deployed payload is sent untouched in the response body; the authed user's saved draft for this path — whatever shape the editor wrote — is attached as the sibling `draft` field when `get_draft=true` and a draft exists. The frontend pairs the two to present diff / reset / discard UI; the server never merges them. When `no_deployed=true` there is no deployed row at this path — the response body is a best-effort stand-in synthesized from the draft, and only `draft` is canonical. Callers should disable "diff vs deployed" UI in that case.
  - `id` integer, required
  - `workspace_id` string, required
  - `path` string, required
  - `summary` string, required
  - `versions` integer[], required
  - `created_by` string, required
  - `created_at` string, date-time, required
  - `value` unknown, required
  - `policy` Policy, required
    - `triggerables` object
    - `triggerables_v2` object
    - `s3_inputs` object[]
    - `allowed_s3_keys` object[]
      - `s3_path` string
      - `resource` string
    - `execution_mode` 'viewer' | 'publisher' | 'anonymous' — Who the app's runnables execute as. Optional, and what omitting it means depends on the operation: creating an app defaults it to `publisher` (runs on behalf of the app's publisher and requires an authenticated viewer), while updating one keeps the mode the app is already deployed under. Either way `anonymous`, which makes the app publicly executable, is never assumed
    - `on_behalf_of` string
    - `on_behalf_of_email` string
    - `sandbox` boolean — Publisher opt-in to app sandbox isolation (alpha). When true the app is isolated from each viewer's Windmill session. When false/absent the app runs same-origin with the viewer's full session (the default, pre-isolation behavior).
    - `frontend_sdk_scopes` string[] — Raw apps: author-declared scopes for the frontend SDK token. Takes effect only when `sandbox` is also true — an unsandboxed bundle runs with the viewer's own session, so no token is advertised or minted for it and this list stays inert. On a sandboxed app a non-empty list lets viewers mint (after consenting) a short-lived token carrying their own identity restricted to these scopes, handed to the app bundle so `windmill-client` calls run as the viewer. Must be a subset of the server's curated allowlist (jobs:run, jobs:read, users:read, resources:read, variables:read).
  - `execution_mode` 'viewer' | 'publisher' | 'anonymous', required
  - `extra_perms` object, required
  - `custom_path` string
  - `raw_app` boolean, required
  - `bundle_secret` string
  - `labels` string[]
  - `is_draft` boolean, required
  - `draft_saved_at` string, date-time
  - `no_deployed` boolean
  - `draft` object
  - `other_drafts_users` object[] — Other workspace users (and the legacy NULL-email row, if any) with a saved draft at the same path. Populated only on the authed user's "get by path" responses for kinds the editor surfaces a fork banner for (script, flow, app, raw_app). Empty / omitted for kinds without that UI.
    - `username` string, nullable — Workspace username of the draft owner. `null` represents the legacy workspace-level (NULL-email) row. Emails never leave the server.
    - `draft_saved_at` string, date-time, required — When this user's draft was last saved (`draft.created_at`), surfaced in the fork modal as "Last updated".

---

[API](https://skmtc.net/windmill/apis/windmill-api.md) · [All operations](https://skmtc.net/windmill/apis/windmill-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/windmill/windmill-api/revisions/b007f84c1981/schema)
