Calls, events and orgs
Calls and views
Section titled “Calls and views”let answer = try await client.call(app, "send_message", ["message": "hi"]) // POST /apps/{app}/intentsanswer.index; answer.result; answer.eventslet read = try await client.view(app, "get_messages", [:]) // POST /apps/{app}/views- A call carries an idempotency key (
node:c-…unless you pass one). While the node answers503or cannot be reached, the same request with the same key is sent again: 6 retries, 200 ms doubling to 2 s, or the node’sRetry-Afterwhen longer (CloudRetryOptions). ThenUnavailableError, whosecommittedis.noor.unknown. - An app’s own refusal is
AppErrorwithappCodeandfields. callJSON/viewJSONtake and return JSON bytes, every number as written (au64beyond 2^53);CloudContextContractuses them.
Events
Section titled “Events”for try await event in client.events(app, from: 0) { … } // GET /apps/{app}/events, sealed SSEEach event has id (index:seq), kind and data. Cancel the task (or stop
iterating) to close the stream.
Orgs, teams, invites
Section titled “Orgs, teams, invites”| Call | Route |
|---|---|
orgs.create(name:recoveryKey:), orgs.get(org:), orgs.metadata(org:metadata:) |
/orgs, /orgs/{org} |
setRecoveryKey(org, publicKey:, passkey:), startRecovery(org, seed:), orgs.recoveryCancel(org:passkey:), orgs.recoveryFinish(org:passkey:) |
/orgs/{org}/recovery… |
orgs.teamCreate(org:name:join:), orgs.teamGet, updateTeam, orgs.teamDelete |
/orgs/{org}/teams/… |
orgs.setMember, orgs.removeMember, orgs.teamSetMember, orgs.teamRemoveMember, orgs.capabilities (each with passkey:) |
/orgs/{org}/members, …/capabilities |
orgs.inviteCreate(org:role:teams:passkey:) → .token (inv_…) |
POST /orgs/{org}/invites |
orgs.inviteRedeem(token:) |
POST /invites/{token}/redeem |
apps.create(name:package:org:access:) (access: AppAccess.team(id).generated) |
POST /apps |
auth.me() lists the account’s organizations; orgs.get(org:) answers the organization, its teams, members and their metadata; OrgInfo(json: try JSONValue(encoding: org)) reads it as MeroKit’s type.
An owner who loses every passkey gets the organization back with its recovery seed (core rc.9+). The seed never leaves the device: the node stores only its public key and checks a signature the seed makes for the recovering account.
let seed = RecoverySeed()showToOwner(seed.text) // 64 hex digits in groups of eight; keep it offlinelet org = try await client.orgs.create(name: "Acme", recoveryKey: seed.publicKey).orgId
// Every passkey lost: sign up again with a new passkey, thenlet times = try await fresh.startRecovery(org, seed: try RecoverySeed(text: written))// 72 hours later (the owner may orgs.recoveryCancel; members see OrgInfo.recovery?.pending)_ = try await fresh.orgs.recoveryFinish(org: org, passkey: newPasskey) // RecoveryNotReady before readyAtRotating the key (setRecoveryKey) cancels a recovery under way, and the old
seed is refused from then on.
Blobs and presence
Section titled “Blobs and presence”apps.blobUpload(app:body:contentType:) (the node stores the blob with the
contentType you name and answers downloads with it; leave it out and it is
sent as application/octet-stream), apps.blobDownload(app:id:grant:)
(grant: no session, a grant one of the app’s runs handed out),
blobContent(app, id, grant:) (bytes and content type), listBlobs,
blobInfo, apps.blobDelete(app:id:) on
/apps/{app}/blobs; uploadFile(app, data) for a component app’s sealed file
(core rc.9+: only the app’s code reads it; its owner and organization members
upload it, and see sealed and the plaintext’s sha256 in listBlobs and
blobInfo); appXcalls(app) for a component app’s outbox and dead
letters; publishPresence, presence,
presenceStream on /apps/{app}/presence.
let png = try Data(contentsOf: imageURL)let blob = try await client.apps.blobUpload(app: app, body: png, contentType: "image/png")let content = try await client.blobContent(app, blob.blobId) // content.contentType == "image/png"