Skip to main content

Overview

Every validator can serve an HTTP API (default devnet port 4000, set by rpc_port in the validator config). The cowboy CLI and SDKs are wrappers over this API; anything they do, you can do with plain HTTP.
With COWBOY_DEV_MODE set on the node, a Swagger UI is served at /swagger-ui and the machine-readable spec at /api-docs/openapi.json. That spec is the exhaustive, always-current endpoint list; this page covers the conventions and the endpoints developers use most.

Conventions

  • Addresses are 20-byte hex strings (0x-prefixed accepted). Invalid addresses return 400.
  • Pagination: list endpoints take offset and limit query params (limit defaults to 50, capped at 1,000) and return total_count with the echoed offset/limit; the actor storage/mailbox endpoints use cursor pagination (next_cursor).
  • Rate limits: global sliding window (default 100 req/s, RPC_GLOBAL_RATE_LIMIT_PER_SEC); the faucet is limited separately (default 5 req/min). Exceeding returns 429.
  • Errors are JSON with an HTTP status plus a numeric code (table below).
  • Body size: requests are capped at 1 MB globally; /submit and /submit_wait enforce a tighter 512 KB.
  • Amounts (balances, fees) are integers in CBY base units (1 CBY = 10⁹).

Transactions

The submission body is binary CBOR, not JSON: a Submission::Transactions([...]) envelope of signed transactions (max 50 per batch). In practice you produce it with the CLI (cowboy transaction submit) or an SDK rather than by hand; the wallet’s transaction encoding is byte-compatible with the node’s deterministic CBOR. /submit_wait returns per-transaction results including status, block_height, gas used, and revert_reason when execution failed.

Accounts

Actors

/actor/read runs a handler against current state without a transaction — the workhorse for UIs and polling:
The payload can be given as payload (base64 bytes), payload_text (UTF-8 string), or payload_json (JSON value); optional max_cycles/max_cells bound the execution. A handler that attempts a state write is rejected (error 5003).

Blocks and chain state

Tokens (CIP-20)

Runners and jobs (CIP-2)

Read endpoints useful when integrating with off-chain compute: The runner daemon itself uses signed POST flows (/runner/{address}/heartbeat, /runner/{address}/job_result, …): each has a companion *_payload GET that returns the exact message_to_sign_base64, so signatures are computed over server-canonical bytes.

Proofs (CIP-15/17)

/proof/receipt/{tx_hash}, /proof/tx/{tx_hash}, /proof/account/{address}, /proof/actor/{address}, /proof/storage/{address}/{key}, and batch /proof/multi (POST) return Merkle proofs against the block state root, for light-client-style verification. /state/{actor}/{key_hex} returns a storage value together with its proof.

Faucet (devnet only)

The route exists only when the validator runs with the faucet enabled (404 otherwise); with the faucet enabled on a non-dev chain (chain id other than 1 or 100) it returns 403. Rate-limited per minute.

Other endpoint families

Consult /api-docs/openapi.json (dev mode) for the full schemas of these families.

Error codes

Numeric codes accompany HTTP errors so clients can branch reliably: Execution-level failures inside a committed transaction surface as E-codes in the receipt instead — see the error reference.

Further reading