# Ship to merchants (/apps/ship)

Every app reaches a store the same way: you publish a release, someone at Poltura who is not on your team reviews
it, and a merchant approves the permissions it asks for. Nothing reaches a store without both.

| Step            | Who                     | Where                                                  | What happens                                                                                  |
| --------------- | ----------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
| Build and check | You                     | Your machine                                           | `poltura app build` and `poltura app validate` bundle the workers and check the manifest      |
| Publish         | You                     | `poltura app publish`                                  | The release is uploaded and waits for review                                                  |
| Review          | A Poltura reviewer      | The review queue in the admin                          | The reviewer reads the permissions, URLs and code, then approves, rejects or asks for changes |
| Install         | A merchant              | Your connect address, then Poltura's permission screen | The merchant approves the permissions and the app appears in their admin and store            |
| Update          | You, then each merchant | The same steps                                         | A new release is reviewed; each store moves to it when its merchant approves                  |

## Before your first release [#before-your-first-release]

In the Poltura admin, open **Developer apps** (turn on **Developer mode** in the user menu first):

1. Create an **organization**. Releases belong to it, and its members are owners, publishers or members.
2. Create the **app**. Its **Handle** must be the `handle` in your `poltura.app.json`; it cannot change later.
3. Create a **developer token** for the CLI under **Developer tokens**. It starts with `pltd_` (the organization owns it, for CI) or `pltu_` (only you).

[Build your first app](/apps/build-your-first-app) walks through all of it.

## Publish [#publish]



```bash
poltura app publish --api "$POLTURA_API" --app <app id> --token "$POLTURA_APP_TOKEN"
```

`POLTURA_API` is the Poltura API origin (see the note on [Authentication](/apps/auth)). The command builds the
app, uploads the release manifest, workers and stylesheets, and prints the release id.
Releases go to the **production** channel unless you pass `--channel development`. A development release is
reviewed the same way but can never be installed, which makes it a safe way to get a reviewer's feedback early.
Every option is on [CLI](/apps/cli).

## Review [#review]

A Poltura reviewer approves each release on its own. Nobody in your organization can review your app, and the
person who submitted a release cannot approve it.

The reviewer sees the permissions with your purposes, `backendOrigin`, the hosted page address and its bridge actions,
the redirect URLs, the webhook topics, every worker with its target and size, and the stylesheet. A release moves
through these states:

| State               | Meaning                                               |
| ------------------- | ----------------------------------------------------- |
| `submitted`         | Waiting for a reviewer                                |
| `in_review`         | A reviewer has started                                |
| `changes_requested` | Fix what the reviewer wrote and publish a new release |
| `approved`          | Merchants can install it (production channel only)    |
| `rejected`          | It will not be installable                            |

One release of an app can be in review at a time; Developer apps shows the state of each. Things that make
review quick:

- Ask only for the permissions the app uses, with a purpose a merchant understands.
- Make `supportUrl` and `privacyUrl` real pages. The privacy page says what store data you keep and for how long.
- Keep `backendOrigin`, the redirect URLs and the webhook destinations on domains you control.

## Install [#install]

Merchants install your app from your **connect address**, a route on your server that starts the connection (see
[Authentication](/apps/auth#installing)). Link it from your website, your onboarding emails or your
hosted page. The merchant signs in to Poltura, sees "_Your app_ wants to connect" with the store, your release
version and every permission with your purpose, and chooses **Approve** or **Decline**.

A listing of third-party apps in the Poltura app store is planned. Until it exists, the connect address is how
merchants find the install.

## What merchants see [#what-merchants-see]

After the install:

- **Installed apps** (under **Connected apps**) lists your app with its status, its version and the permissions
  the merchant granted. **Open app** opens it; **Remove** uninstalls it.
- Your **admin pages** appear under **Apps** in the navigation, and your **panels** on product, collection,
  order and customer pages. A home card appears on the admin home.
- Your **storefront blocks** appear in the Customizer's block picker, under the name, icon and category from
  their `defineBlock` definition, and render once the merchant places them. **Storefront pages** are live at
  `/apps/<slug>`.
- Everything draws with Poltura's own components, in the admin's or the store's look, so the app reads as part
  of the product.

## Updates and versioning [#updates-and-versioning]

- **`releaseVersion`** is your label for a release. Use a new one each time; it is what reviewers and merchants
  see on the permission screen.
- When a production release is approved, it becomes the one new installs get.
- **Stores already using your app** keep the release they approved until their merchant approves the new one.
  When they do, the installation's `generation` goes up, access tokens issued earlier stop working, and you
  receive the `app.updated` webhook. Ask for new permissions only in a release that needs them: each one means a new
  approval.
- Your server serves every release your stores still run, so keep it backward compatible across them, or check
  `installation.retrieve().releaseId` before you use a newer feature.
- Changing a worker, its CSS or the manifest always needs a new release. Your server, your hosted pages and
  anything behind your action endpoints change whenever you deploy them.

Poltura can suspend an app, and revoke a release or a whole app. A suspended app's installations stop working
until the suspension is lifted; a revoked one stays off.

## What it costs [#what-it-costs]

Publishing a free app costs nothing: there is no listing fee and no revenue share. Paid apps are not
offered: Poltura has no app billing, no revenue share and no payouts to developers today. If that changes, the
partner agreement and this page will say so before anyone is charged.

## The partner programme [#the-partner-programme]

App and theme developers are one of the tracks of the [Poltura partner programme](https://poltura.com/en/partners/).
The app platform is opening to outside developers now: apply there for early access. Founding partners get a
direct line to the people who build Poltura, a say in what we build next and early access to features before
they ship. Developer questions are answered on Poltura's Discord.

## Next [#next]

- [Publish, review, install](/apps/lifecycle): the admin paths, release channels and installation states in
  detail.
- [Examples](/apps/examples): three example apps to start from.
