---
title: "Import a previously exported app manifest as a new app (spec B3.2 Portability)"
method: POST
path: "/v1/apps/import"
tags: ["Apps"]
---

# Import a previously exported app manifest as a new app (spec B3.2 Portability)

`POST /v1/apps/import`

## Request

- Base URL: `https://api.talonic.com`
- URL: `https://api.talonic.com/v1/apps/import`
- Auth: HTTP bearer

Creates the app then saves `content` as its draft, through the same create+saveDraft path as POST /v1/apps/{id}/duplicate. `mode` defaults from `content.mode` when the body omits it. Counterpart to GET /v1/apps/{id}/export.

## Request body

- object
  - `slug` string, required
  - `display_name` string, required
  - `mode` 'rules' | 'assisted' | 'external'
  - `content` object, required
  - `export_version` 1, required

## Response `201`

The created app's manifest plus the saved draft version.

- object
  - `app` AppManifest: An app as humans and agents both see it (docs/APPS-SPEC.md §B1.2). A `hosted` app's document is discovered at `/.well-known/talonic-app.json` first, then `/manifest.json` (`manifest_path` says which one answered); its `requires[]` slots are referenced elsewhere in the manifest as `$requires.<alias>` and bound to workspace resources at install (`POST .../install` `bindings`).
    - `app_id` string: Stable public id (app_ prefix).
    - `id` string, uuid
    - `slug` string
    - `display_name` string
    - `version` integer, nullable
    - `content_hash` string, nullable
    - `mode` 'rules' | 'assisted' | 'autonomous' | 'external'
    - `enabled` boolean
    - `contract` object, nullable
      - `reads` string[]
      - `acts` string[]
    - `output_contract` object, nullable: JSON Schema 2020-12 the decision validates against.
    - `input_schema` object
    - `triggers` object, nullable
    - `thresholds` object, nullable
    - `fallback` 'rules' | 'hold' | 'none', nullable
    - `endpoints` object
      - `mcp` string
      - `rest` string
      - `surface` string: The installed external service's UI. The one install-derived value a manifest carries - read-only, absent when the app is not installed.
    - `surface` object: How the app's own UI may be hosted, from the ACTIVE version's manifest with the defaults applied (a manifest with no surface block reads as embed link, scopes [apps:read], context []). A draft never changes it.
      - `embed` 'iframe' | 'link': iframe = hosted inside the shell; link = opened in its own tab.
      - `scopes` string[]: OAuth scopes an embedded session carries; a subset of the pre-consentable set (apps:read, apps:operate, records:write, identity:read).
      - `context` string[]: What the shell shares over the handshake (theme, locale, role).
    - `required_grants` object[]: The capability claim an owner approves at install (§B13.1); disclosed BEFORE the service key is minted.
      - `kind` string
      - `id` string: A resource id, `*`, `self`, or `$requires.<alias>`.
      - `access` 'read' | 'act' | 'write'
    - `subscriptions` object[]: Outbox events the active version subscribes to, with the defaults applied.
      - `event` string
      - `match` object
    - `subscriptions_endpoint` string, nullable: Where events are delivered; null when the manifest subscribes to nothing.
    - `source` 'pushed' | 'hosted': pushed = draft + publish; hosted = fetched from manifest_url.
    - `manifest_url` string, nullable
    - `last_fetch_at` string, date-time, nullable
    - `last_fetch_error` string, nullable: Null when the last hosted fetch succeeded; the config page offers Refresh instead of a draft editor while this is set.
    - `identity` AppManifestIdentity: The vendor's self-declared identity block (docs/APPS-SPEC.md §B1.2). Required on a hosted manifest; informational on a pushed one, where the platform's own app row and content hash remain the identity of record.
      - `name` string
      - `display_name` string, nullable
      - `description` string, nullable
      - `version` string, nullable
      - `homepage` string, nullable
      - `icon` string, nullable
    - `requires` AppRequirementSlot[]
      - `alias` string
      - `kind` string: AppResourceType, e.g. data_product, reference_table, source_connection, app, spec, pipeline, document_source, app_run_set, review.
      - `access` 'read' | 'act' | 'write'
      - `purpose` string: One sentence the install disclosure shows.
      - `optional` boolean
      - `scope` 'self': 'self' binds the slot to the app itself - admissible only on a `review` slot (any access) or an `app` slot with access `act` - so it needs no owner choice and never appears in `bindings`.
    - `allowed_origins` string[]: Origins the manifest's host vouches for, beyond the manifest's own origin (the implicit default when empty). A hosted manifest's `subscriptions_endpoint` and `surface.url` must lie inside this set.
  - `draft` object
    - `version` integer
    - `status` string
    - `content_hash` string

## Other responses

- `409`: The request conflicts with the current resource state.
- `422`: The request is well-formed but violates the declared task contract.

---

[API](https://skmtc.dev/talonic/apis/talonic-api.md) · [All operations](https://skmtc.dev/talonic/apis/talonic-api/llms.txt) · [OpenAPI document](https://skmtc.dev/talonic/apis/talonic-api/revisions/678fe5f8c9c3?raw)
