Reactor HTTP API
Off-chain applications submit messages through Reactor Website’s public API. Website authenticates and rate-limits the request, derives the account source identity, and forwards accepted messages to Reactor Core’s send method.
POST https://api.reactor.network/v1/messages
Authorization: Bearer <REACTOR_API_KEY>
Content-Type: application/jsonRequest
All HTTP fields are required. The TypeScript, Python, and Go SDKs generate request_id and payload_hash by default.
| Field | Type | Meaning |
|---|---|---|
request_id | string | Idempotency key, 1–128 characters. Reuse it for an explicit retry of the same logical request. |
destination_name | string | A supported destination name. |
destination_address | string | Destination recipient; EVM destinations use a 20-byte hex address. |
action | string | chain_message, web_message, or generate_random_numbers. |
payload | string | Encoded payload bytes. SDK EVM helpers return canonical 0x hex. |
payload_hash | string | Keccak-256 of the decoded payload bytes, as lowercase 0x hex. |
Do not send source_address. Reactor derives it from the account that owns the API key; a caller-supplied value is rejected with HTTP 400.
{
"request_id": "req-001",
"destination_name": "base",
"destination_address": "0x1111111111111111111111111111111111111111",
"action": "chain_message",
"payload": "0x010203",
"payload_hash": "0xf1885eda54b7a053318cd41e2093220dab15d65381b1157a3633a83bfd5c9239"
}The hash above is Keccak-256 of bytes 01 02 03, not a hash of the textual hex characters.
Idempotency
The pair of API-key identity and request_id identifies a submission. Reusing the ID with the same message fingerprint returns the existing outcome with status duplicate_returned; reusing it with different content returns HTTP 409 idempotency_conflict. SDKs do not retry automatically. If your application retries, retain the same request ID.
Response
{
"message_id": "<text>",
"transaction_id": "<text>",
"status": "submitted"
}| Status | HTTP | Meaning |
|---|---|---|
submitted | 202 | Accepted and submitted for processing. |
pending | 202 | Accepted; processing remains pending. |
duplicate_returned | 200 | Existing idempotent outcome returned. |
failed | 200 | Accepted request reached a failed outcome. |
Additive response fields may be introduced; clients should ignore fields they do not recognize.
Errors and limits
Errors are JSON with an error code and, when safe, detail or message.
| HTTP | Code | Meaning |
|---|---|---|
| 400/422 | invalid_request | Missing, malformed, unsupported, mismatched, or oversized input. |
| 401 | missing_bearer_token, invalid_api_key, or unauthenticated | Authentication failed. |
| 402 | insufficient_balance | The Reactor account needs more credits. |
| 403 | forbidden | The key/account is not permitted to send. |
| 409 | idempotency_conflict | Request ID reused with different content. |
| 429 | rate_limited | Key or IP limit exceeded. |
| 502/503 | upstream_error or service_unavailable | Reactor dependency temporarily unavailable. |
The default request body limit is 262,144 bytes. Default rate limits are 60 requests per 60 seconds per API key and 120 per 60 seconds per IP. Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset; HTTP 429 also includes Retry-After.
Direct HTTP example
curl -X POST https://api.reactor.network/v1/messages \
-H "Authorization: Bearer $REACTOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"request_id":"req-001",
"destination_name":"base",
"destination_address":"0x1111111111111111111111111111111111111111",
"action":"chain_message",
"payload":"0x010203",
"payload_hash":"0xf1885eda54b7a053318cd41e2093220dab15d65381b1157a3633a83bfd5c9239"
}'For normal application code, prefer the TypeScript, Python, or Go SDK so request IDs, hashing, timeouts, and error parsing are handled consistently.