REST API Reference
Public REST API reference for the Goliath Bridge — status, history, fee-quote, limits, XCN withdraw intent, and health endpoints with full request/response schemas.
All public endpoints live under the common base URL:
Testnet
Contact support for the current testnet base URL — it may change as testnet environments evolve.
All responses are application/json. All timestamps are ISO-8601 UTC. Amounts are atomic units (stringified big integers) with the token's decimals applied — amountFormatted fields give the human-readable equivalent for convenience.
Authentication
None. All endpoints documented on this page are public. Rate limits apply per IP.
Admin endpoints under /api/v1/admin/* exist for operational use by the Goliath team and are not public — they are omitted from this reference. Do not build against them.
Error Envelope
Failing requests return:
{
"error": "ERROR_CODE",
"message": "Human-readable description"
}Common codes:
400
VALIDATION_ERROR
Malformed or missing parameter. message names the offending field.
400
BELOW_MINIMUM
Amount below the per-token minimum.
400
DEADLINE_EXPIRED
Intent deadline already in the past.
400
SIGNATURE_INVALID / SIGNATURE_MISMATCH / SIGNATURE_DOMAIN_REJECTED
EIP-712 signature rejected.
403
SENDER_MISMATCH
senderAddress does not match the original signer.
404
OPERATION_NOT_FOUND / INTENT_NOT_FOUND
No record for the given identifier (yet).
409
INTENT_ALREADY_BOUND / INTENT_NOT_PENDING / DUPLICATE_ORIGIN_TX
Conflict with existing state.
410
INTENT_EXPIRED
Signed intent expired.
429
RATE_LIMIT_EXCEEDED
Too many requests.
503
SIGNATURE_VERIFICATION_UNAVAILABLE
ERC-1271 signature verification is transiently unavailable, or the smart-account senderAddress is not yet deployed on Goliath. Retry after 1–5 s. See Smart Account Integration.
503
SERVICE_PAUSED
New XCN intents temporarily disabled.
GET /bridge/status
GET /bridge/statusLook up a single bridge operation.
Query parameters
At least one of:
originTxHash
string
Origin-chain transaction hash (0x + 64 hex).
depositId
string
bytes32 from the Deposit event (Ethereum → Goliath).
withdrawId
string
bytes32 from the Withdraw event (Goliath → Ethereum).
Response 200 — BridgeOperationResponse
BridgeOperationResponseKey fields
direction
"ETHEREUM_TO_GOLIATH" | "GOLIATH_TO_ETHEREUM"
amount / amountFormatted
atomic / human-readable
Input amount (pre-fee).
fee
{ amount, formatted, bps } | null
Deducted fee. null for deposits.
outputAmount / outputAmountFormatted
atomic / human-readable
Amount delivered to recipient.
originConfirmations / requiredConfirmations
numbers
Progress toward source-chain finality.
estimatedCompletionTime
ISO 8601 | null
Best-effort ETA.
holdUntil
ISO 8601 | null
Non-null on G→E while in the hold period.
settlement
object | null
Populated on terminal COMPLETED state; mirrors the destination delivery.
Poll this endpoint every 5–10 seconds after submitting the origin tx. Stop polling once status is COMPLETED, EXPIRED, or FAILED.
Response 404 — OPERATION_NOT_FOUND
OPERATION_NOT_FOUNDExpected for the first several seconds after the origin tx is mined, while the relayer indexes the event. Treat as "keep polling".
GET /bridge/history
GET /bridge/historyList operations for a given wallet address, newest first. address matches either sender or recipient.
Query parameters
address
string
—
Required. Lowercased EVM address.
limit
number
10
Max 100.
offset
number
0
For pagination.
direction
"ETHEREUM_TO_GOLIATH" | "GOLIATH_TO_ETHEREUM"
—
Optional filter.
Response 200
Use pagination.hasMore to drive infinite-scroll in mobile clients.
GET /bridge/fee-quote
GET /bridge/fee-quotePreview the fee and output amount for a pending transfer. Call this before prompting the user to sign — it is the canonical source of fee and minimum data.
Query parameters
token
"ETH" | "USDC" | "XCN"
Required.
amount
string
Required. Human-readable (e.g. "100").
direction
"ETHEREUM_TO_GOLIATH" | "GOLIATH_TO_ETHEREUM"
Required.
Response 200
For ETHEREUM_TO_GOLIATH, feeAmount = 0 and outputAmount = inputAmount.
Response 400 — BELOW_MINIMUM
BELOW_MINIMUMGET /bridge/limits
GET /bridge/limitsReturns the current fee configuration and per-token minimums for both directions. Safe to cache in the client for a few minutes.
Response 200
Ethereum → Goliath has no fee and no minimums enforced by the protocol — you may still want a client-side sanity check (e.g. "dust" amounts below gas cost).
POST /bridge/xcn-withdraw-intent
POST /bridge/xcn-withdraw-intentRegister a signed intent to withdraw native XCN from Goliath to Ethereum. Required only for native-XCN withdrawals — not for ETH or USDC withdrawals.
See the full flow in Goliath → Ethereum — Native XCN.
ERC-1271 smart-account signatures are accepted. When senderAddress is a deployed contract, the bridge verifies the signature via an on-chain isValidSignature(bytes32,bytes) call and requires magic 0x1626ba7e. The legacy isValidSignature(bytes,bytes) variant is not accepted. See Smart Account Integration for the full contract, examples, and failure modes.
Request body
senderAddress
string
EVM address of the signer. Must match the recovered signer.
recipientAddress
string
EVM address on Ethereum that will receive XCN (as ERC-20).
amountAtomic
string
18-decimal wei string (e.g. parseEther("5000").toString()).
idempotencyKey
string
Client-generated idempotency key, ≤128 characters. Use crypto.randomUUID().
deadline
number
Unix seconds. Must be in the future. Use now + 1800 (30 min).
nonce
string
Any unique string. Date.now().toString() is fine.
signature
string
EIP-712 signature over the message below.
EIP-712 domain and types
Response 200
After receiving this response, send native XCN value = amountAtomic from the senderAddress wallet to relayerWalletAddress, then call /bridge/xcn-withdraw-intent/bind-origin.
Relevant errors
VALIDATION_ERROR (bad body), DEADLINE_EXPIRED, SIGNATURE_INVALID, SIGNATURE_MISMATCH, SIGNATURE_DOMAIN_REJECTED, SIGNATURE_VERIFICATION_UNAVAILABLE (ERC-1271 only — transient RPC or undeployed smart account), BELOW_MINIMUM, SERVICE_PAUSED.
POST /bridge/xcn-withdraw-intent/bind-origin
POST /bridge/xcn-withdraw-intent/bind-originPair a previously registered intent with the Goliath tx hash that transferred native XCN to the relayer.
Request body
Response 200
Relevant errors
404
INTENT_NOT_FOUND
Wrong intentId.
409
INTENT_NOT_PENDING
Intent already progressed.
409
INTENT_ALREADY_BOUND
Already bound to a different tx.
409
DUPLICATE_ORIGIN_TX
Tx hash already bound to another intent.
410
INTENT_EXPIRED
Passed the 30 min window.
403
SENDER_MISMATCH
senderAddress does not match the original signer.
Retry transient errors with exponential backoff. Stop on terminal states (INTENT_EXPIRED, SENDER_MISMATCH, INTENT_ALREADY_BOUND).
GET /health
GET /healthPublic liveness / readiness probe. Safe to call at the start of your session to decide whether to enable the Bridge UI.
Response 200 (healthy)
Response 503 (unhealthy)
Same shape with "status": "unhealthy" and one or more connected: false. Treat as "bridge temporarily unavailable — prompt the user to try again shortly" rather than a hard error.
Client Polling Pattern
Canonical polling loop used by the Onyx App reference client:
Back off politely on errors — the endpoint has a public rate limit. For mobile apps, pause polling while the app is in the background and resume on foreground with a single fresh fetch.
Next
Ethereum → Goliath — how and when to call these endpoints.
Goliath → Ethereum — including the XCN withdraw intent flow.
Contracts & Events — identifiers to feed into
/bridge/status.
Last updated