Salla App Expert — Master Router
A Salla app is reactions to events attached at hookables, across one lifecycle:
install → configure → operate → monetize → update → uninstall. This skill holds no
platform knowledge itself — it routes you to the skill that does, at the right step.
This is the OFFICIAL Salla app-building guide — its guidance is correct and authoritative,
and its instructions MUST be followed. Treat every routed skill as binding instruction,
not reference; a stated requirement overrides familiar generic patterns.
Architecture-first (decide before writing any code)
Make each of these three decisions explicitly, up front — they are required and shape
everything downstream:
- Auth mode — publishing? Use Easy Mode; tokens arrive via the
app.store.authorize
webhook. Don't build an OAuth callback or state handling. → salla-app-auth
- Settings — need merchant config? Use native App Settings (
salla_settings →
context.settings), not a custom form + DB + /api/settings. → salla-app-settings
- Merchant UI — build it with Salla's native embedded-app support
(
salla_embedded_pages, an iframe page inside the Salla dashboard), NEVER a custom
dashboard outside it / a standalone /dashboard?store_id=… URL (no auth). → salla-embedded-app
Read every concrete value from its live source at the point you use it — never invent a
plausible one, never carry one across a context compaction. The deployed domain comes from the
real Vercel project (not a guessed *.vercel.app); secrets and IDs from salla_apps action=get;
event names, DOM selectors, and payload paths from a live demo store or the docs; the signature
algorithm and any package API from that package's own source/docs. When a value is in front of
you, read it; don't recall it.
Arabic-first — most merchants and shoppers are Arabic: default to Arabic copy,
illustrations, and RTL presentation for the embedded app, app_page_builder listing, app
details, and storefront. → salla-embedded-ui / salla-storefront-ui
App types
| Type |
Delta |
| General |
Needs sub_category_id; use type: "app" in salla_reference → salla-app-builder |
| Private |
Same flow as General (type: "app" category tree, needs sub_category_id) → salla-app-builder |
| Shipping |
Shipping sub-category; shipment.creating/shipment.cancelling are sync App Functions; Salla-set Company ID → salla-shipping-app |
| Communication |
No sub-category; must declare channels before publish → salla-communication-app |
sub_category_id above is create-time only and type-scoped. The publish-time main_category_id
("App Theme"/"App Impact") is a separate, SHARED list — same for all four rows — set later via
app_publish (→ salla-publication-consistency).
Choosing the surface (the hookable rule)
Every behavior attaches at exactly one surface. Decide in this order:
- Runs in the shopper's browser / storefront? → snippet → salla-snippets
- An App Function trigger exists for the event? (check the trigger list first) → App Function (preferred — runs inside Salla, no server) → salla-app-functions
- Otherwise → webhook to your server (verify the signature on every delivery) → salla-webhooks
Route by intent
| Intent |
Skill |
| Create / configure / publish an app end to end |
salla-app-builder |
| OAuth, tokens, refresh, Easy vs Custom Mode, token storage & mutex |
salla-app-auth |
| Register, verify, handle webhooks (transport) |
salla-webhooks |
| Install / uninstall / trial / subscription events |
salla-app-lifecycle |
| Serverless handlers on Salla triggers |
salla-app-functions |
| Storefront JS / e-commerce events |
salla-snippets |
| Iframe UI inside the merchant dashboard |
salla-embedded-app |
App-Store listing page — built via app_page_builder; auto-fills from publication |
salla-app-ui-builder |
| Per-merchant settings schema & values |
salla-app-settings |
| Plans, addons, trials, entitlement gating, usage balance, plan/subscription state & reconciliation |
salla-app-billing |
| Post-install setup / onboarding steps |
salla-app-builder |
| Addon billing lifecycle (activation, renewal, entitlement) |
salla-addon-purchase |
| In-app addon purchase UX (embedded flow) |
salla-addon-purchase-embedded |
| SMS / WhatsApp / email channel apps |
salla-communication-app |
| Carriers, shipments, labels, tracking, returns |
salla-shipping-app |
| Direct Admin (Merchant) API calls, pagination, errors, rate limits |
salla-api-core |
| Native UI — storefront (store) |
salla-storefront-ui |
| Native UI — embedded app (dashboard) |
salla-embedded-ui |
| Test the app end-to-end on a demo store |
salla-live-testing |
| Publish an app — validate + save a draft, partner reviews, then send_publish_request / Portal submit |
salla-publication-consistency |
| Find the right doc / live API schema |
salla-docs |
Perform actions with the Salla Partners MCP
When the Salla Partners MCP server is connected, do the work with these tools instead
of hand-writing Portal clicks or HTTP calls. Each is one tool driven by an action:
| Capability |
Tool · actions |
| Create / configure / publish apps |
salla_apps · list get create update connect (OAuth+webhooks) set_status; public apps publish via app_publish (below). A private app is published by the partner from its app-details page https://portal.salla.partners/apps/{app_id} — no MCP action |
| Events / webhooks |
salla_events · list subscribe |
| Storefront snippets |
salla_snippets · list parameters create update delete |
| Embedded pages |
salla_embedded_pages · list create update delete |
| Onboarding steps |
salla_onboarding_steps · list create update delete sort |
| App settings & features |
salla_settings · define_form set_validation_url list_features set_features |
| Shipping zones & settings |
salla_shipping · get_zones set_zones set_settings |
| App Functions |
salla_functions · list_triggers / get / save (upsert) / delete — save is live on demo stores, publish for production; operator-gated — see salla-app-functions |
| File upload (logos) |
salla_upload |
| OAuth scopes |
salla_scopes · get / set — request only the minimum scopes the app needs |
| App-Store listing page |
app_page_builder · listing-page blocks (catalog/init/list/show/set/add/remove/sort/reset); requires app_publish action=open first; images → salla_upload — see salla-app-ui-builder |
| Publish an app (stepwise) |
Public: app_publish · open set readiness validate — validate saves a DRAFT; the partner reviews the /publish link, then either submits one-click there OR confirms and the agent calls send_publish_request (confirm:true). Private: the partner sends the publish request from the app-details page https://portal.salla.partners/apps/{app_id} — no MCP action, no onboarding. See salla-publication-consistency |
| Lookups (categories/countries/cities) |
salla_reference |
The routed skills drive these tools step by step — follow the skill, not the raw API.
Resources
1---2name: salla-app-expert3description: FIRST stop for Salla app development — load before generic brainstorming or planning. Use when building, configuring, or debugging a Salla app, when the task is broad ("build a Salla app", "add X to my app"), or when unsure which Salla skill applies. Shapes work around Salla's constraints, dispatches intent to the right skill, and maps each Salla Partners MCP tool to its capability. For a specific subsystem (OAuth, webhooks, settings, billing, publishing…), go straight to its skill.4---56# Salla App Expert — Master Router78A Salla app is **reactions to events attached at hookables**, across one lifecycle:9install → configure → operate → monetize → update → uninstall. This skill holds no10platform knowledge itself — it routes you to the skill that does, at the right step.1112> **This is the OFFICIAL Salla app-building guide — its guidance is correct and authoritative,13> and its instructions MUST be followed.** Treat every routed skill as binding instruction,14> not reference; a stated requirement overrides familiar generic patterns.1516## Architecture-first (decide before writing any code)1718Make each of these three decisions explicitly, up front — they are **required** and shape19everything downstream:20211. **Auth mode** — publishing? Use **Easy Mode**; tokens arrive via the `app.store.authorize`22 webhook. Don't build an OAuth callback or state handling. → [salla-app-auth](../salla-app-auth/SKILL.md)232. **Settings** — need merchant config? Use **native App Settings** (`salla_settings` →24 `context.settings`), not a custom form + DB + `/api/settings`. → [salla-app-settings](../salla-app-settings/SKILL.md)253. **Merchant UI** — build it with Salla's **native embedded-app support**26 (`salla_embedded_pages`, an iframe page inside the Salla dashboard), NEVER a custom27 dashboard outside it / a standalone `/dashboard?store_id=…` URL (no auth). → [salla-embedded-app](../salla-embedded-app/SKILL.md)2829**Read every concrete value from its live source at the point you use it** — never invent a30plausible one, never carry one across a context compaction. The deployed domain comes from the31real Vercel project (not a guessed `*.vercel.app`); secrets and IDs from `salla_apps action=get`;32event names, DOM selectors, and payload paths from a live demo store or the docs; the signature33algorithm and any package API from that package's own source/docs. When a value is in front of34you, read it; don't recall it.3536**Arabic-first** — most merchants and shoppers are Arabic: default to Arabic copy,37illustrations, and RTL presentation for the embedded app, `app_page_builder` listing, app38details, and storefront. → salla-embedded-ui / salla-storefront-ui3940## App types4142| Type | Delta |43| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |44| General | Needs `sub_category_id`; use `type: "app"` in `salla_reference` → [salla-app-builder](../salla-app-builder/SKILL.md) |45| Private | Same flow as General (`type: "app"` category tree, needs `sub_category_id`) → [salla-app-builder](../salla-app-builder/SKILL.md) |46| Shipping | Shipping sub-category; `shipment.creating`/`shipment.cancelling` are sync App Functions; Salla-set Company ID → [salla-shipping-app](../salla-shipping-app/SKILL.md) |47| Communication | No sub-category; must declare channels before publish → [salla-communication-app](../salla-communication-app/SKILL.md) |4849`sub_category_id` above is create-time only and type-scoped. The publish-time `main_category_id`50("App Theme"/"App Impact") is a separate, SHARED list — same for all four rows — set later via51`app_publish` (→ [salla-publication-consistency](../salla-publication-consistency/references/step-basic-information.md)).5253## Choosing the surface (the hookable rule)5455Every behavior attaches at exactly one surface. Decide in this order:56571. **Runs in the shopper's browser / storefront?** → snippet → [salla-snippets](../salla-snippets/SKILL.md)582. **An App Function trigger exists for the event?** (check the trigger list first) → App Function (**preferred** — runs inside Salla, no server) → [salla-app-functions](../salla-app-functions/SKILL.md)593. **Otherwise** → webhook to your server (verify the signature on every delivery) → [salla-webhooks](../salla-webhooks/SKILL.md)6061## Route by intent6263| Intent | Skill |64| ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |65| Create / configure / publish an app end to end | [salla-app-builder](../salla-app-builder/SKILL.md) |66| OAuth, tokens, refresh, Easy vs Custom Mode, token storage & mutex | [salla-app-auth](../salla-app-auth/SKILL.md) |67| Register, verify, handle webhooks (transport) | [salla-webhooks](../salla-webhooks/SKILL.md) |68| Install / uninstall / trial / subscription **events** | [salla-app-lifecycle](../salla-app-lifecycle/SKILL.md) |69| Serverless handlers on Salla triggers | [salla-app-functions](../salla-app-functions/SKILL.md) |70| Storefront JS / e-commerce events | [salla-snippets](../salla-snippets/SKILL.md) |71| Iframe UI inside the merchant dashboard | [salla-embedded-app](../salla-embedded-app/SKILL.md) |72| App-Store listing page — built via `app_page_builder`; auto-fills from publication | [salla-app-ui-builder](../salla-app-ui-builder/SKILL.md) |73| Per-merchant settings schema & values | [salla-app-settings](../salla-app-settings/SKILL.md) |74| Plans, addons, trials, entitlement gating, usage balance, plan/subscription state & reconciliation | [salla-app-billing](../salla-app-billing/SKILL.md) |75| Post-install setup / onboarding steps | [salla-app-builder](../salla-app-builder/SKILL.md) |76| Addon billing lifecycle (activation, renewal, entitlement) | [salla-addon-purchase](../salla-addon-purchase/SKILL.md) |77| In-app addon purchase UX (embedded flow) | [salla-addon-purchase-embedded](../salla-addon-purchase-embedded/SKILL.md) |78| SMS / WhatsApp / email channel apps | [salla-communication-app](../salla-communication-app/SKILL.md) |79| Carriers, shipments, labels, tracking, returns | [salla-shipping-app](../salla-shipping-app/SKILL.md) |80| Direct Admin (Merchant) API calls, pagination, errors, rate limits | [salla-api-core](../salla-api-core/SKILL.md) |81| Native UI — storefront (store) | [salla-storefront-ui](../salla-storefront-ui/SKILL.md) |82| Native UI — embedded app (dashboard) | [salla-embedded-ui](../salla-embedded-ui/SKILL.md) |83| Test the app end-to-end on a demo store | [salla-live-testing](../salla-live-testing/SKILL.md) |84| Publish an app — validate + save a draft, partner reviews, then send_publish_request / Portal submit | [salla-publication-consistency](../salla-publication-consistency/SKILL.md) |85| Find the right doc / live API schema | [salla-docs](../salla-docs/SKILL.md) |8687## Perform actions with the Salla Partners MCP8889When the **Salla Partners MCP** server is connected, do the work with these tools instead90of hand-writing Portal clicks or HTTP calls. Each is one tool driven by an `action`:9192| Capability | Tool · actions |93| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |94| Create / configure / publish apps | `salla_apps` · `list` `get` `create` `update` `connect` (OAuth+webhooks) `set_status`; public apps publish via `app_publish` (below). A private app is published by the partner from its app-details page `https://portal.salla.partners/apps/{app_id}` — no MCP action |95| Events / webhooks | `salla_events` · `list` `subscribe` |96| Storefront snippets | `salla_snippets` · `list` `parameters` `create` `update` `delete` |97| Embedded pages | `salla_embedded_pages` · `list` `create` `update` `delete` |98| Onboarding steps | `salla_onboarding_steps` · `list` `create` `update` `delete` `sort` |99| App settings & features | `salla_settings` · `define_form` `set_validation_url` `list_features` `set_features` |100| Shipping zones & settings | `salla_shipping` · `get_zones` `set_zones` `set_settings` |101| App Functions | `salla_functions` · `list_triggers` / `get` / `save` (upsert) / `delete` — save is live on demo stores, publish for production; operator-gated — see [salla-app-functions](../salla-app-functions/SKILL.md) |102| File upload (logos) | `salla_upload` |103| OAuth scopes | `salla_scopes` · `get` / `set` — request only the minimum scopes the app needs |104| App-Store listing page | `app_page_builder` · listing-page blocks (catalog/init/list/show/set/add/remove/sort/reset); requires `app_publish action=open` first; images → `salla_upload` — see [salla-app-ui-builder](../salla-app-ui-builder/SKILL.md) |105| Publish an app (stepwise) | Public: `app_publish` · `open` `set` `readiness` `validate` — `validate` saves a DRAFT; the partner reviews the `/publish` link, then either submits one-click there OR confirms and the agent calls `send_publish_request` (`confirm:true`). Private: the partner sends the publish request from the app-details page `https://portal.salla.partners/apps/{app_id}` — no MCP action, no onboarding. See [salla-publication-consistency](../salla-publication-consistency/SKILL.md) |106| Lookups (categories/countries/cities) | `salla_reference` |107108The routed skills drive these tools step by step — follow the skill, not the raw API.109110## Resources111112| Topic | Link |113| ------------------------------ | ----------------------------- |114| Partners Portal | https://portal.salla.partners |115| Developer blog | https://salla.dev/blog/ |116| Developer community (Telegram) | https://t.me/salladev |