Auth: workspace token. Scope: sign on both routes.
Both address a public key directly. Resolution is scoped to the session’s own
workspace, so one tenant can never sign with another’s key — and an address that
exists elsewhere returns the same 404 as one that does not exist at all.
POST /v1/sign/message
Returns 200.
Request
{
"address": "0xabc…",
"message": "hello from tee-docker",
"encoding": "personal_sign"
}| Field | Type | Required | Notes |
|---|---|---|---|
address |
string | yes | Public key, 1–128 characters |
message |
string | yes | The message to sign |
encoding |
enum | no | personal_sign, raw, or ed25519 |
Omit encoding and the address signs with its VM’s natural default.
Response
{ "address": "0xabc…", "signature": "0x…" }With an explicit encoding, the response may also carry messageHash:
{ "address": "0xabc…", "signature": "0x…", "messageHash": "0x…" }POST /v1/sign/typed-data
EIP-712 typed data. EVM only. Returns 200.
Request
{
"address": "0xabc…",
"typedData": {
"domain": { "name": "MyDapp", "version": "1", "chainId": 1, "verifyingContract": "0xdef…" },
"types": { "Order": [ { "name": "maker", "type": "address" } ] },
"primaryType": "Order",
"message": { "maker": "0xabc…" }
},
"chainId": 1
}| Field | Type | Required | Notes |
|---|---|---|---|
address |
string | yes | Public key, 1–128 characters |
typedData |
object | yes | The EIP-712 payload |
chainId |
integer | no | Positive. Defaults to the address’s own network |
Response
{
"address": "0xabc…",
"signature": "0x…",
"domainSeparator": "0x…",
"structHash": "0x…"
}Both intermediate hashes are returned so you can verify the domain binding independently.
A non-EVM address returns 422 with unsupported_for_kind.
Errors
| Status | Code |
|---|---|
| 400 | invalid_body |
| 401 | session_expired |
| 403 | scope_denied |
| 404 | account_not_found |
| 422 | unsupported_for_kind |
| 423 | account_locked |
Related
- Sign messages — the task walkthrough