Skip to main content

Record Terms of Service agreement – Earn API

Updated on
Jul 31, 2026

Overview

Records the wallet's ToS acceptance. SignedRequest, action tos_agreement; the signature binds terms_url, which is echoed back. The recovered wallet must equal the path addr or the call fails 403 owner_mismatch.

Endpoint

POST https://earn-api.quicknode.dev/functions/v1/api/v1/wallets/{addr}/tos

Authorization

Include the published apikey header and a valid Sign-In with Ethereum (SIWE) proof in the request body. The SIWE message binds the wallet to this action, payload, and request path.

Parameters

ParameterLocationTypeRequiredDescription
addrpathstringYesWallet address (`0x` + 40 hex).

Request body

The signed payload binds the literal terms_url for auditability.

FieldTypeRequiredDescription
siweobjectYesA Sign-In-With-Ethereum proof binding the wallet to (action, payload, issuedAt, expirationTime).
terms_urlstringNoThe ToS URL being agreed to; echoed back in the response.

Example request

curl --request POST \
--url 'https://earn-api.quicknode.dev/functions/v1/api/v1/wallets/0x1234567890abcdef1234567890abcdef12345678/tos' \
--header 'Accept: application/json' \
--header 'apikey: <EARN_PUBLIC_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"terms_url": "https://www.quicknode.com/terms-of-service",
"siwe": {
"message": "earn.quicknode.com wants you to sign in with your Ethereum account:\n0x1234...\n\nAuthorize tos_agreement\n\nURI: https://earn.quicknode.com\nVersion: 1\nChain ID: 8453\nNonce: 5c6d...\nIssued At: 2026-07-07T18:00:00.000Z\nExpiration Time: 2026-07-07T18:05:00.000Z\nResources:\n- sha256:<hex>\n- path:/wallets/0x1234.../tos",
"signature": "0xabcd..."
}
}'

Response

FieldTypeRequiredDescription
okbooleanYesAlways true on a 2xx.
addressstringYesLowercased wallet address.
has_agreementbooleanYesAlways true after recording.
terms_urlstringNoEcho of the signed `terms_url` (absent when the caller sent none).

Example response

{
"ok": true,
"address": "0x1234567890abcdef1234567890abcdef12345678",
"has_agreement": true,
"terms_url": "https://www.quicknode.com/terms-of-service"
}

HTTP responses

StatusDescription
200The recorded agreement.
400Malformed request or SIWE block. `code` is one of: `invalid_request`, `siwe_missing` (no `siwe` block), `siwe_shape` (message/signature not strings), `siwe_parse` (message does not match the documented line format).
401SIWE verification failed. `code` is one of: `siwe_domain` (message domain not allowlisted), `siwe_action` (statement/action mismatch), `siwe_stale` (expired or validity window out of bounds), `siwe_payload` (payload hash or resource mismatch — canonicalization drift, a re-serialized body, or a `- path:` entry that does not match the request path), `siwe_chain` (bad chain id), `siwe_recover` (signature does not match the claimed address), `siwe_replay` (nonce already used — sign a fresh request).
403The signing wallet does not match the `{addr}` in the path. A wallet may only write its own preferences / ToS state.
429Rate limit exceeded. `Retry-After` (seconds) tells you when to retry. Reads, feedback, and push writes are keyed per IP; create/update/delete are keyed per wallet+IP; deposit/withdraw/claim calldata is keyed per strategy+IP.
500Internal server error.
503Signature verification could not reach the chain to validate a contract (ERC-1271) wallet. Transient — retry. Only occurs for smart-wallet signers.
OpenAPI source

This page is based on operation recordTosAgreement in the Earn OpenAPI 3.1 specification.

Share this doc