---
title: "Create/reuse draft and replace app content"
method: PUT
path: "/v2/documents/{documentId}/draft/app"
tags: ["Apps"]
---

# Create/reuse draft and replace app content

`PUT /v2/documents/{documentId}/draft/app`

## Request

- Base URL: `https://blobsrus.omniapp.co/api`
- URL: `https://blobsrus.omniapp.co/api/v2/documents/{documentId}/draft/app`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

<Note>
  This API is currently in development and may change.
</Note>

Create or reuse the document's main draft and replace the existing app. Use the `draftIdentifier` in the response to call the [Publish draft API](/api/documents-v2/publish-draft) and publish the changes.

## Path parameters

- `documentId` string, required: Document identifier — either the URL slug (e.g. `abc123`) or the canonical workbook UUID.

## Query parameters

- `userId` string, uuid

## Request body

- AppPutBody
  - `html` string, required: The complete app HTML document. Replaces the current HTML; capped at 2 MiB of UTF-8. `maxLength` counts characters — the byte cap is what the server enforces. Every write appends an immutable revision.
  - `settings` object: When present, replaces the app settings; omitted fields take their locked-down defaults. When absent, the current settings are retained.
    - `allowClipboard` boolean: Allow the app to read from and write to the user's clipboard.
    - `allowDefaultMapProviders` boolean: Allow the app to load Omni's default map tile providers.
    - `allowDownloads` boolean: Allow the app to trigger file downloads.
    - `allowExternalNavigation` boolean: Allow the app to navigate to domains outside the `navAllowedDomains` / `safeDomains` allowlists.
    - `allowFullscreen` boolean: Allow the app to enter full screen via `requestFullscreen()` (e.g. a "Present" button).
    - `allowInternalNavigation` boolean: Allow the app to navigate within the Omni instance.
    - `externalNavOpensInNewTab` boolean: When true, external navigation opens in a new tab instead of the current one.
    - `navAllowedDomains` string[]: Domains the app is allowed to navigate to when `navAllowedDomainsEnabled` is true.
    - `navAllowedDomainsEnabled` boolean: When true, restrict navigation to the domains listed in `navAllowedDomains`.
    - `safeDomains` string[]: Domains treated as safe for embedded content when `safeDomainsEnabled` is true.
    - `safeDomainsEnabled` boolean: When true, restrict embedded content to the domains listed in `safeDomains`.

## Response `200`

Draft created or reused and app written. Use the `draftIdentifier` in the response to call the [Publish draft API](/api/documents-v2/publish-draft) and publish the changes.

- AppPutResponse
  - `identifier` string, required: Published document identifier the draft targets.
  - `draftIdentifier` string, required: Identifier of the draft the patch was applied to.
  - `name` string, required: Document name.
  - `description` string, nullable, required: Document description.
  - `app` AppState, required
    - `settings` AppSettings, required: The app's sandbox settings. A write replaces the whole object; omitted fields use their locked-down defaults. Host lists are normalized (deduped, invalid or Omni-owned hosts dropped) before they are stored.
      - `allowClipboard` boolean: Allow the app to read from and write to the user's clipboard.
      - `allowDefaultMapProviders` boolean: Allow the app to load Omni's default map tile providers.
      - `allowDownloads` boolean: Allow the app to trigger file downloads.
      - `allowExternalNavigation` boolean: Allow the app to navigate to domains outside the `navAllowedDomains` / `safeDomains` allowlists.
      - `allowFullscreen` boolean: Allow the app to enter full screen via `requestFullscreen()` (e.g. a "Present" button).
      - `allowInternalNavigation` boolean: Allow the app to navigate within the Omni instance.
      - `externalNavOpensInNewTab` boolean: When true, external navigation opens in a new tab instead of the current one.
      - `navAllowedDomains` string[]: Domains the app is allowed to navigate to when `navAllowedDomainsEnabled` is true.
      - `navAllowedDomainsEnabled` boolean: When true, restrict navigation to the domains listed in `navAllowedDomains`.
      - `safeDomains` string[]: Domains treated as safe for embedded content when `safeDomainsEnabled` is true.
      - `safeDomainsEnabled` boolean: When true, restrict embedded content to the domains listed in `safeDomains`.
  - `warnings` string[]: Included only when non-blocking warnings are encountered when creating/updating an app. The write itself succeeded.

## Other responses

- `400`: Invalid request body (unknown field, empty, or `html` exceeds the cap of 2 MiB).
- `401`: Authentication required.
- `403`: Insufficient permissions: no write access to the document, apps not enabled for the organization, or (a user-scoped key, or an organization key acting as `userId`) the role does not allow creating apps. Also returned when a user-scoped key passes `userId` naming a different member, or when `userId` names an embed user with no live embed session.
- `404`: Document not found, `documentId` names a draft rather than a published document, `userId` names a membership outside the organization, or `userId` names a member who hasn't accepted their invitation.
- `405`: Method not allowed.
- `422`: The document is a dashboard, not an app.

## Changes

- **2026-11-03** `43290040f88f`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/omni/apis/omni-api/changes/v2/documents/:documentId/draft/app/put.md)

---

[API](https://skmtc.dev/omni/apis/omni-api.md) - [All operations](https://skmtc.dev/omni/apis/omni-api/llms.txt) - [OpenAPI document](https://skmtc.dev/omni/apis/omni-api/revisions/43290040f88f?raw)
