Manifest

The manifest.webapp file provides important information about the app, such as version, name, description, icon location, locale strings, domains the app can be installed from, and much more. Most importantly, it contains a list of APIs that your app needs. This allows users to make informed decisions about apps before installing them.

Your app's manifest.webapp file should be placed in the root of your app directory, and contain a simple JSON structure. A simple App Manifest JSON looks like this:

{
  "version": "1.0.0",
  "name": "KaiOS App",
  "description": "A file simple example manifest.webapp",
  "launch_path": "/your/repository/index.html",
  "icons": {
    "56": "/your/repository/icons/ic_Appname_56.png",
    "112": "/your/repository/icons/ic_Appname_112.png"
  },
  "developer": {
    "name": "Your Name",
    "url": "http://yourawesomeapp.com"
  },
  "locales": {
    "en-US": {
      "name": "The Open Web",
      "description": "Your new web app application"
    }
  },
  "default_locale": "en-US"
}

Required fields

The fields in your manifest can be in any order. Fields in the manifest other than the ones listed below will be ignored.

name

Note: Required for all app manifests.

A human-readable name for the app. Maximum length is 20 characters.

If you change the name of your app after distribution, the name will not be updated for any existing installations.

"name": "The Open Web!"

version

A specialized string that represents the version of the app. Must be integers separated by dots.

"version": "1.2.0"

description

Note: Required for all app manifests.

A human-readable description for the app. It should be a short and strong message.

"description": "My elevator pitch goes here"

icons

Note: One icon sized 56×56 is required for all app manifests. One icon sized 112×112 is recommended for all app manifests.

A map of icon sizes to URIs of the icons.

Remember that internal paths to icons must be absolute from the app's origin, while paths to externally hosted icons must be fully qualified.

Icons must be square and in .png format. Icons should not have solid backgrounds that extend to all four corners of the icon.

For more details about app icon check Launcher Icon section in Design Guide.

"icons": {
  "56": "/img/ic_Appname_56.png",
  "112": "/img/ic_Appname_112.jpg"
}

developer

Note: Only the name is required for all app manifests.

  • name: The name of the developer. Required for all app manifests.
  • url: The URL of a website containing information about the app's developer. Optional.
"developer": {
    "name": "The Open Web!",
    "url": "http://www.mywebapp.com"
}

locales

A map of one or more language-specific overrides of the field values in your app manifest.

Keys for locales use the same language tags as for default_locale (RFC 4646).

"locales": {
  "it-IT": {
    "name": "L'Open Web",
    "description": "Eccitante azione di sviluppo web open!"
  },
  "de-DE": {
    "name": "Der Open Web",
    "description": "Spannende offene Web-Entwicklung-Action!"
  }
}

default_locale

A language tag (RFC 4646) that defines the language you used in the field values of your app manifest.

Please refer to the list below of language identification codes used in the KaiOS system. We strongly suggest to use the same language identification codes throughout to avoid misalignment issues or incorrect results when users change language settings in the system:

af-ZA Afrikaans
ar-SA عربي
az-Latn-AZ Azərbaycan
be-BY Беларуская
bg-BG Български
bn-IN বাংলা (IN)
bn-BD বাংলা-BD
bs-BA Bosanski
cs-CZ Česky
da-DK Dansk
de-DE Deutsch
el-GR Ελληνικά
en-GB English (GB)
en-US English (US)
es-US Español (US)
et-EE Eesti
es-ES Español (ES)
fa-IR فارسی (IR)
fi-FI Suomi
fil-PH Tagalog
fr-CA French (CA)
fr-FR Français (FR)
he-IL עברית
hi-HI हिन्दी
hr-HR Hrvatski
hu-HU Magyar
hy-AM Հայերեն
id-ID Bahasa Indonesia
is-IS Íslenska
it-IT Italiano
it-LT Lietuvių
ka-GE ქართული
kk-KZ Қазақша
km-KH ភាសាខ្មែរ
lo-LA ລາວ
lv-LV Latviešu
mk-MK Македонски
mo-RO Молдовеняскэ
ms-MY Melayu
nb-NO Norsk (bokmål)
ne-IN नेपाली
nl-NL Nederlands
pl-PL Polski
ps-AF پښتو
pt-BR Português (do Brasil)
pt-PT Português (Europeu)
ro-RO Română
ru-RU Русский
si-LK සිංහල
sk-SK Slovenčina
sl-SI Slovenščina
sq-AL Shqip
sr-Latn-CS Српски/Srpski
sv-SE Svenska
sw-ZA Kiswahili
ta-IN தமிழ்
th-TH ไทย
tr-TR Türkçe
uk-UA Українська
ur-PK اردو
uz-Cyrl-UZ O'zbek
vi-VN Tiếng Việt
xh-ZA isiXhosa
zh-CN 中文 (简体)
zh-HK 中文-HK
zh-TW 中文-TW
zu-ZA isiZulu
as-IN অসমীয়া
und-bod बोड़ो
doi-IN डोगरी
gu-IN ગુજરાતી
kn-IN ಕನ್ನಡ
ks-IN کأشُر
kok-IN कोंकणी
mai-IN मैथिली
ml-IN മലയാളം
mni-IN মণিপুরী
mr-IN मराठी
or-IN ଓଡ଼ିଆ
pa-IN ਪੰਜਾਬੀ
sa-IN संस्कृत
sat-IN ᱥᱟᱱᱛᱟᱞᱤ
sd-IN सिन्धी
te-IN తెలుగు
ko-KR 한국어"

For example, if your app uses English, it's default_locale would be:

"default_locale": "en-US"

type

The app's type, which defines its level of access to sensitive device APIs. If you do not define type, it will default to web as the type.

  • web: A regular hosted app. This type has the least access to APIs.

  • privileged: An authenticated app that has been approved by an app store such as the KaiStore. This type has greater access to APIs than a web app.

Optional fields

The following fields are optional.

short_name

A human-readable name for the app. Can differ from name field.

subtitle

Your app’s subtitle appears below your app name throughout the KaiStore. A subtitle is a short and striking or memorable message, and is intended to summarize your app in a concise phrase. A compelling subtitle can encourage product page views and installs. The maximum length of a subtitle is 40 characters.

bgs

A map of background images sizes to URIs of the icons.

"bgs": {
  "56": "/img/ic_Appname_56.png",
  "112": "/img/ic_Appname_112.jpg"
}

launch_path

The path within the app's origin that is loaded when the app starts.

Specifies the starting point of the content local to the zip file containing the packaged app. For example, if the launch_path is /mywebapp/index.html, the app will open the file at /mywebapp/index.html when the app is launched.

Tips:

  • If your app is stored in the root of a Web server, for example mywebapp.github.com/, then launch_path must be set to /.

  • If your app is stored in a subdirectory, for example mymarket.github.com/mywebapp/, then launch_path must be set to /mywebapp/.
"launch_path": "/index.html"

origin

Note: Applies only to privileged or internal (certified) packaged apps.

Packaged apps have a special internal protocol of app://UUID where UUID is a string unique to each device the app is installed on. UUID is not easily accessible at this time. The origin field allows you to replace this UUID value with a single domain name that will be used by each installed app.

Remember: domain name must start with app://, and you must be the owner of the domain name you specify.

"origin": "app://mywebapp.com"

permissions

The user permissions for sensitive device APIs that your app needs, for example, access to the user's Contacts. See a full list of API permissions/features.

Each permission requires:

  • name: the name of the permission

  • description: the reason why your app needs to use this permission

  • access: the level of access required, options being readonly, readwrite, readcreate, and createonly. Only a few APIs need this, for example Data Store.

For example, here's a manifest entry for an app that needs permission to use the device's contacts and alarms.

"permissions": {
  "contacts": {
    "description": "Required for autocompletion in the share screen",
    "access": "readcreate"
    },
  "alarms": {
    "description": "Required to schedule notifications"
  }
}

Note: If an app tries to use one of these APIs without a corresponding entry in the permissions field, it will fail to run.

There are many APIs, some of whom require the app type to be privileged or internal (certified). For example, systemXHR requires the type field to be set to privileged in order to work:

"type": "privileged",
  "permissions": {
    "systemXHR": {
      "description": "Required to download podcasts."
    }
  }

fullscreen

A control that tells the runtime whether or not to launch the app in full-screen mode.

"fullscreen": "true"

datastores-owned

Note: Applies only to privileged/certified apps to be installed on KaiOS.

When making use of the Data Store API, the app that owns the data store MUST include the datastores-owned field in its manifest to claim ownership, for example:

"datastores-owned": {
  "myData": {
    "access": "readwrite",
    "description": "my data store"
  }
}

You can include multiple properties to represent different data stores, and each one can use an access of readonly/readwrite to specify whether the data store can be read/modified by other applications. A description is also included to describe the purpose of the data store.

datastores-access

Note: Applies only to privileged/certified apps to be installed on KaiOS.

When making use of the Data Store API, any non-owner app that wants access to the the data store MUST include the datastores-access field in its manifest, for example:

"datastores-access": {
  "myData": {
    "access": "readwrite",
    "description": "Read and modify my data store"
  }
}

Without this field being specified, the default behaviour is "no access". Again, multiple properties can be included if you want to access multiple data stores, and an access of readonly or readwrite can be set to declare what access type is needed by the app.

messages

Note: Applies only to apps to be installed on KaiOS.

The system messages you allow the app to capture, and the pages in your app that will display when those messages occur.

Below is an example from the KaiOS Dialer app. Every time an incoming call comes in (system message: telephony-new-call), the device shows the dialer's keypad (URL: /dialer/index.html#keyboard-view).

"messages": [
  { "alarm": "/index.html" }
  { "notification": "/index.html" }
  { "telephony-new-call": "/dialer/index.html#keyboard-view" }
]

redirects

Note: Applies only to privileged/certified apps that are to be installed on KaiOS.

The internal URLs your app uses to handle external processes.

For example, your app might use Facebook OAuth authentication to get a user's contacts. When the authentication is finished, the server usually redirects back to a URL that you control. Because packaged apps are not hosted on the web, a packaged app does not have a valid URL that can be redirected to. So you use the redirects field to redirect an external URL to an internal app URL.

In the scenario above, the redirects field will look like this:

"redirects": [
  {
    "from": "http://facebook.com/authentication/success.html",
    "to": "/app/main_interface.html"
  }
]

The scope of the redirects declared by redirects is limited to the app that declares them. That makes it so that several apps can redirect the same public URL to their own local resources, and it also prevents global hijacking of public URLs by an application.

activities

A set of Web Activities that your app supports (full list). It's structured like so:

  • Each property in this field is an activity
  • Activity names are free-form text
  • Each activity is represented by an object

For example, here's an entry with one activity named share.

"activities": {
  "share": {
    "filters": {
      "type": [ "image/png", "image/gif" ]
    },
    "href": "foo.html",
    "disposition": "window",
    "returnValue": true
  }
}

The object for the share activity in the example has filters, href, disposition and returnValue properties. These are described in Activity handler description.

precompile

The path to JavaScript files containing asm.js code that you want compiled at install time.

Compilation at install time makes the installation process longer, but reduces the time it takes to start up an app.

"precompile": [
  "game.js",
  "database.js"
]

orientation

The positioning at which the application will stay locked.

Illustration of possible values:

Value App will stay locked to
portrait-primary portrait-primary
portrait-secondary portrait-secondary
portrait
If you declare this, there's no need to write -primary or -secondary
portrait-primary portrait-secondary
landscape-primary landscape-primary
landscape-secondary landscape-secondary
landscape
If you declare this, there's no need to write -primary or -secondary
landscape-primary landscape-secondary
"orientation": [ "landscape-primary" ]

csp

This field can be used to define a Content Security Policy (CSP) that is applied to all pages in the app. The policies you can add to a CSP are listed in CSP policy directives, and for an app you'll need to include them in a line like so:

"csp" : "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'"

The default policies applied to KaiOS privileged and internal/certified apps are as follows:

Privileged CSP

default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'

Certified/Internal CSP

default-src *; script-src 'self'; object-src 'none'; style-src 'self'

These defaults can’t be overridden, only added to, i.e. the CSP policy in the manifest can only make the actual CSP applied more restrictive in the case of privileged/internal apps.

Serving manifest

Note: This is applied to 'hosted app URL'

The app manifest must be served from the same origin that the app is served from.

The manifest should be stored with a file extension of .webapp. App manifests must be served with a Content-Type header of application/x-web-app-manifest+json. This is currently enforced by the KaiStore. The KaiStore only checks this if the origin of the page where the user triggers the install is different from the origin of the app itself. You don't need other headers such as Content-Security-Policy and X-UA-Compatible.

Manifests can be served over SSL to mitigate certain classes of attacks. You can also serve the manifest with HTTP compression. The manifest should not be cached.

The manifest must be in UTF-8 encoding in order for the app to be submitted to the KaiStore. It is recommended that you omit the byte order mark (BOM). Other encodings can be specified with a charset parameter on the Content-Type header.

User Agents when possible should meaningfully message the site identity and TLS status when prompting a user to install an app.