r*.online Ecosystem — API Reference
Complete endpoint documentation for all modules
Version: 1.0.0
Last Updated: February 2026
Authentication
All modules authenticate via EncryptID (WebAuthn passkeys + JWT).
Token Acquisition
POST https://auth.ridentity.online/api/auth/start
→ { challenge, allowCredentials }
POST https://auth.ridentity.online/api/auth/complete
← { token: "eyJ..." }
Token Transport
Attach the JWT to requests using one of:
| Method |
Format |
Use Case |
| Header |
Authorization: Bearer <token> |
API calls |
| Cookie |
encryptid_token=<token> |
Browser navigation |
| Query |
?token=<token> |
WebSocket upgrade |
| Subprotocol |
Sec-WebSocket-Protocol: encryptid.<token> |
WebSocket upgrade |
JWT Claims
{
"sub": "user_abc123",
"did": "did:key:z6Mk...",
"username": "ana",
"authLevel": 2,
"aud": ["rspace.online", "rvote.online", "rnotes.online"],
"iat": 1708000000,
"exp": 1708086400
}
Auth Levels
| Level |
Name |
Grants |
| 1 |
BASIC |
Read-only operations |
| 2 |
STANDARD |
Create and edit own resources |
| 3 |
ELEVATED |
Moderate other users' resources |
| 4 |
CRITICAL |
Admin operations, key management |
Space Roles & Permissions
Every request within a space is authorized against a SpaceRole:
| Role |
Level |
Default For |
| VIEWER |
0 |
Anonymous users in PUBLIC_READ spaces |
| PARTICIPANT |
1 |
Anonymous users in PUBLIC spaces, authenticated users in PUBLIC_READ |
| MODERATOR |
2 |
Explicitly granted |
| ADMIN |
3 |
Space owner, explicitly granted |
Checking Capabilities
Each module defines a capability map. Example (rVote):
import { hasCapability, SpaceRole, RVOTE_PERMISSIONS } from '@encryptid/sdk';
// Returns true if user's role meets minimum for capability
hasCapability(SpaceRole.PARTICIPANT, 'cast_vote', RVOTE_PERMISSIONS); // true
hasCapability(SpaceRole.VIEWER, 'cast_vote', RVOTE_PERMISSIONS); // false
Common Patterns
Error Responses
All modules return errors in this format:
{
"error": "Not authorized",
"code": "FORBIDDEN",
"status": 403
}
| Status |
Meaning |
| 400 |
Invalid request body or parameters |
| 401 |
Missing or invalid authentication token |
| 403 |
Authenticated but insufficient permissions |
| 404 |
Resource not found |
| 409 |
Conflict (duplicate slug, concurrent edit) |
| 429 |
Rate limited |
| 500 |
Internal server error |
Modules using Prisma support cursor-based pagination:
GET /api/proposals?cursor=abc123&take=20
Space Scoping
Most endpoints are scoped to a space via subdomain:
https://crypto.rvote.online/api/proposals → proposals in "crypto" space
https://coop.rnotes.online/api/notebooks → notebooks in "coop" space
EncryptID Server
Base URL: https://auth.ridentity.online
Tech: Hono.js on Bun | PostgreSQL
Registration
| Method |
Path |
Auth |
Description |
| POST |
/api/register/start |
None |
Begin WebAuthn registration, returns challenge + options |
| POST |
/api/register/complete |
None |
Complete registration, store credential, return JWT |
Authentication
| Method |
Path |
Auth |
Description |
| POST |
/api/auth/start |
None |
Begin authentication, returns challenge |
| POST |
/api/auth/complete |
None |
Complete authentication, return JWT |
Session Management
| Method |
Path |
Auth |
Description |
| GET |
/api/session/verify |
Bearer |
Verify token validity, returns claims |
| POST |
/api/session/verify |
Body |
Verify token passed in request body |
| POST |
/api/session/refresh |
Bearer |
Refresh expired token (1h grace period) |
Credential Management
| Method |
Path |
Auth |
Description |
| GET |
/api/user/credentials |
Bearer |
List user's registered passkeys |
Recovery
| Method |
Path |
Auth |
Description |
| POST |
/api/recovery/email/set |
Bearer |
Set recovery email address |
| POST |
/api/recovery/email/request |
None |
Request recovery email (30-min token) |
| POST |
/api/recovery/email/verify |
None |
Verify recovery token, issue new session |
Membership (NEW — Phase 4)
| Method |
Path |
Auth |
Description |
| POST |
/api/spaces/:slug/members |
Admin |
Add or update member in space |
| GET |
/api/spaces/:slug/members |
Bearer |
List all members of a space |
| GET |
/api/spaces/:slug/members/:did |
Bearer |
Get one member's role in space |
| DELETE |
/api/spaces/:slug/members/:did |
Admin |
Remove member from space |
rVote — Decision Engine
Base URL: https://{space}.rvote.online
Tech: Next.js App Router | PostgreSQL (Prisma) | NextAuth
Proposals
| Method |
Path |
Auth |
Description |
| GET |
/api/proposals |
Optional |
List proposals (filterable by status) |
| POST |
/api/proposals |
PARTICIPANT |
Create new proposal |
| GET |
/api/proposals/:id |
Optional |
Get proposal with vote data |
| PATCH |
/api/proposals/:id |
Author |
Edit proposal (before voting phase) |
| DELETE |
/api/proposals/:id |
Author |
Delete proposal (before voting phase) |
Voting
| Method |
Path |
Auth |
Description |
| POST |
/api/proposals/:id/vote |
PARTICIPANT |
Cast or update ranking vote (spend credits) |
| DELETE |
/api/proposals/:id/vote |
PARTICIPANT |
Remove vote (refund credits) |
| GET |
/api/proposals/:id/final-vote |
Optional |
Get final vote counts (YES/NO/ABSTAIN) |
| POST |
/api/proposals/:id/final-vote |
PARTICIPANT |
Cast final vote on promoted proposal |
Credits
| Method |
Path |
Auth |
Description |
| GET |
/api/user/credits |
Bearer |
Get user's available and stored credits |
| POST |
/api/user/credits |
Bearer |
Claim accumulated daily credits |
Spaces
| Method |
Path |
Auth |
Description |
| GET |
/api/spaces |
Bearer |
List user's spaces |
| POST |
/api/spaces |
Bearer |
Create new space |
| GET |
/api/spaces/:slug |
Optional |
Get space details |
| PATCH |
/api/spaces/:slug |
ADMIN |
Update space settings |
| DELETE |
/api/spaces/:slug |
Owner |
Delete space |
Members
| Method |
Path |
Auth |
Description |
| GET |
/api/spaces/:slug/members |
Bearer |
List space members with roles |
| POST |
/api/spaces/:slug/members |
ADMIN |
Add member by email |
| PATCH |
/api/spaces/:slug/members/:userId |
ADMIN |
Update member role |
| DELETE |
/api/spaces/:slug/members/:userId |
ADMIN |
Remove member |
Invites
| Method |
Path |
Auth |
Description |
| GET |
/api/spaces/:slug/invites |
ADMIN |
List active invite links |
| POST |
/api/spaces/:slug/invites |
ADMIN |
Create invite link |
| DELETE |
/api/spaces/:slug/invites/:id |
ADMIN |
Revoke invite link |
| GET |
/api/spaces/join/:token |
Bearer |
Join space via invite token |
rNotes — Collaborative Notebooks
Base URL: https://{space}.rnotes.online
Tech: Next.js App Router | PostgreSQL (Prisma) | Automerge CRDT
Notes
| Method |
Path |
Auth |
Description |
| GET |
/api/notes |
Bearer |
List notes (filter by notebook, type, tags) |
| POST |
/api/notes |
PARTICIPANT |
Create note |
| GET |
/api/notes/:id |
Bearer |
Get note with tags |
| PATCH |
/api/notes/:id |
Author/MOD |
Update note |
| DELETE |
/api/notes/:id |
Author/MOD |
Delete note |
| GET |
/api/notes/search?q= |
Bearer |
Full-text search across notes |
Notebooks
| Method |
Path |
Auth |
Description |
| GET |
/api/notebooks |
Bearer |
List notebooks with note counts |
| POST |
/api/notebooks |
PARTICIPANT |
Create notebook |
| GET |
/api/notebooks/:id |
Bearer |
Get notebook details |
| PATCH |
/api/notebooks/:id |
Owner/MOD |
Update notebook metadata |
| DELETE |
/api/notebooks/:id |
Owner/ADMIN |
Delete notebook |
| GET |
/api/notebooks/:id/notes |
Bearer |
Get notes in notebook |
| GET |
/api/notebooks/:id/canvas |
Bearer |
Get canvas shape data for notebook |
File Uploads
| Method |
Path |
Auth |
Description |
| POST |
/api/uploads |
Bearer |
Upload file (max 50MB) |
| GET |
/api/uploads/:filename |
Bearer |
Download file |
Voice
| Method |
Path |
Auth |
Description |
| POST |
/api/voice/transcribe |
Bearer |
Transcribe audio file |
| POST |
/api/voice/diarize |
Bearer |
Speaker diarization |
Canvas Sync
| Method |
Path |
Auth |
Description |
| POST |
/api/sync |
Service |
Receive shape updates from rSpace canvas |
rSpace — Collaborative Canvas
Base URL: https://{space}.rspace.online
Tech: Hono.js on Bun | Automerge CRDT | WebSocket
WebSocket Protocol
Connect: wss://{space}.rspace.online/?mode=automerge&token=JWT
| Message Type |
Direction |
Payload |
sync |
Bidirectional |
Automerge binary sync frame |
snapshot |
Server→Client |
Full JSON state (fallback mode) |
presence |
Bidirectional |
{ userId, cursor, selection } |
ping |
Client→Server |
Keep-alive (30s interval) |
pong |
Server→Client |
Keep-alive response |
error |
Server→Client |
{ code, message } |
REST API
| Method |
Path |
Auth |
Description |
| GET |
/health |
None |
Health check with DB connectivity |
| GET |
/api/communities/:slug |
Optional |
Get community metadata |
| POST |
/api/communities/:slug/shapes/:id |
Service |
Update shape from module callback |
Shape Update API (NEW — bidirectional sync)
POST /api/communities/{slug}/shapes/{shapeId}
Authorization: Bearer <service-jwt>
{
"title": "Updated Note Title",
"status": "PASSED",
"fields": { ... }
}
rCal — Calendar & Scheduling
Base URL: https://{space}.rcal.online
Tech: Next.js App Router | PostgreSQL (Prisma)
Events
| Method |
Path |
Auth |
Description |
| GET |
/api/events |
Optional |
List events (filter by date range, source) |
| POST |
/api/events |
PARTICIPANT |
Create event |
| GET |
/api/events/:id |
Optional |
Get event details |
| PATCH |
/api/events/:id |
Author/MOD |
Update event |
| DELETE |
/api/events/:id |
Author/MOD |
Delete event |
Calendar Sources
| Method |
Path |
Auth |
Description |
| GET |
/api/sources |
Bearer |
List calendar sources (Google, iCal, etc.) |
| POST |
/api/sources |
PARTICIPANT |
Add calendar source |
| GET |
/api/sources/:id |
Bearer |
Get source details |
| PATCH |
/api/sources/:id |
Owner |
Update source config |
| DELETE |
/api/sources/:id |
Owner |
Remove source |
Context & Integration
| Method |
Path |
Auth |
Description |
| GET |
/api/context/:tool |
Bearer |
Get events relevant to an r-tool context |
| GET |
/api/lunar |
None |
Get lunar phase data for date range |
rMaps — Spatial Intelligence
Base URL: https://{space}.rmaps.online
Tech: Next.js App Router | PostgreSQL (Prisma) | MapLibre GL
Routing
| Method |
Path |
Auth |
Description |
| POST |
/api/routing |
Optional |
Calculate route (origin, dest, mode) |
Request body:
{
"origin": { "lat": 52.52, "lng": 13.405 },
"destination": { "lat": 52.51, "lng": 13.39 },
"mode": "walking",
"indoor": false
}
Indoor Maps (c3nav)
| Method |
Path |
Auth |
Description |
| GET |
/api/c3nav/:event |
None |
Get indoor map metadata for event |
| GET |
/api/c3nav/tiles/:event/:level/:z/:x/:y |
None |
Tile server for indoor maps |
WebSocket (Real-time Location Sharing)
Connect: wss://{room}.rmaps.online/ws?token=JWT
| Message Type |
Direction |
Payload |
location |
Client→Server |
{ lat, lng, accuracy, privacy } |
locations |
Server→Client |
{ participants: [...] } |
waypoint |
Bidirectional |
{ id, name, lat, lng, emoji } |
Privacy modes: exact, approximate, area, ghost
rFiles — Secure File Sharing
Base URL: https://{space}.rfiles.online
Tech: Django REST Framework | PostgreSQL | S3-compatible storage
Media Files
| Method |
Path |
Auth |
Description |
| GET |
/api/v1/media/ |
Bearer |
List files (filter by mime, tags, space) |
| POST |
/api/v1/media/ |
PARTICIPANT |
Upload file |
| GET |
/api/v1/media/:id/ |
Bearer |
Get file metadata |
| PATCH |
/api/v1/media/:id/ |
Author/MOD |
Update metadata |
| DELETE |
/api/v1/media/:id/ |
Author/ADMIN |
Delete file |
| POST |
/api/v1/media/:id/share/ |
Author |
Create share link |
| GET |
/api/v1/media/:id/shares/ |
Author |
List shares for file |
| GET |
/api/v1/media/:id/access_logs/ |
Author |
Access history (last 100) |
Public Shares
| Method |
Path |
Auth |
Description |
| GET |
/s/:token/ |
None |
Download shared file |
| GET |
/s/:token/download/ |
None |
Explicit download |
| GET |
/s/:token/info/ |
None |
Get share info (no download) |
| POST |
/s/:token/verify/ |
None |
Verify password-protected share |
Share Management
| Method |
Path |
Auth |
Description |
| GET |
/api/v1/shares/ |
Bearer |
List user's shares |
| POST |
/api/v1/shares/:id/revoke/ |
Author |
Revoke share link |
| POST |
/api/v1/shares/:id/set_password/ |
Author |
Add password to share |
| POST |
/api/v1/shares/:id/remove_password/ |
Author |
Remove password |
Direct Upload
| Method |
Path |
Auth |
Description |
| POST |
/api/upload/ |
Bearer |
Direct file upload (FormData or pre-signed) |
rFunds — Funding Flows
Base URL: https://{space}.rfunds.online
Tech: Next.js | React Flow | Automerge CRDT
rFunds is primarily client-side (Automerge + localStorage). The flow diagrams are stored in the rSpace Automerge document as folk-budget and demo-expense shapes.
Planned Server API
| Method |
Path |
Auth |
Description |
| POST |
/api/flows |
PARTICIPANT |
Save flow diagram to server |
| GET |
/api/flows/:id |
VIEWER |
Get flow diagram |
| POST |
/api/campaigns |
PARTICIPANT |
Create crowdfunding campaign |
| POST |
/api/campaigns/:id/contribute |
PARTICIPANT |
Contribute to campaign |
Base URL: https://{space}.rtube.online
Tech: Hono.js on Bun | Cloudflare R2
Videos
| Method |
Path |
Auth |
Description |
| POST |
/api/upload |
PARTICIPANT |
Upload video file |
| GET |
/api/videos |
VIEWER |
List videos in space |
| GET |
/api/videos/:id |
VIEWER |
Get video metadata |
| GET |
/api/videos/:id/stream |
VIEWER |
Stream video (HTTP range requests) |
Live Streaming (Planned)
| Method |
Path |
Auth |
Description |
| POST |
/api/streams |
PARTICIPANT |
Start RTMP ingest stream |
| GET |
/api/streams/:id/hls |
VIEWER |
Get HLS playlist for live stream |
rMail — Secure Messaging
Base URL: https://{space}.rmail.online
Tech: Next.js App Router | PostgreSQL (Prisma) | IMAP
Mailboxes
| Method |
Path |
Auth |
Description |
| GET |
/api/mailboxes |
Bearer |
List user's mailboxes |
| POST |
/api/mailboxes |
ADMIN |
Create mailbox (IMAP/SMTP config) |
| GET |
/api/mailboxes/:slug/members |
Bearer |
List mailbox members |
| POST |
/api/mailboxes/:slug/members |
ADMIN |
Add member |
| DELETE |
/api/mailboxes/:slug/members/:did |
ADMIN |
Remove member |
Messages
| Method |
Path |
Auth |
Description |
| GET |
/api/mailboxes/:slug/messages |
Bearer |
List messages (IMAP sync) |
| GET |
/api/mailboxes/:slug/threads/:threadId |
Bearer |
Get email thread |
| PATCH |
/api/mailboxes/:slug/threads/:threadId |
Bearer |
Update thread (read, folder) |
| POST |
/api/mailboxes/:slug/threads/:threadId/comments |
Bearer |
Add comment |
Multi-Sig Approvals
| Method |
Path |
Auth |
Description |
| GET |
/api/approvals |
Bearer |
List pending approvals |
| POST |
/api/approvals |
PARTICIPANT |
Create email approval draft |
| GET |
/api/approvals/:id |
Bearer |
Get approval with signatures |
| POST |
/api/approvals/:id/sign |
Bearer |
Sign approval (add signature) |
Workspaces
| Method |
Path |
Auth |
Description |
| GET |
/api/workspaces |
Bearer |
List workspaces |
| POST |
/api/workspaces |
Bearer |
Create workspace |
| GET |
/api/workspaces/:slug/mailboxes |
Bearer |
List mailboxes in workspace |
rTrips — Trip Planning
Base URL: https://{space}.rtrips.online
Tech: Next.js App Router | PostgreSQL (Prisma) | Gemini AI
Trips
| Method |
Path |
Auth |
Description |
| GET |
/api/trips |
Bearer |
List trips |
| POST |
/api/trips |
PARTICIPANT |
Create trip from parsed text |
| GET |
/api/trips/:id |
Bearer |
Get trip with all entities |
| PATCH |
/api/trips/:id |
Author/MOD |
Update trip |
| DELETE |
/api/trips/:id |
Author/ADMIN |
Delete trip |
| GET |
/api/trips/by-slug/:slug |
Bearer |
Get trip by slug |
| POST |
/api/trips/parse |
Bearer |
AI-parse trip text → structured data |
Destinations
| Method |
Path |
Auth |
Description |
| GET |
/api/trips/:id/destinations |
Bearer |
List destinations |
| POST |
/api/trips/:id/destinations |
PARTICIPANT |
Add destination |
| PATCH |
/api/trips/:id/destinations/:destId |
Author/MOD |
Update destination |
| DELETE |
/api/trips/:id/destinations/:destId |
Author/MOD |
Remove destination |
Itinerary
| Method |
Path |
Auth |
Description |
| GET |
/api/trips/:id/itinerary |
Bearer |
List itinerary items |
| POST |
/api/trips/:id/itinerary |
PARTICIPANT |
Add item |
| PATCH |
/api/trips/:id/itinerary/:itemId |
Author/MOD |
Update item |
| DELETE |
/api/trips/:id/itinerary/:itemId |
Author/MOD |
Remove item |
Bookings
| Method |
Path |
Auth |
Description |
| GET |
/api/trips/:id/bookings |
Bearer |
List bookings |
| POST |
/api/trips/:id/bookings |
PARTICIPANT |
Add booking |
| PATCH |
/api/trips/:id/bookings/:bookingId |
Author/MOD |
Update booking |
| DELETE |
/api/trips/:id/bookings/:bookingId |
Author/MOD |
Cancel booking |
Expenses
| Method |
Path |
Auth |
Description |
| GET |
/api/trips/:id/expenses |
Bearer |
List expenses |
| POST |
/api/trips/:id/expenses |
PARTICIPANT |
Add expense |
| PATCH |
/api/trips/:id/expenses/:expenseId |
Author/MOD |
Update expense |
| DELETE |
/api/trips/:id/expenses/:expenseId |
Author/MOD |
Remove expense |
Packing Lists
| Method |
Path |
Auth |
Description |
| GET |
/api/trips/:id/packing |
Bearer |
Get packing list |
| POST |
/api/trips/:id/packing |
PARTICIPANT |
Add item |
| PATCH |
/api/trips/:id/packing/:itemId |
Bearer |
Check off item |
| DELETE |
/api/trips/:id/packing/:itemId |
Author/MOD |
Remove item |
Canvas & Cross-Module
| Method |
Path |
Auth |
Description |
| GET |
/api/trips/:id/canvas |
Bearer |
Get linked canvas shape data |
| POST |
/api/trips/:id/sync |
Service |
Receive canvas shape updates |
| POST |
/api/proxy/rvote |
Bearer |
Proxy to rVote (in-trip voting) |
| POST |
/api/proxy/rnotes |
Bearer |
Proxy to rNotes (shared trip notes) |
rNetwork — Social Graph
Base URL: https://{space}.rnetwork.online
Tech: Next.js | Automerge CRDT | Force-directed graph
rNetwork uses Automerge CRDT for the graph document. No traditional REST API — state syncs via WebSocket.
WebSocket Protocol
Connect: wss://{space}.rnetwork.online/ws?token=JWT
| Message Type |
Direction |
Payload |
sync |
Bidirectional |
Automerge binary sync frame |
snapshot |
Server→Client |
Full graph JSON |
Graph Document Schema
{
meta: { name, slug, visibility, ownerDID },
nodes: {
[id]: { type: "person"|"org"|"role", name, metadata }
},
edges: {
[id]: { source, target, type, label, metadata }
}
}
rWallet — Treasury
Base URL: https://{space}.rwallet.online
Tech: Next.js | Gnosis Safe SDK
Currently static frontend. Planned API:
| Method |
Path |
Auth |
Description |
| GET |
/api/safes |
Bearer |
List connected Safe wallets |
| GET |
/api/safes/:address/balances |
VIEWER |
Get token balances |
| GET |
/api/safes/:address/transactions |
VIEWER |
List transactions |
| POST |
/api/safes/:address/propose |
PARTICIPANT |
Propose new transaction |
| POST |
/api/safes/:address/sign/:txHash |
PARTICIPANT |
Sign pending transaction |
EncryptID SDK (npm: @encryptid/sdk)
Client-Side
import { EncryptIDClient } from '@encryptid/sdk/client';
const client = new EncryptIDClient('https://auth.ridentity.online');
// Register
await client.register(username);
// Authenticate
const { token, claims } = await client.authenticate();
// Share token across r*.online modules
await client.shareTokenAcrossModules(token, [
'rvote.online',
'rnotes.online',
'rmaps.online',
]);
Server-Side (Hono)
import {
encryptIDAuth,
encryptIDSpaceRoleAuth,
} from '@encryptid/sdk/server/middleware/hono';
// Simple auth (require valid token)
app.use('/api/*', encryptIDAuth({ serverUrl }));
// Space + role auth (combined)
app.use('/api/*', encryptIDSpaceRoleAuth({ serverUrl, lookupMembership }));
// Access context
app.get('/api/data', (c) => {
const claims = c.get('encryptid'); // EncryptIDClaims
const role = c.get('spaceRole'); // ResolvedRole
return c.json({ user: claims.did, role: role.role });
});
Server-Side (Next.js)
import {
checkSpaceRole,
withSpaceRole,
} from '@encryptid/sdk/server/middleware/nextjs';
// In a route handler
export async function GET(req) {
const { claims, role } = await checkSpaceRole(req, {
serverUrl: 'https://auth.ridentity.online',
spaceSlug: 'crypto',
});
if (!hasCapability(role.role, 'view_proposals', RVOTE_PERMISSIONS)) {
return Response.json({ error: 'Forbidden' }, { status: 403 });
}
// ... handle request
}
Server-Side (Python/Django)
from encryptid.roles import SpaceRole, has_capability, RFILES_PERMISSIONS
# Check if user can upload files
if has_capability(user_role, 'upload_file', RFILES_PERMISSIONS):
# allow upload
Capability Maps
Import per-module permission maps:
import { RVOTE_PERMISSIONS } from '@encryptid/sdk/types/modules';
import { RSPACE_PERMISSIONS } from '@encryptid/sdk/types/modules';
import { RNOTES_PERMISSIONS } from '@encryptid/sdk/types/modules';
import { RFUNDS_PERMISSIONS } from '@encryptid/sdk/types/modules';
import { RMAPS_PERMISSIONS } from '@encryptid/sdk/types/modules';
import { RTUBE_PERMISSIONS } from '@encryptid/sdk/types/modules';
WebSocket Protocols Summary
| Module |
URL Pattern |
Protocol |
Auth |
| rSpace |
wss://{slug}.rspace.online/ |
Automerge binary sync |
JWT (query/subprotocol) |
| rNetwork |
wss://{slug}.rnetwork.online/ws |
Automerge binary sync |
JWT (query/subprotocol) |
| rMaps |
wss://{room}.rmaps.online/ws |
JSON location/waypoint |
JWT (query) |
Cross-Module Integration
Canvas Shape Sync (module → canvas)
When a module updates an entity bound to a canvas shape:
POST https://{slug}.rspace.online/api/communities/{slug}/shapes/{shapeId}
Authorization: Bearer <service-jwt>
Content-Type: application/json
{
"title": "Updated Title",
"status": "PASSED"
}
Canvas Shape Sync (canvas → module)
When rSpace updates a shape bound to a module entity, it calls the module's sync endpoint:
POST https://{slug}.rnotes.online/api/sync
POST https://{slug}.rtrips.online/api/trips/{id}/sync
Module Proxying
rTrips demonstrates the proxy pattern for embedded module access:
POST /api/proxy/rvote → proxied to rvote.online
POST /api/proxy/rnotes → proxied to rnotes.online