EchoZero uses three distinct signing schemes depending on direction and transport. Using the wrong algorithm is the most common integration mistake.
Inbound agent HTTP signals
Endpoint: POST https://mcp.echozero.app/api/public/agent-signals/{agentId}
No developer API key. Authenticate with the per-agent signing secret (ezw_...) revealed once at provision or rotation.
Always send a stable idempotencyKey on every inbound signal, including natural-language text and legacy payloads. Without it, a captured or retried signed request can execute the trade again. See Signal envelope.
Signing algorithm
- Serialize the request body as canonical JSON - keys sorted alphabetically at every object level,
undefined fields omitted.
- Build:
payloadString = "${unixSeconds}.${canonicalJson}"
- Sign:
HMAC_SHA256(signingSecret, payloadString) → lowercase hex
SDK helpers
The echozero-sdk provides signInboundWebhook / sign_inbound_webhook in TypeScript, Python, Go, and Rust with canonical JSON built in.
Replay protection
- Requests with timestamp skew beyond ±5 minutes are rejected with 401.
- Use a unique
idempotencyKey per signal so retries are safe no-ops.
Verify inbound (Python)
Golden vectors: Signature test vectors.
Outbound execution webhooks
When your agent has a webhookUrl, EchoZero POSTs execution results after trade attempts.
Signing secret
Use the agent webhook signing secret configured on the agent (webhookUrl + secret pair). Rotate by updating the agent record in Dev Portal or PATCH /api/v1/agents/{id}.
Delivery contract
Event catalog
Verify on your server
Headers:
Reject requests outside a 5-minute timestamp window and treat duplicate signalId deliveries as idempotent.
Provider webhooks (Telegram, Discord)
When EchoZero hosts signal ingestion for Telegram or Discord bots, provider-specific secrets apply. These routes do not use developer API keys.
Telegram
Endpoint: POST /api/webhooks/telegram/signal-bot
When the server has SIGNAL_TELEGRAM_WEBHOOK_SECRET configured, every request must include:
Configure this when registering your bot webhook via Telegram’s setWebhook API.
Discord
Endpoint: POST /api/webhooks/discord/signal-bot
When SIGNAL_DISCORD_WEBHOOK_SECRET is set:
Used when Discord Gateway ingest is off or for webhook-based testing.
REST API HMAC (developer routes)
For authenticated developer API calls (/api/v1/*), HMAC uses your API secret with millisecond timestamps and method+path signing. See API keys and HMAC.
Do not use REST API HMAC headers (x-signature / x-timestamp) on inbound agent signal POSTs. Agent ingress requires X-EZ-Signature / X-EZ-Timestamp with the per-agent ezw_ secret.
Security checklist
- Store signing secrets in a secrets manager - they are shown only once at creation/rotation.
- Use HTTPS for all webhook URLs.
- Enforce timestamp windows on every inbound webhook you receive.
- Deduplicate by
idempotencyKey (inbound) or signalId (outbound).
- Rotate compromised secrets via
rotateInboundWebhookSigningSecret or API key revocation in the Dev Portal.