Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

1. Abstract

This spec defines a CBOR wire format for World ID authenticators to exchange requests, responses and notifications. The method field MUST use underscore-separated camelCase segments prefixed with worldid. Other WIPs define the methods and their payloads.

It also defines worldid:// deeplinks, which SHOULD follow a namespace, version and action structure. The details of individual deeplinks are defined by the protocols that use them.

2. Motivation

World ID supports authenticators from different providers and on different platforms. A shared message and deeplink format lets them communicate over different transports.

3. Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

3.1 Message format

3.1.1 Encoding

Messages MUST be encoded using CBOR (RFC 8949). Each transport message MUST contain exactly one CBOR map: a request, response or notification. Receivers MUST reject trailing bytes and validate the whole message before executing the request, including the duplicate-key and resource checks below.

The transport defines message boundaries, routing, authentication and encryption.

Envelope field names are case-sensitive CBOR text strings. Binary payloads MUST use CBOR byte strings. Each method’s defining WIP specifies its parameter and result schemas.

Senders MUST NOT emit maps with duplicate keys. Receivers MUST reject a message in which any key they interpret, including envelope fields and fields of the method’s parameter or result schema, appears more than once in the same map. Receivers MAY accept duplicates of keys they ignore.

Each transport specification MUST set a maximum encoded message size and define what happens when it is exceeded. Implementations MUST limit nesting depth and resource use. Receivers MAY drop messages that exceed these limits or fail transport authentication without replying.

3.1.2 Requests and notifications

Either peer MAY send a request. For each request, the sender is the caller and the receiver is the responder.

A notification is a valid request without an id field. The responder MUST NOT reply to a valid notification, even if execution fails, the method is unknown or its arguments are invalid. A malformed request without an id is not a notification.

A request is a map with these fields:

FieldRequiredTypeMeaning
versionYesText stringMUST be "1.0", the envelope version defined by this WIP.
methodYesText stringMethod name following §3.2.
paramsNoAny CBOR valueArguments conforming to the method’s parameter schema.
idNoText stringID used to match the response to the request. Omit for notifications.

Request IDs MUST NOT be null. Callers MUST NOT reuse an ID while waiting for the response to that ID from the same peer in the same session.

For a valid request with an id, the responder MUST return one response with the same ID value.

Omitting params means no arguments were supplied. A present value, including null, MUST conform to the method’s parameter schema. Requests MUST NOT contain fields other than those in the table. Receivers MUST reject unknown envelope fields.

3.1.3 Responses

A response is a map with these fields:

FieldRequiredTypeMeaning
versionYesText stringMUST be "1.0".
idYesText string or nullThe request ID, or null for an uncorrelated error as defined in §3.1.4.
resultOn successAny CBOR valueThe method-defined result, including null when allowed by its schema.
errorOn failureMapFailure details as defined below.

A response MUST contain exactly one of result or error. A success always has a non-null ID. An error always includes its id field, even when null. A null error ID MUST NOT be matched to a pending request. Receivers MUST reject unknown response envelope fields.

The failure details map has these fields:

FieldRequiredTypeMeaning
codeYesText stringStable, case-sensitive failure code.
messageYesText stringShort human-readable explanation.
dataNoAny CBOR valueAdditional details defined by the method or error code. A present null value is distinct from omission.

Unknown fields in the error map MUST be ignored. Callers MUST match responses to requests by id, not arrival order. They MUST NOT reply to invalid or unmatched responses, or accept them as successful results. Implementations SHOULD report these as local protocol errors.

3.1.4 Errors

The following error codes are shared by all methods:

CodeMeaning
parse_errorThe message does not follow the CBOR encoding rules in §3.1.1.
invalid_requestThe request is malformed, or its envelope version is unsupported.
method_not_foundThe requested method is not available.
invalid_paramsThe arguments do not match the method’s parameter schema.
internal_errorThe responder could not complete the call because of an internal error.

Method-specific error codes MUST be defined by the method’s WIP and MUST NOT reuse the codes above. Callers MUST use code, not message, to identify an error.

Whether to reply to a parse error is transport-defined. If a parse error response is sent, it MUST use id: null. For an invalid request, the responder MUST copy its ID into id if it can read a single, unambiguous text string ID; otherwise it MUST use null. Error responses MUST use version: "1.0". Responders MUST NOT send errors in reply to notifications or responses.

3.1.5 Examples

These examples show CBOR diagnostic notation. h'0102ff' represents the three bytes 01 02 ff.

Request with an inline binary argument:

{
  "version": "1.0",
  "method": "worldid_example_v1_process",
  "params": {"payload": h'0102ff'},
  "id": "request-1"
}

Successful response with an inline binary result:

{"version": "1.0", "id": "request-1", "result": h'0304'}

Failure response:

{
  "version": "1.0",
  "id": "request-1",
  "error": {"code": "invalid_params", "message": "Unexpected payload length"}
}

Successful response with a nullable result:

{"version": "1.0", "id": "request-1", "result": null}

Uncorrelated parse error:

{"version": "1.0", "id": null, "error": {"code": "parse_error", "message": "bad"}}

Notification (no response, including on failure):

{"version": "1.0", "method": "worldid_example_v1_process", "params": {"payload": h'0102ff'}}

3.2 Methods

The method field MUST consist of camelCase segments joined by underscores _. The first segment MUST be worldid. For example worldid_auth_v1_register.

The method, params, result and error fields MUST be defined in a WIP. This spec does not introduce specific methods.

Deeplinks MUST be URIs (RFC 3986) with the scheme worldid. They SHOULD have the form:

worldid://{namespace}/{version}/{action}?{parameters}

namespace is the protocol area, version is v followed by a positive integer, and action is the operation the deeplink starts. For example worldid://auth/v1/register.

Authenticators SHOULD register the worldid scheme with the operating system where the platform allows.

Deeplinks MUST be defined in a WIP. This spec does not introduce specific deeplinks.

4. Backwards Compatibility

This WIP defines a new message format and deeplink format. It does not modify existing protocol behavior, contracts or stored data, and implementations that do not exchange authenticator messages are unaffected. Existing worldid URIs that are not defined by a WIP are not affected.