Meshline
English translationDownload Markdown

The Simplified Chinese text is authoritative.

Group Lifecycle and Synchronization Methods

Group Hosting Protocol · Common Method Conventions

group.create

The calling account creates a group through group.create and becomes its owner on success. The creator first generates the group ID, a 32-byte client_group_secret, and a member X25519 key pair, computes the client-secret commitment according to Client and Relay Secrets, and then seals a client-secret box to its own member public key.

Item Convention
HTTP POST /meshline/v1/group/create
Session requirement Device session
WSS group.create
HTTP success status 204 No Content

Request Parameters

Field Type Required Semantics and constraints
create GroupCreate Yes The complete group-creation object signed by the creator; becomes the sequence 0 event's payload unchanged
client_secret_box GroupSecretBox Yes The creator's client-secret box

GroupCreate fields:

Field Type Required Semantics and constraints
$type string Yes Fixed to meshline.group.create
group_id string Yes A new group ID jointly derived from the initial owner's account, the current hosting relay, and nonce according to Group ID
nonce string Yes A 16-byte value generated by the creator for this group according to Group ID, encoded as unpadded base64url; used to derive the group ID and immutable throughout the group lifecycle
name string Yes Initial group name; MUST contain at least one non-whitespace character and be at most 256 bytes in UTF-8
description string No Initial description; if nonempty, MUST NOT consist solely of whitespace characters and MUST be at most 4 KiB (4,096 bytes) in UTF-8
member_capacity integer Yes Initial member capacity; MUST be positive and no greater than the maximum group member count declared by relay.info; the creator occupies one slot
invite_policy string Yes Initial member invitation policy; values and meanings are defined by GroupState.invite_policy
owner object Yes Initial owner information
client_secret_commitment string Yes Initial client-secret commitment, using the sha256: textual representation
device_signature string Yes Signed by the initial owner's device used for this call; the signature input is the complete GroupCreate excluding this field

owner contains:

Field Type Required Semantics and constraints
account string Yes The account creating the group and becoming its initial owner; MUST be the calling account and the creator account used to derive group_id
member_encryption_public_key string Yes The initial owner's 32-byte X25519 public key, encoded as unpadded base64url

Response Object

None.

Processing and Errors

The relay identifies the calling account and device through the device session, verifies the creation signature, confirms that the account in the device certificate, owner.account, and the calling account are identical, verifies that the group ID is derived from that account, the current relay, and nonce, and checks the representations of the initial owner's member encryption public key and the client-secret commitment. The creator's key box is validated according to Client-Secret Boxes.

Invalid fixed values, group ID derivation, name, description, capacity, invitation policy, key, commitment, or key-box encoding return bad_request. An incompatible session mode or an initial owner other than the calling account returns forbidden. An existing group ID or concurrent creation conflict returns state_conflict.

On success, the relay creates the member record and the creator device's access interval from the initial owner information in the creation object, fixes the declared client-secret commitment as the group's current commitment, generates the epoch 0 relay secret, saves the initial owner's member public key, the creation event's verification certificate, the epoch 0 key entry, and the initial owner's client-secret box, and atomically appends the sequence 0 creation event.

Signature inputs, management-chain digests, and event bodies MUST preserve the distinction between an omitted field and an explicit empty string; fields MUST NOT be inserted or removed before signature verification or digest computation.

group.resolve

Queries the group's current state for current members or for nonmembers with a valid invitation before joining.

Item Convention
HTTP GET /meshline/v1/group/resolve
Session requirement Device session
WSS group.resolve
HTTP success status 200 OK

Request Parameters

Field Type Required Semantics and constraints
group_id string Yes The group whose current state is requested; MUST be hosted by the current relay
invite_id string No Invitation ID used by a nonmember to read the pre-join state; current members may omit it, while nonmembers MUST supply an invitation that is still valid and applicable to them

Response Object

Returns the current GroupState.

Processing and Errors

Current members who are not banned can query the group state directly. Accounts that have not joined MUST supply an invitation that is valid, unrevoked, has remaining uses, and applies to them. Reading the state neither consumes an invitation use nor creates an application. Banned accounts cannot obtain read access through an invitation.

An invalid group ID or supplied invitation ID format returns bad_request; a nonexistent group returns not_found; a banned caller, or a nonmember without an applicable valid invitation, receives forbidden.

group.sync

Reads the group timeline visible to the current device by sequence, allowing clients to verify the management chain, reconstruct group state, and process group messages.

Item Convention
HTTP GET /meshline/v1/group/sync
Session requirement Device session
WSS group.sync
HTTP success status 200 OK

Request Parameters

Field Type Required Semantics and constraints
group_id string Yes The group whose events are to be synchronized
after integer No Read starting position; only events with a greater sequence are returned. Omit or use -1 for the first synchronization. MUST be at least -1 and no greater than the current timeline head; need not identify an existing event
limit integer No Maximum events returned in this page; MUST be a positive safe integer, subject to the pagination conventions

Response Object

Field Type Required Semantics and constraints
events array<GroupEvent> Yes The page of events read; strictly increasing by sequence, possibly empty, with no requirement for consecutive numeric values
certificates array<DeviceCertificate> Yes Historical signing certificates referenced by this page's event signer_device_id values; deduplicated by derived device ID
has_more boolean Yes Whether more readable events existed when this page was generated; MUST be false for an empty page

Readable Events and Pagination

Before returning events, the relay MUST confirm that the account and device currently have group read access and return only readable events satisfying the requested position. All management events are readable regardless of device message access intervals; message events are readable only within the device's authorized intervals and while they have not been pruned.

events and has_more MUST come from the same read snapshot. The relay MUST NOT skip management or message events that remain readable. Pruned messages and messages outside authorized intervals are skipped and do not occupy page entries. When has_more = true, continue from the last item's sequence; when it is false, this paginated read is complete.

A pagination position does not mean that the client has finished verifying and processing the corresponding events. Advancing the synchronization position follows Group Timeline and Synchronization Rules. Sequence gaps alone do not indicate missing events.

Event Verification and State Reconstruction

A client without locally verified group state MUST start from -1 to obtain the creation event, verify the expected group identity according to the management-chain rules, and reconstruct state event by event. A client with verified local group state may continue from a synchronization position consistent with that state.

The client validates this page's certificates according to the signature and identity rules of DeviceCertificate, rejecting responses with duplicate device IDs, missing certificates, or mismatched references. For client-initiated events, it locates the certificate by signer_device_id and verifies the payload signature using the account and signing public key in that certificate. Relay-initiated rotations are checked against their body definition. Subsequent certificate renewal, expiry, or device removal does not invalidate an original event's signature; historical authorization is determined from preceding group state in the management chain.

Event sequence values strictly increase, and epoch MUST NOT decrease. Known events that advance keys MUST strictly increase the version; in a complete timeline, events that do not advance keys retain the preceding event's version. A message envelope's epoch MUST equal the outer event's value, and the group, device certificate, and message-envelope signature MUST be valid.

Key Retrieval and Message Processing

Events and key material can be read independently. Member private keys obtained through same-account messages are validated, stored, and used according to GroupMemberPrivateState.

Once a group message envelope passes these checks and the corresponding application secret is available, the client checks the sending-account context and decrypts according to Group Message Key Derivation, Encryption, and Decryption, then validates the result against its business-object $type before processing it.

When the corresponding historical private key or key material is unavailable, the client may persist the verified message envelope pending later decryption. Invalid message signatures, ciphertext authentication failures, and invalid business content may be persisted as rejection results. Required keys are obtained through group.key.sync under their original key permissions.

Processing and Errors

The calling account MUST be a current member who is not banned. For a device requiring a new interval, message and key access starting points are established according to Device Access Intervals, while allowing it to read all earlier management events. Failed parameter or authorization checks do not establish a new interval.

An invalid group ID, after, or limit, or a requested position beyond the current timeline head, returns bad_request. A nonexistent group returns not_found. An account that has left, been removed, or been banned, or a device without current read access, receives forbidden.

group.close

The current owner permanently closes the group through group.close. No further group timeline events may be appended after closure. Read service and retention of messages and keys after closure are not guaranteed.

Item Convention
HTTP DELETE /meshline/v1/group/close
Session requirement Device session
WSS group.close
HTTP success status 204 No Content

Request Parameters

Field Type Required Semantics and constraints
$type string Yes Fixed to meshline.group.close
group_id string Yes The group the current owner intends to close permanently
prev_hash string Yes Digest of the preceding management-chain entry; MUST still be the current chain head at submission
device_signature string Yes Signed by the current owner using the device for this call; the signature input is the complete closure request excluding this field

Response Object

None.

Processing and Errors

Invalid request format or fixed values return bad_request; a nonexistent group returns not_found; a caller who is not the current owner or is banned receives forbidden; concurrent state changes or an already closed group return state_conflict.

On success, the operation appends the final closure event, permanently changes the state to closed, and closes all current device access intervals. The closure event retains the pre-closure epoch.