Build on the Mesh
portal.json
The manifest a registrant publishes beside the portal.js snippet. It helps tools find a portal; it never vouches for one.
What it is
portal.json is a small manifest a registrant publishes on their own website, so that a browser or a tool can find the portal: its locked address, where to resolve it, which root key to expect, and the modes and directions the owner set.
The format
{
"schema": "pm.portal/1",
"address": "activate://oasis.character",
"name": "oasis.character",
"pid": "pid:01JBX3Q8Z9M4T7K2V5N6R8W0YC",
"namespace": "character",
"family": "identity",
"scheme": "activate",
"defaultDirection": "bring",
"directions": [
"bring"
],
"modes": [
"text",
"voice"
],
"resolvers": [
"https://pns1.portalmesh.net",
"https://pns2.portalmesh.net",
"https://pns3.portalmesh.net",
"https://pns4.portalmesh.net"
],
"root": {
"kid": "jubilee-root-example",
"publicKey": {
"kty": "OKP",
"crv": "Ed25519",
"x": "PUAXw-hDiVqStwqnTRt-vJyYLM8uxJaMwM1V8Sr0Zgw"
}
},
"certificate": "https://theportalmesh.com/certificate/pid:01JBX3Q8Z9M4T7K2V5N6R8W0YC",
"library": "https://files.theportalmesh.com/portal.js",
"persona": {
"hash": "sha256:f666f7b6e5c7b0a0c94366a7b55b902d2d3c1fb6d6d130922c70f7a274f00a24",
"profile": "https://files.theportalmesh.com/personas/f666f7b6e5c7b0a0c94366a7b55b902d2d3c1fb6d6d130922c70f7a274f00a24.json"
}
}| Field | Meaning |
|---|---|
schema | pm.portal/1 |
address | The name with its locked scheme. |
name | The portal name. |
pid | Its permanent ID. |
namespace | The namespace, without its dot. |
family | identity, destination or experience. A record or certificate signed before October 25, 2026 may say environment or place, the two families that became Destinations. |
scheme | activate, portal or experience. |
defaultDirection | The namespace’s default, go or bring. |
directions | The directions the owner set at activation. |
modes | The modes the owner set at activation. |
resolvers | The PNS server origins, in the order to try them. |
root | { kid, publicKey }: the root key the registry signed with, as a JWK. |
persona | Persona namespaces: { hash, profile } from the PERSONA record. Left out otherwise. |
certificate | The address of the name's certificate page. |
library | The address of portal.js. |
Where it comes from
The registry builds the manifest when a name is activated. POST /v1/names/:pid/activate returns it as manifest, beside the two-line snippet. Activating an active name again, with new modes or directions, returns a fresh one.
- The address, family, scheme and default direction come from the namespace.
- The modes and directions are the ones chosen at activation; each must be offered by the signed ENDPOINT record.
- The resolvers and the root key are the registry’s own configuration.
- The persona comes from the PERSONA record.
The registry does not fix a path for the file. Serve it as application/json wherever suits your site, and replace it when you activate again.
Using it safely
- Never take the root key from
portal.jsonto verify the same portal. Pin the root key you trust, as portal.js does. - Treat every field as a hint: resolve the address from PNS and run the full verification chain.
- PNS and portal.js decide modes and directions from the signed ENDPOINT record, not from this file. If the two ever differ, the signed record wins.