> For the complete documentation index, see [llms.txt](https://vectis.liesware.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://vectis.liesware.com/messages.md).

# Messages

## POST /message/{sender\_kid}

> Send a protected message to another Vectis instance

```json
{"openapi":"3.1.0","info":{"title":"Vectis HTTP API","version":"v1"},"tags":[{"name":"Messages"}],"servers":[{"url":"http://127.0.0.1:3000","description":"Local default server over HTTP"},{"url":"https://127.0.0.1:3000","description":"Local HTTPS server when VECTIS_MODE=prod"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"Kid":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"},"SendMessageInput":{"type":"object","required":["recipient_kid","message"],"properties":{"recipient_kid":{"$ref":"#/components/schemas/Kid"},"message":{"$ref":"#/components/schemas/TextField"}}},"TextField":{"type":"string","minLength":1,"pattern":"^[^\\x00-\\x1F\\x7F-\\x9F]+$"},"SendMessageOutput":{"type":"object","required":["message","symmetric","eddsa","xecdh","ml-dsa","ml-kem"],"properties":{"message":{"type":"object","required":["valid"],"properties":{"valid":{"type":"boolean"}}},"symmetric":{"$ref":"#/components/schemas/VariantValidation"},"eddsa":{"$ref":"#/components/schemas/VariantValidation"},"xecdh":{"$ref":"#/components/schemas/VariantValidation"},"ml-dsa":{"$ref":"#/components/schemas/VariantValidation"},"ml-kem":{"$ref":"#/components/schemas/VariantValidation"}}},"VariantValidation":{"type":"object","required":["variant","valid"],"properties":{"variant":{"$ref":"#/components/schemas/TextField"},"valid":{"type":"boolean"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/TextField"}}}},"responses":{"RequestBodyTooLarge":{"description":"Request body exceeds the internal 2 MiB limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Error":{"description":"Public error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/message/{sender_kid}":{"post":{"tags":["Messages"],"summary":"Send a protected message to another Vectis instance","parameters":[{"name":"sender_kid","in":"path","required":true,"schema":{"$ref":"#/components/schemas/Kid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageInput"}}}},"responses":{"200":{"description":"Send status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageOutput"}}}},"413":{"$ref":"#/components/responses/RequestBodyTooLarge"},"default":{"$ref":"#/components/responses/Error"}}}}}}
```

## Receive a protected message from another Vectis instance

> Public endpoint. Authenticity is validated with EdDSA and ML-DSA signatures.

```json
{"openapi":"3.1.0","info":{"title":"Vectis HTTP API","version":"v1"},"tags":[{"name":"Messages"}],"servers":[{"url":"http://127.0.0.1:3000","description":"Local default server over HTTP"},{"url":"https://127.0.0.1:3000","description":"Local HTTPS server when VECTIS_MODE=prod"}],"paths":{"/message":{"post":{"tags":["Messages"],"summary":"Receive a protected message from another Vectis instance","description":"Public endpoint. Authenticity is validated with EdDSA and ML-DSA signatures.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtectedMessageToken"}}}},"responses":{"200":{"description":"Receive status and local encrypted payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceiveMessageOutput"}}}},"413":{"$ref":"#/components/responses/RequestBodyTooLarge"},"default":{"$ref":"#/components/responses/Error"}}}}},"components":{"schemas":{"ProtectedMessageToken":{"type":"object","required":["version","payload","signatures"],"properties":{"version":{"const":"v1","description":"Envelope version for dispatch; must equal payload.version."},"payload":{"type":"object","required":["version","type","created_at","sender","recipient","kem","cipher"],"properties":{"version":{"const":"v1","description":"Signed payload version; integrity-protected by the signatures."},"type":{"const":"protected-message"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"sender":{"type":"object","required":["host","kid"],"properties":{"host":{"$ref":"#/components/schemas/TextField"},"kid":{"$ref":"#/components/schemas/Kid"}}},"recipient":{"type":"object","required":["kid"],"properties":{"kid":{"$ref":"#/components/schemas/Kid"}}},"kem":{"type":"object","required":["alg","xecdh_ephemeral_public","ml_kem_ciphertext","ml_kem_salt","hkdf_salt"],"properties":{"alg":{"$ref":"#/components/schemas/TextField"},"xecdh_ephemeral_public":{"$ref":"#/components/schemas/HexString"},"ml_kem_ciphertext":{"$ref":"#/components/schemas/HexString"},"ml_kem_salt":{"$ref":"#/components/schemas/HexString"},"hkdf_salt":{"$ref":"#/components/schemas/HexString"}}},"cipher":{"$ref":"#/components/schemas/MessageCipher"}}},"signatures":{"$ref":"#/components/schemas/DualSignatures"}}},"Timestamp":{"type":"string","pattern":"^[0-9]+$"},"TextField":{"type":"string","minLength":1,"pattern":"^[^\\x00-\\x1F\\x7F-\\x9F]+$"},"Kid":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"},"HexString":{"type":"string","pattern":"^[0-9a-fA-F]+$"},"MessageCipher":{"type":"object","required":["alg","nonce","aad","ct"],"properties":{"alg":{"$ref":"#/components/schemas/SymmetricAlgorithm"},"nonce":{"$ref":"#/components/schemas/HexString"},"aad":{"$ref":"#/components/schemas/TextField"},"ct":{"$ref":"#/components/schemas/HexString"}}},"SymmetricAlgorithm":{"enum":["ChaCha20Poly1305","AES-128/GCM","AES-192/GCM","AES-256/GCM"]},"DualSignatures":{"type":"object","required":["eddsa","ml-dsa"],"properties":{"eddsa":{"$ref":"#/components/schemas/SignatureBlock"},"ml-dsa":{"$ref":"#/components/schemas/SignatureBlock"}}},"SignatureBlock":{"type":"object","required":["alg","sig"],"properties":{"alg":{"$ref":"#/components/schemas/TextField"},"sig":{"$ref":"#/components/schemas/HexString"}}},"ReceiveMessageOutput":{"type":"object","required":["status","sender_kid","recipient_kid","local_cipher"],"properties":{"status":{"const":"ok"},"sender_kid":{"$ref":"#/components/schemas/Kid"},"recipient_kid":{"$ref":"#/components/schemas/Kid"},"local_cipher":{"type":"object","required":["alg","nonce","aad","ct"],"properties":{"alg":{"$ref":"#/components/schemas/SymmetricAlgorithm"},"nonce":{"$ref":"#/components/schemas/HexString"},"aad":{"$ref":"#/components/schemas/TextField"},"ct":{"$ref":"#/components/schemas/HexString"}}}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/TextField"}}}},"responses":{"RequestBodyTooLarge":{"description":"Request body exceeds the internal 2 MiB limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Error":{"description":"Public error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}
```

## POST /message/decrypt

> Decrypt a final app delivery payload

```json
{"openapi":"3.1.0","info":{"title":"Vectis HTTP API","version":"v1"},"tags":[{"name":"Messages"}],"servers":[{"url":"http://127.0.0.1:3000","description":"Local default server over HTTP"},{"url":"https://127.0.0.1:3000","description":"Local HTTPS server when VECTIS_MODE=prod"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"DecryptMessageInput":{"type":"object","required":["sender_host","sender_kid","timestamp","message"],"properties":{"sender_host":{"$ref":"#/components/schemas/TextField"},"sender_kid":{"$ref":"#/components/schemas/Kid"},"timestamp":{"$ref":"#/components/schemas/Timestamp"},"message":{"$ref":"#/components/schemas/DecryptMessageCipher"}}},"TextField":{"type":"string","minLength":1,"pattern":"^[^\\x00-\\x1F\\x7F-\\x9F]+$"},"Kid":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"},"Timestamp":{"type":"string","pattern":"^[0-9]+$"},"DecryptMessageCipher":{"type":"object","required":["ctx","nonce","aad","variant"],"properties":{"ctx":{"$ref":"#/components/schemas/HexString"},"nonce":{"$ref":"#/components/schemas/HexString"},"aad":{"$ref":"#/components/schemas/TextField"},"variant":{"$ref":"#/components/schemas/SymmetricAlgorithm"}}},"HexString":{"type":"string","pattern":"^[0-9a-fA-F]+$"},"SymmetricAlgorithm":{"enum":["ChaCha20Poly1305","AES-128/GCM","AES-192/GCM","AES-256/GCM"]},"DecryptMessageOutput":{"type":"object","required":["plaintext"],"properties":{"plaintext":{"$ref":"#/components/schemas/TextField"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/TextField"}}}},"responses":{"RequestBodyTooLarge":{"description":"Request body exceeds the internal 2 MiB limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Error":{"description":"Public error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/message/decrypt":{"post":{"tags":["Messages"],"summary":"Decrypt a final app delivery payload","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecryptMessageInput"}}}},"responses":{"200":{"description":"Decrypted plaintext","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecryptMessageOutput"}}}},"413":{"$ref":"#/components/responses/RequestBodyTooLarge"},"default":{"$ref":"#/components/responses/Error"}}}}}}
```
