Messages and envelopes
Messages in this version are JSON objects carried by a transport. The transport may be postMessage, HTTP, an MCP facade, an extension channel, or a future browser proposal. Envelope semantics do not change with the transport.
Common request fields
Every request MUST contain:
| Field | Requirement |
|---|---|
protocol | The exact value pling.surface/0.1 |
id | A non-empty string unique to this logical call within the session |
method | describe or invoke |
id associates the response, audit event, and error. A client MUST NOT reuse one id for independent business calls. A server MUST NOT execute invoke again merely because it retransmits a response.
describe request
{
"protocol": "pling.surface/0.1",
"id": "req_01",
"method": "describe",
"input": {
"limit": 8,
"capabilities": "full"
}
}2
3
4
5
6
7
8
9
input MAY be omitted. Supported fields:
| Field | Constraint | Meaning |
|---|---|---|
record | Non-empty string, or an array of one to twenty ids | Read selected records |
offset | Non-negative integer | Record-window start |
limit | Non-negative integer, subject to implementation maximum | Record-window size |
capabilities | full or changed | Return a full list or an unchanged signal |
record MUST NOT be combined with offset or limit. Unknown describe.input fields SHOULD be rejected. capabilities: "changed" SHOULD be used only when the client retained the previous description in the same session.
Successful describe
{
"protocol": "pling.surface/0.1",
"id": "req_01",
"ok": true,
"result": {
"app": "orders",
"capabilities": [],
"context": {
"regions": [],
"records": [],
"recordIds": [],
"recordIdsTotal": 0,
"state": {},
"feedback": [],
"unavailable": [],
"recordsTotal": 0,
"feedbackTotal": 0,
"unavailableTotal": 0
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
The response protocol MUST match the request version. Capability and context semantics are defined by the Capability model and Context model.
invoke request
{
"protocol": "pling.surface/0.1",
"id": "req_02",
"method": "invoke",
"capability": "order.update_note@order",
"input": {
"record": "SO-1002",
"note": "Call before Friday"
}
}2
3
4
5
6
7
8
9
10
capability MUST be non-empty and MUST come from the current session's visible list. input MUST be an object; omission is equivalent to an empty object. A folded template's target record MUST be placed in input.record; other properties follow that capability's schema.
Successful invoke
Protocol success does not mean business success. The business result may still be a structured error:
{
"protocol": "pling.surface/0.1",
"id": "req_02",
"ok": true,
"result": {
"error": {
"code": "ACTION_UNAVAILABLE",
"message": "The record is locked"
}
}
}2
3
4
5
6
7
8
9
10
11
A business success may be any JSON value defined by the executor. The client MUST check both ok and result.error.
A successful response MAY include after:
{
"protocol": "pling.surface/0.1",
"id": "req_02",
"ok": true,
"result": { "title": "Note updated" },
"after": {
"records": [{ "id": "SO-1002", "fields": { "note": "Call before Friday" } }],
"state": { "filter": "all" }
}
}2
3
4
5
6
7
8
9
10
after is an incremental observation, not proof of authorization and not a full snapshot. Capabilities, records, and omitted counts MUST be bounded.
Protocol failure
Envelope, version, method, exposure, session, rate-limit, or internal failures use:
{
"protocol": "pling.surface/0.1",
"id": "req_02",
"ok": false,
"error": {
"code": "CAPABILITY_NOT_EXPOSED",
"message": "The capability is outside the current exposure"
}
}2
3
4
5
6
7
8
9
id MAY be empty when it cannot be parsed. message is diagnostic; clients MUST NOT branch on its text. Stable behavior is keyed by error.code.
Processing order
A server SHOULD process in this order:
- validate object,
id,protocol, andmethod; - resolve and validate the session when required;
- apply the rate limit;
- validate method-specific fields;
- for
invoke, validate capability, record, and replay; - call the existing executor;
- produce bounded
afterdata and an audit event.
An implementation MUST NOT leak an unstructured exception to the caller. Unknown versions, unknown methods, and internal exceptions MUST produce ok: false.
Versioning and compatibility
A client MUST send the exact version value. A server MUST return PROTOCOL_VERSION_UNSUPPORTED for an unsupported version and MUST NOT guess a newer interpretation. Future optional response fields SHOULD be safe for older clients to ignore. An older client MUST NOT treat an unknown state as success or approval.
Size and caching
The transport MUST bound request and response size and reject an oversized request with a clear error. describe results are not cached by default. An implementation MAY provide session-scoped increments, but the cache MUST be bound to the session and scope. Navigation, permission changes, or revocation MUST invalidate old descriptions.

