# Apps

Apps (applications) are applets that have been packaged to be standalone executables that are versioned and can be *published* to make them available to other users. Apps can be configured to be open-source or proprietary.

Apps are published in a global app namespace, and multiple versions can be created for a single app name. Once an app name is claimed by a developer, other developers cannot create new apps that use the same name unless they are also listed as developers of the same app name. The app name continues to be claimed even after all app versions have been deleted.

Developers can publish versions of the app and control the list of authorized users, or the accounts that can find and run the app. If you are interested in making an app available to *all* users of the DNAnexus Platform, contact [DNAnexus Support](mailto:support@dnanexus.com).

Apps can be *installed* by any of their authorized users. This is used as merely a bookmarking utility. In the future, proprietary apps may require installation to agree to a billing schedule or a set of terms of service.

Apps are created from existing applets. To create an app, a user (developer) specifies the applet and additional metadata, including the name for the app and information on whether and how they want to be compensated by users installing and running the app in their accounts. Once created, the app is only visible to the user who created it, so it can be tested. If the developer is satisfied, they can publish the app, optionally specifying additional tags (which are similar to a version), and the app becomes visible to all users under the combination of its name and aliases (version and attached tags).

Apps are launched in the same way as applets, and execute jobs the same way applets do. Unlike applets, apps must have both input and output specifications and so can only be created from applets that have both the fields `inputSpec` and `outputSpec`.

## App versioning and publishing

When you create an app, it gets both a unique ID (like "app-xxxx") and an alias in the format `app-<name>/<version>`, such as `app-micromap/0.0.1`. Before you publish an app version, you can still update it (including its code), but only you and other developers of the same app can see it. Once you claim an app name, only developers listed for that app can create new versions with the same name.

Each app version can run in a specific set of [regions](https://documentation.dnanexus.com/developer/api/regions), called the **enabled regions**. You set these regions when you create the app version, and they cannot be changed later.

When you publish an app using the [`/app-xxxx/publish`](#api-method-app-xxxx-yyyy-publish) API method, the version becomes locked and available to authorized users. You can optionally add tags when publishing. Users can then access the app using either the version number (`app-micromap/0.0.1`) or any tags you've assigned (`app-micromap/<tag>`).

Tags are reusable across versions. If you publish a new version with an existing tag, that tag points to the new version instead. However, all previously published versions remain accessible by their version number unless explicitly deleted.

Publishing an app makes it visible only to users on the authorized users list. You can change this list at any time, and it applies to all versions of the app (past and future).

You can mark app versions as deleted using the `/app-xxxx/publish` API method. Deleted app versions can still be described (the response shows they're deleted), but they cannot be run.

## App Workspace and Containers

Like applets, apps receive a container to use as a temporary workspace, whose ID is available in the `workspace` field of the describe API method of each job in the app's execution. The semantics of this workspace are identical to those of the applet workspace.

Besides the temporary workspace, apps have access to two more types of containers:

* The resources containers, which can be used to store objects needed by the app. One resources container is maintained in each region in which the app may be run. These containers are created at app creation time and remain persistent while the app object exists. The resources containers belong to the app developer. When running a job in a certain region, the resources container of the corresponding app *in that region* is read-only to the job, and it is not accessible to the user executing the app. A container's ID is available in the `resources` field of the describe API method of each job in the app's execution.
  * When creating an app, the contents of the resources container can be specified through the `resources` parameter.
* The project cache container. This container is attached to the project from which the user has launched the app, and is for caching data useful for subsequent executions of the app. The cache is shared among all instances of this app running in this project, **unless** the project has been marked as PROTECTED. If the project has the PROTECTED flag set, then each time the app is run, it gets a fresh project cache container that is destroyed on successful completion of the job. The project cache ID is available through the job property `projectCache`. Project members may access or delete objects in the container at any time. The app should be able to tolerate this when creating or accessing objects in it. The cache is not visible to the app developer.

For all types of containers, the job can specify the workspace ID in place of a project ID when performing API relating to data manipulation.

The container IDs to these two types of containers are provided to jobs via the following environment variables:

* `DX_RESOURCES_ID`: a string containing the container ID of the job's resources container.
* `DX_PROJECT_CACHE_ID`: a string containing the container ID of the job's cache for the project context.

Unlike the temporary app workspace, the global resources container and project cache are not deleted when an app finishes. For billing purposes, data in the resources container is the responsibility of the user or organization specified as `billTo` for the app. Data in the project caches belongs to the project it's attached to.

The app also has read access to any objects which are listed in projects with public view access.

Unlike applets, apps by default do not have VIEW access to data in the project they were launched from. Apps' default data access is limited to:

* Data explicitly specified by the user as inputs
* Data available in the resources container or the project cache
* Data in public projects
* However, if access.project or access.allProjects flags are set when calling [`/app/new`](#api-method-app-new), the app has access equal to that of the user in the project or everywhere on the platform, respectively. (When the user launches an app with these flags set, they are presented with a dialog asking them to confirm the elevated privileges.)

## Developers

Developers are users who are authorized to create a new version of an app with a particular name. When a user creates the first app with a particular name, that user is initially the sole developer. Developers can also add and remove other users as developers, modify unpublished apps, publish the apps, change who can describe and run the app, and view the resources of any version of the app under development.

In general, jobs cannot call methods which require developer permissions unless they have been given the permissions to do on behalf of the user who ran the job. See [Access Requirements](https://documentation.dnanexus.com/developer/api/io-and-run-specifications#access-requirements) for how to request that a particular app or applet always be given developer access.

## Categories

Developers can add categories to an app. This applies the categories to all versions of the app. This is true even when the URL refers to a particular app version. A list of categories is specially displayed in the UI, and developers are encouraged to use these categories to make their apps more accessible. Developers can choose any categories to describe their apps without restrictions, and apps are searchable by their categories.

## App API Method Specifications

### API method: `/app/new`

#### Specification

Creates an app.

A read-only container for the app's resources is created and initialized as specified by the `resources` option. Also, the applet object and the resources specified in `bundledDepends` of the run specification are cloned into it. Developers of the app have VIEW access to the resources container.

If the app is being created for the first time, then the `billTo` of the app defaults to the `billTo` of the requesting user (this is the same default billing account for new projects created by the user) unless otherwise specified. This same billing account **must** be used for all subsequent versions created under the same app name.

When you create the first app with a particular name, you become its sole developer. If you try to create an app with a name that already exists on the Platform, you must be listed as a developer for that app name. Otherwise, the request returns a `PermissionDenied` error, even if the existing app is not available in your organization. This restriction persists even after all versions of an app have been deleted.

If this app version is being initialized from another app version (via `initializeFrom`), then the set of enabled regions of this app version is the same as that of the app from which this app is being initialized. Otherwise, `regionalOptions` is required and the set of enabled regions of this app version is the keys of the `regionalOptions` mapping. The set of enabled regions is fixed once the app version is created.

#### Inputs

* `regionalOptions` **mapping** (required if `initializeFrom` is not specified, optional otherwise) Configurations for all [regions](https://documentation.dnanexus.com/developer/api/regions) in which this app is enabled. Region examples include `aws:us-east-1` and `azure:westus`.
  * **key** — Name of a region in which this app may be run.
  * **value** **mapping** — Configuration of this app in the corresponding region, with the following key-value pairs:
  * `applet` **string** (required if `initializeFrom` is not specified, prohibited otherwise) ID of the underlying applet of this app in the corresponding region. The applet must have both input and output specifications. Also, the I/O specifications of all specified applets must be equal. The run specifications may differ in certain fields, to help the use of different resources across different regions. For more information, refer to [Run Specification](https://documentation.dnanexus.com/developer/api/io-and-run-specifications#run-specification). If `applet` is specified for one region in `regionalOptions`, it must be specified for *all* regions.
  * `resources` **string or array of strings** (optional) Either the string ID of a project whose contents are copied into the corresponding resources container of this app, or an array of data object IDs that are cloned into the root folder of that resources container. If `resources` is specified for one region in `regionalOptions`, it must be specified for *all* regions.

    If `regionalOptions` and `initializeFrom` are both specified, then `regionalOptions` must contain all regions, and only those regions, in which `initializeFrom` is enabled. That is, the set of regions in which this app is enabled must match the regions in which `initializeFrom` is enabled.
* `initializeFrom` **string** (required if `applet` is not provided, cannot be present otherwise) An app identifier from which to use as default values for all the fields. If any of the other fields are given, they override the value stored for the app object. The following exceptions apply:
  * The `version` field must be provided for the new app object to be created
  * If `resources` is not provided, the resources container of the new app object is a cloned copy of the `initializeFrom` app object's resources container. It is not functionally the same as providing the same value of the field `resources` as before (the project contents or data objects may have changed in the meantime).
* `name` **string** (optional if `initializeFrom` is an app identifier) Name for the app, for example, `micromap`. Must match `/^[a-zA-Z0-9._-]+$/` and cannot start with the prefix "app-". If this name already exists within the global namespace on the Platform, you must be listed as a developer of the app. See [App versioning and publishing](#app-versioning-and-publishing).
* `title` **string** (optional) Title for the app, for example "Micro Map". If not provided, inherited from `applet` or `initializeFrom` as applicable. If no (or an empty) title is found from those options, then `name` is used as the title.
* `summary` **string** (optional) A one-line description for the app. If not provided, inherited from `applet` or `initializeFrom` as applicable.
* `description` **string** (optional) A longer description of the app, formatted in Markdown, to be displayed on the app's detail page. If not provided, inherited from `applet` or `initializeFrom` as applicable.
* `developerNotes` **string** (optional) More advanced documentation for the app. If not provided, inherited from `applet` or `initializeFrom` as applicable.
* `details` **array or mapping** (optional) Any conformant JSON, which means a JSON object or array, per RFC4627. This is stored with the app.
* `version` **string** (required) A nonempty freeform string representing the app's version. It must be unique from any existing app with the same name (string provided must match `/^[a-zA-Z0-9._+-]+$/`). See [App versioning and publishing](#app-versioning-and-publishing).
* `openSource` **boolean** (optional) Whether the contents of this app version's resources container should be viewable by all members of the app's developers and authorized users. Defaults to `false`.
* `ignoreReuse` **boolean** (optional) If true, [Smart Reuse](https://documentation.dnanexus.com/user/running-apps-and-workflows/job-reuse) is disabled for this app. When false or omitted, the app allows Smart Reuse provided the organization has the feature enabled. Defaults to `false`.
* `access` **mapping** (optional) Access requirements as described in [I/O and Run Specifications](https://documentation.dnanexus.com/developer/api/io-and-run-specifications#access-requirements).
* `billTo` **string** (optional) ID of the entity to which all costs associated with this app are billed. This must be the ID of the requesting user or an org of which the requesting user is a member with `allowBillableActivities` permission. If this is a subsequent version of an existing app, then `billTo` **must** be the same as `billTo` of the existing app. Defaults to the `billTo` of the requesting user.
* `nonce` **string** (optional) Unique identifier for this request. Ensures that even if multiple requests fail and are retried, only a single app is created. For more information, see [Nonces](https://documentation.dnanexus.com/developer/api/nonces).
* `treeTurnaroundTimeThreshold` **integer** (optional) The turnaround time threshold in seconds for trees (specifically, root executions) that run this executable. See [Job Notifications](https://documentation.dnanexus.com/user/running-apps-and-workflows/job-notifications) for more information about turnaround time and managing job notifications.
  * Defaults to the lowest `treeTurnaroundTimeThreshold` field across the `regionalOptions` applets if the `billTo` of the app has the `jobNotifications` feature switch and `initializeFrom` is N/A. If this condition is not met, defaults to the `treeTurnaroundTimeThreshold` field of the `initializeFrom` app if the `billTo` of the app has the `jobNotifications` feature switch and `initializeFrom` is not N/A. Otherwise, defaults to N/A (positive infinity).

{% hint style="info" %}
A license is required to use the `jobNotifications` feature. Contact [Sales](mailto:sales@dnanexus.com) to enable `jobNotifications`.
{% endhint %}

Deprecated fields:

* `applet` **string** (required if neither `initializeFrom` nor `regionalOptions[r].applet` (for any region name `r`) is specified) ID of the applet from which the app is created. The applet must have both input and output specifications. This field is ignored if `regionalOptions` is specified. If `applet` is specified, then `regionalOptions` is not required above. If neither `regionalOptions[r].applet` (where `r` is a region name) nor `initializeFrom` is specified, then the enabled regions of this app are the region of the specified applet.
* `resources` **string or array of strings** (optional) Either a string containing the ID of a project whose contents are copied into a resources container, or an array of data object IDs, which are all cloned into the root folder of the resources container. All specified objects must reside in the same region as the applet denoted by `applet`. This field is ignored if `regionalOptions` is specified.

#### Outputs

* `id` **string** ID of this app (of the form `app-<hash>`).
* `resourcesByRegion` **mapping** The resource containers created for this app.
  * **key** — Region name such as `aws:us-east-1` or `azure:westus`.
  * **value** **string** — ID of the resources container of this app in the corresponding region.

Deprecated fields:

* `resources` **string** Arbitrarily selected ID of one of the resources containers of this app.

#### Errors

* InvalidInput
  * If `regionalOptions` and `initializeFrom` are both specified, then `regionalOptions` must contain exactly the regions in which the app version denoted by `initializeFrom` is enabled.
  * If `regionalOptions` is specified, then it must be non-empty.
  * If `applet` (or `resources`) is specified for one region in `regionalOptions`, then it must be specified for *all* regions.
  * The applet denoted by `regionalOptions[r].applet` (where `r` is a region name) must reside in the region denoted by `r`.
  * Only one of `initializeFrom` or `applet` may be specified.
  * `version` (if specified) is already in use by an existing version of this app, or is a `tag` for a published version of this app.
  * The applet (if specified) contains bundled dependencies that reside in regions that differ from the region in which the applet was created.
  * If `regionalOptions[r].applet` (where `r` is a region name) is specified for at least one `r`, then the input, output, and run specifications of all specified applets must be equivalent, as defined above.
  * If `regionalOptions[r].resources` (where `r` is a region name) is specified for at least one `r`, then all objects denoted by `r.resources` must reside in the region denoted by `r`.
  * If `resources` is an array of objects, then all objects must reside in the same region as the one in which this app is being created.
  * If `resources` is a project id, then the project must reside in the same region as the one in which this app is being created and the project can contain any object that is not in `live` status.
  * A `nonce` was reused in a request but other inputs had changed signifying a new and different request
  * A `nonce` may not exceed 128 bytes
  * `instanceType` and `instanceTypeSelector` keywords are mutually exclusive
  * `instanceTypeSelector` and `clusterSpec` keywords are mutually exclusive
  * The requested instance types are unavailable (no price has been contractually set for the `billTo` organization)
* PermissionDenied
  * VIEW access is required to the applet and to all required objects, or the invoking user must be a developer of the app specified in `initializeFrom`
  * VIEW access to the project specified by `resources` (if provided) is required
  * The app `name` is already claimed by another developer. If the `name` provided is already in use by an existing app on the Platform, you must be listed as a developer for that app. This applies even if the existing app is not available in your organization and even if all versions have been deleted.
  * A full scope token or one with developer access is required
  * `billTo` must be either the ID of the requesting user or the ID of an org of which the requesting user is a member with `allowBillableActivities` permission
  * The `billTo` of the invoking user is an org and the user is no longer a member of that org
  * The region of the original app or applet that this app was created from must be one of the `permittedRegions` of this app's `billTo`
  * The `billTo` of the app is not licensed to use `jobNotifications`. Contact [DNAnexus Sales](mailto:sales@dnanexus.com) to enable `jobNotifications`.
  * `instanceTypeSelector` keyword requires the `billTo` to have the `instanceTypeSelector` license feature
  * The project context is associated with a [TRE](https://documentation.dnanexus.com/developer/api/trusted-research-environments). Creating new apps is not allowed in TRE projects. See [Non-Configurable Restrictions](https://documentation.dnanexus.com/developer/trusted-research-environments#non-configurable-restrictions).
* SpendingLimitExceeded
  * The `billTo` has reached its spending limit
* OrgExpired
  * The `billTo` organization has expired

### API method: `/app-xxxx[/yyyy]/update`

#### Specification

Updates the app version with any fields that are specified below.

If either `regionalOptions[r].applet` (where `r` is a region name) or `regionalOptions[r].resources` are specified, then, for each region in which this app version is enabled, the previous resources container is emptied of its contents before initializing it again with the corresponding applet, its bundled dependencies, and the contents of the user-specified `regionalOptions[r].resources` field. If `regionalOptions[r].applet` is provided but `regionalOptions[r].resources` is not, this has the effect of specifying the empty list for `regionalOptions[r].resources`.

#### Inputs

* `regionalOptions` **mapping** (optional) Configurations for all regions in which this app is enabled, such as `aws:us-east-1` and `azure:westus`. This mapping must contain a key for each region in which this app version is enabled.
  * **key** — Name of a region in which this app may be run.
  * **value** **mapping** — Configuration of this app in the corresponding region, with the following key-value pairs:
  * `applet` **string** (optional) ID of the new underlying applet of this app in the corresponding region. The applet must have both input and output specifications. Also, the input, output, and run specifications of all specified applets must be [equivalent](https://documentation.dnanexus.com/developer/api/running-analyses/io-and-run-specifications). If `applet` is specified in one region in `regionalOptions`, it must be specified for *all* regions.
  * `resources` **string or array of strings** (optional) Either the string ID of a project whose contents are copied into the existing resources container of this app in the corresponding region, or an array of data object IDs that are cloned into the root folder of that resources container. The existing resources container's ID remains unchanged. If `resources` is specified for one region in `regionalOptions`, it must be specified for *all* regions.
* `title` **string** (optional) The app's title, for example, "Micro Map".
* `summary` **string** (optional) The app's summary.
* `description` **string** (optional) The app's description.
* `developerNotes` **string** (optional) Advanced documentation for the app.
* `details` **array or mapping** (optional) Any conformant JSON, which is defined as a JSON object or array per RFC4627. This is stored with the app.
* `openSource` **boolean** (optional) Whether the contents of this app version's resources container should be viewable by all members of the app's developers and authorized users.
* `access` **mapping** (optional) Access requirements as described in the [I/O and Run Specifications](https://documentation.dnanexus.com/developer/api/io-and-run-specifications#access-requirements).

Deprecated fields:

* `applet` **string** (optional) Recreate the app using the provided applet ID. This field is ignored if `regionalOptions` is specified.
* `resources` **string or array of strings** (optional) Either a string containing the ID of a project whose contents are copied into a resources container, or an array of data object IDs, which are all cloned into the root folder of the resources container. The resource container's ID does not change. This field is ignored if `regionalOptions` is specified.

#### Outputs

* `id` **string** ID of the app (of the form "app-\<hash id>").

#### Errors

* InvalidInput
  * If `regionalOptions` is specified, then it must contain exactly the regions in which this app version is enabled and the project can contain any object that is not in `live` status.
  * If `applet` (or `resources`) is specified for one region in `regionalOptions`, then it must be specified for *all* regions.
  * The applet denoted by `regionalOptions[r].applet` (where `r` is a region name) must reside in the region denoted by `r`.
  * If `regionalOptions[r].applet` (where `r` is a region name) is specified for at least one `r`, then the input, output, and run specifications of all specified applets must be equivalent, as defined above.
  * If `regionalOptions[r].resources` (where `r` is a region name) is specified for at least one `r`, then all objects denoted by `r.resources` must reside in the region denoted by `r`.
  * `instanceType` and `instanceTypeSelector` keywords are mutually exclusive
  * `instanceTypeSelector` and `clusterSpec` keywords are mutually exclusive
  * The requested instance types are unavailable (no price has been contractually set for the `billTo` organization)
* ResourceNotFound (the specified app does not exist)
* InvalidState (the app has already been published)
* PermissionDenied
  * User must be the user who created the app
  * A full scope token or one with developer access is required
  * `instanceTypeSelector` keyword requires the `billTo` to have the `instanceTypeSelector` license feature

### API method: `/app-xxxx[/yyyy]/addTags`

#### Specification

Adds the specified tags to this version of the app. If any of the tags are already present, no action is taken for those tags. If any of the tags are already in use by different versions of this app, those tags are removed from the other versions and added to this version. This maintains the invariant that any tag only applies to a single version of an app.

Example: you have two published versions of an app, app-foo/1.0.0 and app-foo/2.0.0, and version 1.0.0 is the current default, you can make version 2.0.0 the default by calling `/app-foo/2.0.0/addTags` with input `{"tags":["default"]}`

#### Inputs

* `tags` **array of strings** (required) List of tags to add to the specified app version.

#### Outputs

* `id` **string** ID of the app (of the form "app-\<hash id>").

#### Errors

* ResourceNotFound
  * The specified app does not exist
* InvalidInput
  * Input is not a hash, `tags` is not present or is not an array of nonempty strings, a tag is equal to an existing version, whether published or not
* PermissionDenied
  * User must be a developer of the app
  * A full scope token or one with developer access is required
* InvalidState
  * The app object has already been deleted

### API method: `/app-xxxx[/yyyy]/removeTags`

#### Specification

Remove the requested aliases of "app-\<name>/\<tag>"

#### Inputs

* `tags` **array of strings** (required) List of tags to remove from all versions of the app.

#### Outputs

* `name` **string** App name modified, such as "bwa".

#### Errors

* ResourceNotFound
  * The specified app name does not exist
* InvalidInput
  * Tnput is not a hash, `tags` is not present or is not an array of nonempty strings, a tag is equal to an existing version, or the tag includes the special tag "default"
* PermissionDenied
  * User must be a developer of the app
  * A full scope token or one with developer access is required

### API method: `/app-xxxx[/yyyy]/publish`

#### Specification

This version of the app becomes discoverable by authorized users on the Platform and can be accessed by object ID, "app-\<name>/\<version>", and "app-\<name>/\<tag>" if the app object also has tags. The app is closed to further updates by the developers.

#### Inputs

* `makeDefault` **boolean** (optional) Whether this app should take on the "default" tag, removing it from whichever app version was previously marked as "default". Defaults to `false`.

#### Outputs

* `id` **string** ID of the app (of the form "app-\<hash id>").

#### Errors

* PermissionDenied
  * User must be the user who created the app
  * A full scope token or one with developer access is required

### API method: `/app-xxxx[/yyyy]/describe`

#### Specification

Describe the app.

#### Inputs

* `fields` **mapping** (optional) Restrict the output of this method to have only the provided keys in this field. The `inputSpec` and `outputSpec` fields can be further customized as well.
  * **key** — Output field. See the "Outputs" section below for valid values here.
  * **value** **boolean or mapping** — A boolean value indicates whether to include the output field. For `inputSpec` and `outputSpec`, then the value may be a mapping with key/values restricting the fields returned for each input or output parameter specification. In such a case, the key/values must be:
    * **key** — Field name of an I/O parameter descriptor, for example, "name" or "choices" (see the documentation on [input and output specifications](https://documentation.dnanexus.com/developer/api/running-analyses/io-and-run-specifications) for all possible choices).
    * **value** **boolean** — Whether to include the field for all I/O parameter descriptors.

#### Outputs

* `id` **string** ID of the app (of the form "app-\<hash id>").
* `class` **string** The value "app".
* `billTo` **string** ID of the user/organization that owns this app's name (and is billed for the storage incurred by the app versions).
* `name` **string** Name of the app.
* `version` **string** Version of the app.
* `aliases` **array of strings** List that includes the version and all tags of this app by which the app can be addressed using "app-\<name>/\<alias>".
* `createdBy` **string** ID of the user who created the app.
* `created` [**timestamp**](https://documentation.dnanexus.com/developer/api/..#data-types) When the app was created.
* `modified` [**timestamp**](https://documentation.dnanexus.com/developer/api/..#data-types) When this app was last modified.
* `installed` **boolean** Whether the requesting user has installed the app.
* `openSource` **boolean** Whether the app is open-source (and its `resources` container is accessible by all members of `authorizedUsers`).
* `ignoreReuse` **boolean** Whether job reuse is disabled by default for the app.
* `deleted` **boolean** Whether the app has been deleted.
* `installs` **integer** Number of current installations (includes developers).
* `isDeveloperFor` **boolean** Whether the requesting user has developer permissions for the app AND the token provided has full scope or has developer access.
* `authorizedUsers` **array of strings** List of user and org IDs representing who can describe and run this app. If the string "PUBLIC" is present, then all users can access this app.
* `regionalOptions` **mapping** The regional configurations for this app.
  * **key** — Region name such as `aws:us-east-1` or `azure:westus`. The existence of a region here indicates that this app may be run in this region, and absence of a region indicates otherwise.
  * **value** **mapping** — Mapping of the configuration of this app in the corresponding region, with the following key-value pairs:
    * `applet` **string** ID of the underlying applet of this app in the corresponding region.
    * `resources` **string** ID of the resources container of this app in the corresponding region.
    * `pricingPolicy` **mapping** (nullable) Returns `null` if the app is billed based on the compute cost in the region, or if the app has been deleted. Otherwise, it is a mapping that describes how the app is billed. This field can only be set by DNAnexus administrators. Keys/values may include:
      * `unit` **string** The unit that is billed. This could be "run" for a single run of the app or another appropriate billing unit.
      * `unitPrice` **number** Price in dollars of the unit to be billed.
* `httpsApp` **mapping** HTTPS app configuration.
  * `shared_access` **string** HTTPS access restriction for this job.
  * `ports` **array of integers** Ports that are open for inbound access.
  * `dns` **mapping** DNS configuration for the job.
    * `hostname` **string** If specified, the URL to access this job in the browser is `https://hostname.dnanexus.cloud` instead of the default `https://job-xxxx.dnanexus.cloud`.

If the app is published:

* `published` [**timestamp**](https://documentation.dnanexus.com/developer/api/..#data-types) Time at which this app was published.

If the app has not been deleted:

* `title` **string** Freeform name.
* `summary` **string** A one-line description of the app.
* `description` **string** A long description of the app, formatted in Markdown, to be displayed on the app's detail page.
* `details` **mapping or array** Contents of the app's details.
* `categories` **array of strings** List of categories the app belongs to.
* `developerNotes` **string** More advanced documentation for the app.
* `lineItemPerTest` **boolean** Whether the final invoice includes a line item for each execution of this app. The text of the line is determined by the value given as `invoiceMetadata` when calling [`/app-xxxx[/yyyy]/run`](#api-method-app-xxxx-yyyy-run) if present and otherwise contains some basic metadata about the job (including the job's name, ID, and name of the app run). At this time, this field can only be set by DNAnexus administrators. Defaults to `false`.
* `access` **mapping** The access requirements of the app.
* `inputSpec` **array of mappings** The input specification of the app.
* `outputSpec` **array of mappings** The output specification of the app.
* `dxapi` **string** The version of the API used by the encapsulated applet.
* `runSpec` **mapping** The run specification of the app, without the `code` field (use the [`/app-xxxx/get`](#api-method-app-xxxx-yyyy-get) method to retrieve the source code).

The following fields are included by default (but can be disabled using fields):

* `treeTurnaroundTimeThreshold` **integer** (nullable) The turnaround time threshold (in seconds) for trees (specifically, root executions) that run this executable. See [Job Notifications](https://documentation.dnanexus.com/user/running-apps-and-workflows/job-notifications) for more information about turnaround time and managing job notifications.

{% hint style="info" %}
A license is required to use the `jobNotifications` feature. Contact [DNAnexus Sales](mailto:sales@dnanexus.com) to enable `jobNotifications`.
{% endhint %}

Deprecated fields:

* `region` **string** Arbitrarily selected name of one of the regions in which this app may be run.
* `applet` **string** ID of the underlying applet of this app in `region`.
* `resources` **string** ID of the resources container of this app in `region`.
  * Only present when the app has not been deleted.

#### Errors

* InvalidInput
  * Input is not a hash, or `fields` if present, is not a hash or has a non-boolean key
* ResourceNotFound
  * The specified app does not exist
* PermissionDenied
  * The requesting user must be represented in the access list or must be one of the app's developers. If the latter, a full scope token or one with developer access is required
  * If the app is unpublished, the requesting user must be one of the app's developers, and a full scope token or one with developer access is required

### API method: `/app-xxxx[/yyyy]/install`

#### Specification

Installs the app into the user's account. For apps that do not require additional terms of service or billing agreements, this serves as a bookmarking functionality. Once installed, the user can run any version of the app.

#### Inputs

* None

#### Outputs

* `name` **string** The app name, such as "bwa".

#### Errors

* InvalidState
  * App object specified has been deleted or is not yet published
* PermissionDenied
  * The requesting user must be represented in the access list or must be one of the app's developers. If the latter, a full scope token is required
  * If the app is unpublished, the requesting user must be one of the app's developers, and a full scope token is required

### API method: `/app-xxxx[/yyyy]/uninstall`

#### Specification

Uninstalls the app from the user's account. If it was not originally installed or the app does not (or no longer) exist, then this does not throw an error.

Developers can uninstall an app, but they can still run it by being a developer.

#### Inputs

* None

#### Outputs

* `name` **string** The app name, such as "bwa".

#### Errors

* PermissionDenied
  * The requesting user must be represented in the access list or must be one of the app's developers. If the latter, a full scope token is required
  * If the app is unpublished, the requesting user must be one of the app's developers, and a full scope token is required

### API method: `/app-xxxx[/yyyy]/get`

#### Specification

Returns the full specification of the app along with the usual fields returned in [`/app-xxxx/describe`](#api-method-app-xxxx-yyyy-describe).

#### Inputs

* Same as for `/app-xxxx/describe`

#### Outputs

* Same as the output for `/app-xxxx/describe`, with the following exception:
* `runSpec` **mapping** The full run specification of the app, including the field `code` containing the source code.

#### Errors

* InvalidInput
  * Input is not a hash, or `fields` if present, is not a hash or has a non-boolean key
* ResourceNotFound
  * The app does not exist
* InvalidState
  * The app has been deleted
* PermissionDenied
  * Requestor must have VIEW access into the resources container. This means you must be either a developer of the app or a job running the app

### API method: `/app-xxxx[/yyyy]/run`

#### Specification

Run the specified app.

#### Inputs

* `name` **string** (optional) Name for the resulting job.
  * Defaults to the app's title if set, otherwise the app's name.
* `input` **mapping** (optional) Input that the app is launched with.
  * **key** — Input field name (as it appears in the input specification of the app).
  * **value** — Input field value.
* `dependsOn` **array of strings** (optional) List of job, analysis and/or data object IDs. The app does not begin running any of its entry points until all jobs and analyses listed have transitioned to the "done" state, and all data objects listed are in the "closed" state.
* `project` **string** (required if invoked by a user, optional if invoked from a job with `detach: true` option, prohibited when invoked from a job with `detach: false`) The ID of the project in which this applet runs, also known as the *project context*. If invoked with the `detach: true` option, then the detached job runs under the provided `project` (if provided), otherwise project context is inherited from that of the invoking job. If invoked by a user or run as detached, all output objects are cloned into the project context. Otherwise, all output objects are cloned into the temporary workspace of the invoking job. See [The Project Context and Temporary Workspace](https://documentation.dnanexus.com/developer/api/running-analyses/..#project-context-and-temporary-workspace) for more information.

{% hint style="info" %}
A license is required to launch detached executions. [Contact DNAnexus Sales](mailto:sales@dnanexus.com) for more information.
{% endhint %}

* `folder` **string** (optional) The folder into which objects output by the job are placed. If the folder does not exist when the job completes, the folder (and any parent folders necessary) are created. The folder structure that output objects reside in is replicated within the target folder, for example, if `folder` is set to "/myJobOutput" and the job outputs an object which is in the folder "/mappings/mouse" in the workspace, the object is placed into "/myJobOutput/mappings/mouse". Defaults to `"/"`.
* `tags` **array of strings** (optional) Tags to associate with the resulting job.
* `properties` **mapping** (optional) Properties to associate with the resulting job.
  * **key** — Property name.
  * **value** **string** — Property value.
* `details` **mapping or array** (optional) JSON object or array that is to be associated with the job. Defaults to `{}`.
* `systemRequirements` **mapping** (optional) Request specific resources for each of the executable's entry points. See the [Requesting Instance Types](https://documentation.dnanexus.com/developer/api/applets-and-entry-points#requesting-instance-types) section for more details.
* `systemRequirementsByExecutable` **mapping** (optional) Request system requirements for all jobs in the resulting execution tree, configurable by executable and by entry point, described in more detail in the [Requesting Instance Types](https://documentation.dnanexus.com/developer/api/applets-and-entry-points#requesting-instance-types) section.
* `timeoutPolicyByExecutable` **mapping** (optional) The timeout policies for jobs in the resulting job execution tree, configurable by executable and the entry point within that executable. See the `timeoutPolicyByExecutable` field in [`/applet-xxxx/run`](https://documentation.dnanexus.com/developer/api/applets-and-entry-points#api-method-applet-xxxx-run) for more details.
* `executionPolicy` **mapping** (optional) A collection of options that govern automatic job restart on certain types of failures. The format of this field is identical to that of the `executionPolicy` field in the [run specification](https://documentation.dnanexus.com/developer/api/io-and-run-specifications#run-specification) supplied to [`/applet/new`](https://documentation.dnanexus.com/developer/api/applets-and-entry-points#api-method-applet-new) and can override part or the whole of the `executionPolicy` mapping found in the app's run specification (if present).
* `ignoreReuse` **boolean** (optional) If true, [Smart Reuse](https://documentation.dnanexus.com/user/running-apps-and-workflows/job-reuse) is disabled for this execution. If false, Smart Reuse is enabled for this execution (if the organization has the feature enabled). Takes precedence over the value supplied for `app-xxxx/new`.
* `delayWorkspaceDestruction` **boolean** (optional) If not given, the value defaults to false for root executions (launched by a user or detached from another job), or to the parent's `delayWorkspaceDestruction` setting. If set to true, the temporary workspace created for the resulting job is preserved for 3 days after the job either succeeds or fails.
* `invoiceMetadata` **mapping** (optional) If the app has `lineItemPerTest` set to true, then the line item on the invoice contains the key/value pairs provided here. If the app does not have `lineItemPerTest` set to true, then this field is ignored.
  * **key** — Metadata key to provide on invoice.
  * **value** **string** — Metadata value to provide on invoice.
* `allowSSH` **array of strings** (optional) Array of IP addresses or [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) blocks (up to /16) from which SSH access is allowed to the user by the worker running this job. Array may also include `"*"` which is interpreted as the IP address of the client issuing this API call as seen by the API server. See [Connecting to Jobs](https://documentation.dnanexus.com/developer/apps/execution-environment/connecting-to-jobs) for more information. Defaults to `[]`.
* `debug` **mapping** (optional) Specify debugging options for running the executable. This field is only accepted when this call is made by a user (and not a job). Defaults to `{}`.
  * `debugOn` **array of strings** (optional) Array of job errors after which the job's worker should be kept running for debugging purposes, offering a chance to SSH into the worker before worker termination (assuming SSH has been enabled). This option applies to all jobs in the execution tree. Jobs in this state for longer than 2 days are automatically terminated but can be terminated earlier. Defaults to `[]`.
    * Must be one of `"ExecutionError"`, `"AppError"`, `"AppInternalError"`, or `"AppInsufficientResourceError"`. For a description of each error type, see [Types of Errors](https://documentation.dnanexus.com/developer/apps/error-information).
* `singleContext` **boolean** (optional) If true then the resulting job and its descendants are only allowed to use the authentication token given to it at the onset. Use of any other authentication token results in an error. This option offers extra security to ensure data cannot leak out of your given context. In restricted projects user-specified value is ignored, and `singleContext: true` setting is used instead.
* `nonce` **string** (optional) Unique identifier for this request. Ensures that even if multiple requests fail and are retried, only a single job is created. For more information, see [Nonces](https://documentation.dnanexus.com/developer/api/nonces).
* `detach` **boolean** (optional) This option has no impact when the API is invoked by a user. If invoked from a job with detach set to true, the new job is detached from the creator job and appears as a typical root execution. A failure in the detached job does not cause a termination of the job from which it was created and vice versa. Detached job inherits neither the access to the workspace of its creator job nor the creator job's priority. Detached job's access permissions are the intersection (most restricted) of access permissions of the creator job and the permissions requested by the detached job's executable. To launch the detached job, creator job must have CONTRIBUTE or higher access to the project in which the detached job is launched. The billTo of the project in which the creator job is running must be licensed to launch detached executions.

{% hint style="info" %}
A license is required to launch detached executions. [Contact DNAnexus Sales](mailto:sales@dnanexus.com) for more information.
{% endhint %}

* `rank` **integer** (optional) An integer between -1024 and 1023, inclusive. The rank indicates the priority in which the executions generated from this executable are processed. The higher the rank, the more prioritized it is. If no rank is provided, the executions default to a rank of zero. If the execution is not a root execution, it inherits its parent's rank.

{% hint style="info" %}
A license is required to use the Job Ranking feature. [Contact DNAnexus Sales](mailto:sales@dnanexus.com) for more information.
{% endhint %}

* `costLimit` **number** (optional) The limit of the cost that this execution tree should accrue before termination. This field is ignored if this is not a root execution.
* `headJobOnDemand` **boolean** (optional) If true, then the resulting master job is allocated to an on-demand instance, regardless of its scheduling priority. Its descendant jobs (if any) inherit its scheduling priority, and their instance allocations are independent from this option. This option overrides the settings in the app's `headJobOnDemand` (if any).
* `preserveJobOutputs` **mapping** (optional, nullable) Preserves all cloneable outputs of every completed, non-`jobReused` job in the execution tree launched by this API call in the root execution project, even if root execution ends up failing. Preserving the job outputs in the project trades off higher costs of storage for the possibility of subsequent job reuse. Defaults to `null`.

  \
  When a non-`jobReused` job in the root execution tree launched with non-null `preserveJobOutputs` enters "done" state, all cloneable objects referenced by the `$dnanexus_link` in the job's `output` field are cloned to the project folder described by `preserveJobOutputs.folder`. This happens unless the output objects already appear elsewhere in the project. Cloneable objects include files, records, applets, and closed workflows, but not databases. If the folder specified by `preserveJobOutputs.folder` does not exist in the project, the system creates the folder and its parents.\
  \
  As the root job or root analysis' stages complete, the regular outputs of the root execution are moved from `preserveJobOutputs.folder` to the regular output folders of the root execution. When you run your root execution without the `preserveJobOutputs` option to completion, some root execution outputs appear in the project in the root execution's output folders. If you had run the same execution with `preserveJobOutputs.folder` set to `"/pjo_folder"`, the same set of outputs would appear in the same set of root execution folders as in the first case at completion of the root execution. Some additional job outputs that are not outputs of the root execution would appear in `"/pjo_folder"`.\
  \
  `preserveJobOutputs` argument can be specified only when starting a root execution or a detached job.\
  \
  `preserveJobOutputs` value, if not **null**, should be a mapping that may contain the following:

  * **key** — `"folder"` (optional).
  * **value** **string** — Specifies a folder in the root execution project where the outputs of jobs that are a part of the launched execution are stored. `path_to_folder` starting with `/` is interpreted as absolute folder path in the project the job is running in. `path_to_folder` not starting with `/` is interpreted as a path relative to the root execution's `folder` field. An empty string `path_to_folder` value (`""`) preserves job outputs in the folder described by root execution's `folder` field. If the `preserveJobOutputs` mapping does not have a `folder` key, the system uses the default folder value of `"intermediateJobOutputs"`. For example, `"preserveJobOutputs": {}` is equivalent to `"preserveJobOutputs": {"folder":"intermediateJobOutputs"}`.

    It is recommended to place preserveJobOutputs outputs for different root executions into different folders so as not to create a single folder with a large (>450K) number of files.

{% hint style="info" %}
A license is required to use `preserveJobOutputs`. [Contact DNAnexus Sales](mailto:sales@dnanexus.com) for more information.
{% endhint %}

* `detailedJobMetrics` **boolean** (optional) Requests detailed metrics collection for jobs if set to true. This flag can be specified for root executions and applies to all jobs in the root execution. The list of detailed metrics collected every 60 seconds and viewable for 15 days from the start of a job is available using [`dx watch --metrics`](https://documentation.dnanexus.com/user/helpstrings-of-sdk-command-line-utilities#watch-metrics-help).
  * Defaults to the project `billTo`'s `detailedJobMetricsCollectDefault` policy setting, or `false` if the org default is not set.

{% hint style="info" %}
A license is required to use `detailedJobMetrics`. Contact [DNAnexus Sales](mailto:sales@dnanexus.com) for more information.
{% endhint %}

#### Outputs

* `id` **string** ID of the created job, such as "job-xxxx".

#### Errors

* ResourceNotFound
  * The specified app or project context does not exist, or one of the IDs listed in `dependsOn` does not exist.
* PermissionDenied
  * The requesting user must be represented in the access list or must be one of the app's developers. If the latter, a full scope token or one with developer access is required.
  * If the app is unpublished, the requesting user must be one of the app's developers, and either (1) a full scope token or one with developer access is required or (2) the token belongs to a job that is already running the same app.
  * CONTRIBUTE access to the project context is required unless called by a job.
  * VIEW access is required for any objects listed in `dependsOn` and for the project contexts of any jobs listed in `dependsOn.`
  * The user has too many non-terminal jobs (such as running or runnable) and must wait for some to finish before creating more. The default limit is 65,536 jobs.
  * When specifying `allowSSH` or `debug` options, the user must be one of the app's developers, or the app must have the `openSource` field set to true.
  * If rank is provided and the billTo does not have license feature executionRankEnabled set to true.
  * If `preserveJobOutputs` is not **null** and `billTo` of the project where execution is attempted does not have preserveJobOutputs license.
  * `detailedJobMetrics` setting of true requires project's `billTo` to have `detailedJobMetrics` license feature set to true.
  * `app{let}-xxxx` can not run in `project-xxxx` because executable's `httpsApp.shared_access` should be `NONE` to run with isolated browsing.
  * The requested instance types are unavailable (no price has been contractually set for the `billTo` organization)
  * The project is associated with a [TRE](https://documentation.dnanexus.com/developer/api/trusted-research-environments) and `allowSSH` was specified. SSH access is not allowed in TRE projects. See [Execution Restrictions](https://documentation.dnanexus.com/developer/trusted-research-environments#execution-restrictions).
  * The project is associated with a TRE and the executable's `httpsApp` settings are not allowed. In TRE projects, only allowlisted HTTPS apps may expose HTTPS, and only on port `443`. See [Execution Restrictions](https://documentation.dnanexus.com/developer/trusted-research-environments#execution-restrictions).
  * The project is associated with a TRE and the executable is not in the project's `allowedExecutables` list, if the TRE policy restricts allowed executables.
* InvalidInput
  * An invalid link syntax appears in the `input`
  * The `input` does not satisfy the app's input specification
  * All data object inputs that are specified directly must be in the same region as the project context.
  * All inputs that are job-based object references must refer to a job that was run in the same region as the project context.
  * `allowSSH` accepts only IP addresses or [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) blocks up to /16
  * A `nonce` was reused in a request but other inputs had changed signifying a new and different request
  * A `nonce` may not exceed 128 bytes
  * The `billTo` of the job's project must be licensed to start detached executions when invoked from the job with `detach: true` argument.
  * `preserveJobOutputs` is specified when launching a non-detached execution from a job.
  * `preserveJobOutputs.folder` value is a syntactically invalid path to a folder.
  * `detailedJobMetrics` can not be specified when launching a non-detached execution from a job.
  * `timeoutPolicyByExecutable` for all executables should not be `null`
  * `timeoutPolicyByExecutable` for all entry points of all executables should not be `null`
  * `timeoutPolicyByExecutable` for all entry points of all executables should not exceed 30 days
  * Expected key `timeoutPolicyByExecutable.*` of input to match `/^(app|applet)-[0-9A-Za-z]{24}$/`
  * `systemRequirements.*.instanceTypeSelector` keyword is not allowed at runtime
  * `systemRequirementsByExecutable.*.*.instanceTypeSelector` keyword is not allowed at runtime
* InvalidState
  * Some input to the app is not in the "closed" state
  * Some execution in `dependsOn` has already failed or been terminated
  * The project context's region is not among the enabled regions of the app

### API method: `/app-xxxx[/yyyy]/delete`

#### Specification

Mark an app version as *deleted*. A deleted app can no longer be run, modified, nor published. This state is reflected in the output of describe. The associated resources container is made inaccessible. Any non-default tags associated with this app are invalidated and do not refer to any version of the app.

If this is the final or only version of the app, the app is also uninstalled for all users.

#### Inputs

* None

#### Outputs

* `id` **string** ID of the app (of the form "app-\<hash id>").

#### Errors

* PermissionDenied
  * User must be the user who created the app
  * A full scope token or one with developer access is required
* InvalidState
  * If an app has multiple versions, all other versions must be deleted before an app with the "default" can be deleted

### API method: `/app-xxxx[/yyyy]/addDevelopers`

#### Specification

Adds developers (users and/or orgs) to the app. All new user developers automatically have the app installed to their accounts.

If the requesting user is not a developer of the app, but they are the `billTo` of the app **or** the `billTo` of the app is an org and the user is an ADMIN of that org, then the user may invoke this method. They can grant themselves, and **only** themselves, developer access to the app.

#### Inputs

* `developers` **array of strings** (required) List of user and/or org IDs that are added as developers.

#### Outputs

* `name` **string** The app name, such as "bwa".

#### Errors

* ResourceNotFound
  * Specified app does not exist
  * A specified user does not exist
* InvalidInput
  * If the requesting user is not a developer of the app **and** is or administers the `billTo` of the app, then `developers` may only contain the ID of the requesting user
* PermissionDenied
  * The requesting user must be a developer of the app, or they must be or administer the `billTo` of the app
  * If the requesting user is a developer of the app, then the user must have either a full-scope token or a token with developer access
  * If the requesting user is not a developer of the app but is or administers the `billTo` of the app, then the user must have a full scope token

### API method: `/app-xxxx[/yyyy]/listDevelopers`

#### Specification

List the developers of the app

#### Inputs

* None

#### Outputs

* `developers` **array of strings** List of user and/or org IDs that are developers.

#### Errors

* ResourceNotFound
  * The specified app does not exist

### API method: `/app-xxxx[/yyyy]/removeDevelopers`

#### Specification

Remove a list of developers from the app. Attempting to remove a user or org who is not listed as a developer does not throw an error. If the billing account of the app is a user ID, then the developer access of that user may **not** be revoked.

#### Inputs

* `developers` **array of strings** (required) List of user and/or org IDs that are removed as developers.

#### Outputs

* `name` **string** The app name, such as "BWA".

#### Errors

* ResourceNotFound
  * The specified app does not exist
* InvalidInput
  * The billing account of the app is a user ID and `developers` contains that user ID
* PermissionDenied
  * User must be a developer of the app
  * A full scope token or one with developer access is required

### API method: `/app-xxxx[/yyyy]/addAuthorizedUsers`

#### Specification

Add users and/or org IDs to the access list.

#### Inputs

* `authorizedUsers` **array of strings** (required) List of user and/or org IDs to add to the access list.

#### Outputs

* `name` **string** The app name, such as "BWA".

#### Errors

* ResourceNotFound
  * A specified app or user does not exist
* InvalidInput
  * Input is not a hash, `authorizedUsers` is missing or is not an array of nonempty strings
* PermissionDenied
  * User must be a developer of the app
  * A full scope token or one with developer access is required
  * "PUBLIC" cannot be added as an authorized user. If you are interested in making an app available to all users of the DNAnexus Platform, contact [DNAnexus Support](mailto:support@dnanexus.com).

### API method: `/app-xxxx[/yyyy]/listAuthorizedUsers`

#### Specification

List the user and/or org IDs on the access list for the app. The string "PUBLIC" represents the set of all users.

#### Inputs

* None

#### Outputs

* `authorizedUsers` **array of strings** List of user and/or org IDs that can describe and run the app. If "PUBLIC" is present, this means all users can access the app.

#### Errors

* ResourceNotFound
  * The specified app does not exist
* PermissionDenied
  * The requesting user must be represented in the access list or must be one of the app's developers. If the latter, a full scope token or one with developer access is required.

### API method: `/app-xxxx[/yyyy]/removeAuthorizedUsers`

#### Specification

Remove a list of user and/or org IDs from the access list for the app. Removing an entity that is not listed in the access list does not throw an error.

#### Inputs

* `authorizedUsers` **array of strings** (required) List of user and/or org IDs to remove from the access list.

#### Outputs

* `name` **string** The app name, such as "bwa".

#### Errors

* ResourceNotFound
  * A specified app does not exist
* InvalidInput
  * Input is not a hash, `authorizedUsers` is missing or is not an array of nonempty strings
* PermissionDenied
  * User must be a developer of the app
  * A full scope token or one with developer access is required

### API method: `/app-xxxx[/yyyy]/addCategories`

#### Specification

Add categories for the app.

#### Inputs

* `categories` **array of strings** (required) List of categories to add the app to.

#### Outputs

* `name` **string** The app name, such as "bwa".

#### Errors

* ResourceNotFound
  * A specified app does not exist
* InvalidInput
  * Input is not a hash, `categories` is missing or is not an array of nonempty strings, a listed category is not allowed: "new", "recommended", or "popular"
* PermissionDenied
  * User must be a developer of the app
  * A full scope token or one with developer access is required

### API method: `/app-xxxx[/yyyy]/listCategories`

#### Specification

List the categories that an app is a member of. Anyone can list the categories of a published app.

#### Inputs

* None

#### Outputs

* `categories` **array of strings** List of categories the app belongs to.

#### Errors

* ResourceNotFound
  * The specified app does not exist
* PermissionDenied
  * The requesting user must be represented in the access list or must be one of the app's developers. If the latter, a full scope token or one with developer access is required
  * If the app is unpublished, the requesting user must be one of the app's developers, and a full scope token or one with developer access is required

### API method: `/app-xxxx[/yyyy]/removeCategories`

#### Inputs

* `categories` **array of strings** (required) List of categories to remove the app from.

#### Outputs

* `name` **string** The app name, such as "bwa".

#### Errors

* ResourceNotFound
  * A specified app does not exist
* InvalidInput
  * Input is not a hash, `categories` is missing or is not an array of nonempty strings
* PermissionDenied
  * User must be a developer of the app
  * A full scope token or one with developer access is required

### API method: `/app-xxxx[/yyyy]/isCompatible`

#### Specification

Checks whether the app object specified in the URL can replace the app object specified in the `otherVersion` field of the input in a workflow without user intervention.

The following changes to the input and output specifications of the app specified in `otherVersion` can be made while remaining compatible:

* Changing any `label` or `help` fields
* Setting `optional` to true for any input field
* Setting `default` to some valid value for any input field
* Adding additional optional inputs
* Adding additional outputs

The following changes result in incompatibility:

* Making an optional input required
* Adding a required input
* Renaming or changing the class or type specification for an existing input or output field name
* Removing an output

#### Inputs

* `otherVersion` **string** (required) An app identifier with which to test compatibility. This app object can be a deleted version.

#### Outputs

* `id` **string** ID of the app object checked for compatibility.
* `otherVersion` **string** ID of the app object specified as `otherVersion` in the input.
* `compatible` **boolean** True if it is compatible and false otherwise.

#### Errors

* ResourceNotFound
  * One of the specified apps does not exist
* InvalidInput
  * Input is not a hash, `otherVersion` is not present or is not a nonempty string
* PermissionDenied
  * The requesting user must be represented in the access list or must be one of the app's developers. If the latter, a full scope token or one with developer access is required.
  * If the app is unpublished, the requesting user must be one of the app's developers, and a full scope token or one with developer access is required.
* InvalidState
  * The app object in the URL has already been deleted

### API method: `/app-xxxx[/yyyy]/validateBatch`

#### Specification

This API call verifies that a set of input values for a particular app can be used to launch a batch of jobs in parallel.

Batch and common inputs:

`batchInput`: Mapping of inputs corresponding to batches. The nth value of each array corresponds to the nth execution of the app. Including a `null` value in an array at a given position means that the corresponding app input field is optional and the default value, if defined, should be used. For example:

```json
{
  "a": [{$dnanexus_link: "file-xxxx"}, {$dnanexus_link: "file-yyyy"}, ....],
  "b": [1,null, ...]
}
```

`commonInput`: Mapping of non-batch, constant inputs common to all batch jobs. For example:

```json
{
  "c": "foo"
}
```

File references:

`files`: List of files (passed as `$dnanexus_link` references). Must be a superset of files included in `batchInput` and/or `commonInput`. For example:

```json
[
  {$dnanexus_link: "file-xxxx"},
  {$dnanexus_link: "file-yyyy"}
]
```

Output: List of mappings. Each mapping corresponds to an expanded batch call. Nth mapping contains the input values with which the nth execution of the app runs. For example:

```json
[
  {"a": {$dnanexus_link: "file-xxxx"}, b: 1, c: "foo"},
  {"a": {$dnanexus_link: "file-yyyy"}, b: null, c: "foo"}
]
```

It performs the following validation:

* The input types match the expected app input field types.
* Provided inputs are sufficient to run the app.
* Null values are only among values for inputs that are optional or have no specified default values.
* All arrays of `batchInput` are of equal size.
* Every file referred to in `batchInputs` exists in `files` input.

#### Inputs

* `batchInput` **mapping** (required) Input that the app is launched with.
  * **key** — Input field name. It must be one of the names of the inputs defined in the app input specification.
  * **value** — Input field values. It must be an array of fields.
* `commonInput` **mapping** (optional) Input that the app is launched with.
  * **key** — Input field name. It must be one of the names of the inputs defined in the app input specification.
  * **value** — Input field values. It must be an array of fields.
* `files` **array of mappings** (optional) Files that are needed to run the batch jobs, they must be provided as `$dnanexus_links`. They must correspond to all the files included in `commonInput` or `batchInput`.

#### Outputs

* `expandedBatch` **array of mappings** Each mapping contains the input values for one execution of the app in batch mode.

#### Errors

* InvalidInput
  * Expected `batchInput` to be a JSON object
  * Expected `commonInput` to be a JSON object
  * Expected `files` to be an array of `$dnanexus_link` references to files
  * The `batchInput` field is required but empty array was provided
  * Expected the value of `batchInput` for an app input field to be an array
  * Expected the length of all arrays in `batchInput` to be equal
  * The app input field value must be specified in `batchInput`
  * The app input field is not defined in the input specification of the app
  * All the values of a specific `batchInput` field must be provided (cannot be `null`) since the field is required and has no default value
  * Expected all the files in `batchInput` and `commonInput` to be referenced in the `files` input array


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://documentation.dnanexus.com/developer/api/running-analyses/apps.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
