Skip to content

Manifest — /.well-known/gerege-miniapp.json

Every mini app MUST publish a manifest on its own origin:

https://<origin>/.well-known/gerege-miniapp.json      ← tried first
https://<origin>/.well-known/openpay-miniapp.json     ← the OMAS name, if the first is absent

Content-Type: application/json, ≤ 64 KB, no redirects (the platform does not follow redirects). The platform connects only to public IP addresses (checked after DNS) — a manifest hosted on an internal network cannot be read. http://localhost is allowed only on installations that are not production. If manifest_url is set explicitly in the developer console, only that address is read (it must end in one of these two paths and have the same origin as entry).

The manifest is proof of origin ownership: only someone who can publish the verification token issued at registration on that origin owns that origin. JSON Schema: schemas/manifest.schema.json.

Example

{
  "omas_version": "1.0",
  "slug": "esim",
  "client_id": "mapp_7Qk2c9Xv0bR1aB3dE5fG7hJ9",
  "version": "1.0.0",
  "name": { "mn": "Аяллын eSIM", "en": "Travel eSIM" },
  "subtitle": { "mn": "200+ улсад дата" },
  "category": "travel",
  "developer": { "name": "Жишээ ХХК", "email": "support@example.mn", "url": "https://example.mn" },
  "entry": "https://esim.example.mn/app",
  "origins": ["https://esim.example.mn"],
  "icons": [{ "src": "https://esim.example.mn/icon-512.png", "size": 512 }],
  "accent_color": "#3B82F6",
  "scopes": ["profile.basic", "payments"],
  "bridge": { "min_version": 1, "methods": ["getContext", "getLaunchCode", "requestPayment", "openExternal", "copy", "share", "haptic", "setTitle", "close"] },
  "external_urls": ["https://esimsetup.apple.com/"],
  "channels": ["ios", "android"],
  "webhook_url": "https://esim.example.mn/webhooks/gerege",
  "legal": { "privacy_url": "https://example.mn/privacy", "terms_url": "https://example.mn/terms", "support_url": "https://example.mn/help" },
  "verification": "omas-verify=3f9c1e7a2b4d6f80a1c3e5f7"
}

Fields

Field Required Rule
omas_version ✓ "1.0"
slug ✓ ^[a-z0-9-]{2,32}$, matches the registry, never changes
client_id ✓ mapp_… or mapp_test_… — the app's live or test id
version ✓ semver (1.2.3, 1.2.3-beta.1) — kept in the review history
name.mn ✓ 1–24 characters; name.en optional
subtitle.mn ≤ 40 characters
category ✓ travel · shopping · finance · games · services · food · transport · utilities
developer ✓ name (1–80), email, url (https, optional)
entry ✓ https, within one of origins, exactly equal to the registry's entry_url. The host appends ?launch=<code>&path=<path>
origins ✓ 1–3 origins (https://host[:port], no path). The origin the manifest was fetched from and every origin in the registry are listed here
icons ✓ ≥ 1; size ∈ 128/256/512/1024; 512 required. PNG, opaque, no rounded corners
accent_color ✓ #RRGGBB
scopes ✓ profile.basic required. Every scope in the registry is declared here (auth.md §4)
bridge.min_version ✓ ≥ 1
bridge.methods ✓ Names from bridge.md §3. Applied to the registry when the check passes
external_urls ≤ 20 https prefixes — opened with openExternal. Applied to the registry by the check
requires_verified boolean. When true, a person not verified with eID cannot open the app (403 verification_required) — auth.md §1.1
min_age 13–21 or null. Under age → 403 age_restricted; not verified → 403 verification_required
channels ✓ ios, android, web (android added over OMAS). The host that works today is iOS
webhook_url https. REQUIRED with the payments scope. The URL and secret are set in the console (webhooks.md)
legal.* ✓ privacy_url, terms_url, support_url — https, in Mongolian
verification ✓ The omas-verify=… issued at registration

An unknown field → an error (Үл мэдэгдэх талбар, "unknown field"). Every error comes with a JSON-pointer path (/icons/0/size).

Cross-checking with the registry

«Manifest шалгах» ("Check manifest", POST /api/v1/miniapp/dev/apps/{id}/manifest/check), beyond the schema:

  • slug, client_id, verification and entry match the registry;
  • entry and the origin the manifest was fetched from are within origins; every registry origin and scope is in the manifest;
  • the 512 icon is fetched and checked: PNG, exactly 512×512;
  • legal.privacy_url, terms_url and support_url each answer 200 (redirects are not followed — a redirect is an error);
  • an approved app may narrow bridge.methods and external_urls but not widen them — that needs a new review; it may tighten requires_verified / min_age but not loosen them.

The icon and the legal pages are fetched with the same SSRF-guarded client as the manifest (public addresses only).

Response: {ok, fetched_from, errors: [{path, message}], manifest}. On success manifest_checked_at, manifest_version, the bridge methods, external links, requires_verified and min_age are written to the registry. The host works from the registry — it does not fetch the manifest at runtime.