Device Management API
Device announcements create temporary routing mappings that allow servers to deliver messages to devices. Unlike traditional systems, Cryptid servers store no permanent device records; All mappings expire automatically after 24-48 hours.
Devices must periodically re-announce themselves to maintain message delivery. This approach ensures that server compromise reveals minimal metadata, as inactive devices are automatically forgotten.
Device Identity vs. Delivery Address
Section titled “Device Identity vs. Delivery Address”Cryptid separates device identity from message routing:
Device ID (Permanent)
- Blake3 hash of Ed25519 public key:
device_id = Blake3(public_key) - Used for MLS group membership and message signing
- Cannot be changed without creating a new device
- Example:
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2(64 hex chars)
Delivery Address (Rotatable)
- UUIDv4 prefix + server domain:
{uuid_v4}@{server} - Generated by the server during device announcement
- Used only for routing messages to devices
- Can be rotated freely for privacy without affecting group membership
- Example:
a1b2c3d4-e5f6-4728-9394-a5b6c7d8e9f1@chat.example.com
When announcing a device:
- Device sends its permanent
device_id(for authentication) - Server generates a new UUIDv4 delivery address prefix
- Server maps the delivery address to the device ID internally for 24 hours
Register Device
Section titled “Register Device”Creates a temporary delivery mapping and issues a JWT access token. The server generates a unique delivery address for routing and performs only basic timestamp validation. Signature verification is the recipient’s responsibility, maintaining the minimal-trust model.
Endpoint
Section titled “Endpoint”POST /v1/announceRequest
Section titled “Request”POST /v1/announce HTTP/1.1Content-Type: application/json{ "device_id": "6df9a6cbb41be1bf4575ce6a57886d1aa3e57e65ba9de29bc5810fadba40a6ea", "announcement_signature": "ed25519_signature_over_device_id_and_timestamp", "timestamp": 1759695461, "storage_preferences": { "max_retention_days": 30, "offline_message_limit": 1000 }}Parameters:
-
device_id: Blake3 hash of device’s Ed25519 public key (32 bytes, 64 hex characters) -
announcement_signature: Ed25519 signature over device_id and timestamp -
timestamp: Unix timestamp (prevents replay attacks) -
storage_preferences: Optional message storage settings
Response
Section titled “Response”{ "assigned_address": "2eafc575-6217-4338-96b8-f71a52c22f6a@chat.example.com", "access_token": "jwt_access_token", "expires_at": 1759695599, "server_capabilities": { "protocol_version": "1.0", "server_name": "server.example.com", "federation_enabled": true, "supported_features": ["mls_messaging", "websocket_streaming", "offline_queuing"], "rate_limits": { "federated_messages_per_minute": 1000, "announcements_per_hour": 24, "infopackage_uploads_per_hour": 10, "infopackage_uploads_per_day": 50 }, "message_limits": { "max_message_size": 10485760, "max_retention_days": 30 }, "websocket": { "enabled": true, "max_connections_per_device": 1, "max_message_backlog": 1000, "keepalive_interval_seconds": 30, "connection_timeout_seconds": 300 }, "certificate_fingerprint": "blake3:a1b2c3d4e5f6172839..." }, "next_announcement_required": 1759696000}Response Fields:
-
assigned_address: The server-generated delivery address (UUIDv4 prefix + server domain) -
access_token: JWT Bearer token for authenticated endpoints (expires with mapping) -
expires_at: Unix timestamp when the delivery mapping expires -
server_capabilities: Server limits and features for client configuration -
next_announcement_required: Recommended time for next keepalive announcement
Update Device Announcement
Section titled “Update Device Announcement”Extends the delivery mapping expiration. Devices should call this endpoint before their current mapping expires (typically every 20-24 hours) to ensure continuous message delivery. This is a lightweight keepalive that doesn’t require re-uploading storage preferences.
The device must provide its currently assigned delivery address to extend the mapping.
Endpoint
Section titled “Endpoint”PUT /v1/announceRequest
Section titled “Request”PUT /v1/announce HTTP/1.1Authorization: Bearer {access_token}Content-Type: application/json{ "device_id": "6df9a6cbb41be1bf4575ce6a57886d1aa3e57e65ba9de29bc5810fadba40a6ea", "announcement_signature": "ed25519_signature_over_device_id_and_timestamp", "timestamp": 1759696179}Response (200 OK)
Section titled “Response (200 OK)”{ "expires_at": 1759697179, "next_announcement_required": 1759699999}Deregister Device
Section titled “Deregister Device”Explicitly removes the device from the server’s routing table. While mappings expire automatically, explicit deregistration ensures immediate cleanup and prevents queuing messages for devices that are intentionally going offline.
Endpoint
Section titled “Endpoint”DELETE /v1/announceRequest
Section titled “Request”DELETE /v1/announce HTTP/1.1Authorization: Bearer {access_token}Content-Type: application/json{ "device_id": "6df9a6cbb41be1bf4575ce6a57886d1aa3e57e65ba9de29bc5810fadba40a6ea", "deregistration_signature": "ed25519_signature_over_device_id_and_timestamp", "timestamp": 1759699999}Response
Section titled “Response”{ "status": "deregistered"}Important Notes
Section titled “Important Notes”Signature Verification
Section titled “Signature Verification”The server validates that signatures are properly formatted but does not verify their cryptographic correctness. Recipients must verify signatures themselves using the sender’s public key. This prevents the server from making trust decisions.
Automatic Expiration
Section titled “Automatic Expiration”All device mappings expire after 24 hours by default. Queued messages expire according to max_retention_days (default: 30 days). No manual cleanup is required.
Address Rotation
Section titled “Address Rotation”Each time a device announces itself (POST /v1/announce), the server generates a fresh delivery address.
To rotate addresses for privacy:
- Wait for current mapping to expire naturally, OR
- Call DELETE /v1/announce to deregister
- Call POST /v1/announce to get a new delivery address
The device ID remains constant across all address rotations.
Rate Limiting
Section titled “Rate Limiting”Device announcements are limited to 24 per hour per address. This allows for legitimate network reconnections while preventing announcement spam.
Example Flow
Section titled “Example Flow”-
Device generates Ed25519 keypair locally.
-
Device derives device ID:
device_id = Blake3(public_key). -
POST /v1/announce with device_id -> Server assigns delivery address and returns JWT token.
-
Device stores assigned_delivery_address for future announcements.
-
Uses access_token for all subsequent API calls.
-
PUT /v1/announce every 20 hours with current_delivery_address (keepalive).
-
DELETE /v1/announce with current_delivery_address when going offline (optional).
-
POST /v1/announce again to get a new delivery address (rotates for privacy).