curl --request POST \
--url https://harness.chance.cc/api/v1/wallets/{id}/swap \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"sell": "USDC",
"buy": "WETH",
"amount": "25",
"chain": "base",
"slippageBps": 50
}
'import requests
url = "https://harness.chance.cc/api/v1/wallets/{id}/swap"
payload = {
"sell": "USDC",
"buy": "WETH",
"amount": "25",
"chain": "base",
"slippageBps": 50
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({sell: 'USDC', buy: 'WETH', amount: '25', chain: 'base', slippageBps: 50})
};
fetch('https://harness.chance.cc/api/v1/wallets/{id}/swap', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://harness.chance.cc/api/v1/wallets/{id}/swap",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'sell' => 'USDC',
'buy' => 'WETH',
'amount' => '25',
'chain' => 'base',
'slippageBps' => 50
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://harness.chance.cc/api/v1/wallets/{id}/swap"
payload := strings.NewReader("{\n \"sell\": \"USDC\",\n \"buy\": \"WETH\",\n \"amount\": \"25\",\n \"chain\": \"base\",\n \"slippageBps\": 50\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://harness.chance.cc/api/v1/wallets/{id}/swap")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"sell\": \"USDC\",\n \"buy\": \"WETH\",\n \"amount\": \"25\",\n \"chain\": \"base\",\n \"slippageBps\": 50\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://harness.chance.cc/api/v1/wallets/{id}/swap")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sell\": \"USDC\",\n \"buy\": \"WETH\",\n \"amount\": \"25\",\n \"chain\": \"base\",\n \"slippageBps\": 50\n}"
response = http.request(request)
puts response.read_body{
"txId": "<string>",
"status": "blocked",
"verdict": "<string>",
"reasoning": "<string>",
"requestHash": "<string>",
"simulation": {
"ok": true,
"status": "clean",
"declared": true,
"wouldRevert": true,
"error": "<string>",
"caip2": "<string>",
"changes": [
{
"direction": "in",
"assetType": "native",
"changeType": "transfer",
"symbol": "<string>",
"name": "<string>",
"contractAddress": "<string>",
"rawAmount": "<string>",
"decimals": 123,
"amount": "<string>",
"usdValue": 123,
"counterparty": "<string>",
"logoUrl": "<string>"
}
],
"totalUsdOut": 123,
"totalUsdIn": 123,
"gasUsed": "<string>",
"logsExcerpt": [
"<string>"
],
"warnings": [
"<string>"
],
"simulatedAt": "2023-11-07T05:31:56Z",
"provider": "tatum"
},
"approvalUrl": "<string>",
"txHash": "<string>",
"scanId": "<string>",
"creditsRemaining": 123,
"proof": {
"transcriptRoot": "<string>",
"outputHash": "<string>",
"signature": "<string>",
"judge": "<string>",
"attested": true,
"anchorTx": "<string>",
"anchorVerified": true,
"transcriptUri": "<string>",
"explorerTx": "<string>"
},
"swap": {
"routing": "<string>",
"sell": {
"address": "<string>",
"decimals": 123,
"symbol": "<string>"
},
"buy": {
"address": "<string>",
"decimals": 123,
"symbol": "<string>"
},
"amountIn": "<string>",
"amountOut": "<string>",
"minimumOut": "<string>",
"amountInHuman": "<string>",
"amountOutHuman": "<string>",
"minimumOutHuman": "<string>",
"priceImpactPct": 123,
"slippagePct": 123,
"gasFeeUSD": "<string>",
"routeString": "<string>",
"approvalNeeded": true,
"approvalSpender": "<string>"
}
}Propose a swap
Quotes the swap on the Uniswap Trading API, builds the batch (an approval for exactly the sell amount when needed, then the swap) and proposes it like /propose. Base and Ethereum wallets only. One credit when the judge runs.
curl --request POST \
--url https://harness.chance.cc/api/v1/wallets/{id}/swap \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"sell": "USDC",
"buy": "WETH",
"amount": "25",
"chain": "base",
"slippageBps": 50
}
'import requests
url = "https://harness.chance.cc/api/v1/wallets/{id}/swap"
payload = {
"sell": "USDC",
"buy": "WETH",
"amount": "25",
"chain": "base",
"slippageBps": 50
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({sell: 'USDC', buy: 'WETH', amount: '25', chain: 'base', slippageBps: 50})
};
fetch('https://harness.chance.cc/api/v1/wallets/{id}/swap', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://harness.chance.cc/api/v1/wallets/{id}/swap",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'sell' => 'USDC',
'buy' => 'WETH',
'amount' => '25',
'chain' => 'base',
'slippageBps' => 50
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://harness.chance.cc/api/v1/wallets/{id}/swap"
payload := strings.NewReader("{\n \"sell\": \"USDC\",\n \"buy\": \"WETH\",\n \"amount\": \"25\",\n \"chain\": \"base\",\n \"slippageBps\": 50\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://harness.chance.cc/api/v1/wallets/{id}/swap")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"sell\": \"USDC\",\n \"buy\": \"WETH\",\n \"amount\": \"25\",\n \"chain\": \"base\",\n \"slippageBps\": 50\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://harness.chance.cc/api/v1/wallets/{id}/swap")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sell\": \"USDC\",\n \"buy\": \"WETH\",\n \"amount\": \"25\",\n \"chain\": \"base\",\n \"slippageBps\": 50\n}"
response = http.request(request)
puts response.read_body{
"txId": "<string>",
"status": "blocked",
"verdict": "<string>",
"reasoning": "<string>",
"requestHash": "<string>",
"simulation": {
"ok": true,
"status": "clean",
"declared": true,
"wouldRevert": true,
"error": "<string>",
"caip2": "<string>",
"changes": [
{
"direction": "in",
"assetType": "native",
"changeType": "transfer",
"symbol": "<string>",
"name": "<string>",
"contractAddress": "<string>",
"rawAmount": "<string>",
"decimals": 123,
"amount": "<string>",
"usdValue": 123,
"counterparty": "<string>",
"logoUrl": "<string>"
}
],
"totalUsdOut": 123,
"totalUsdIn": 123,
"gasUsed": "<string>",
"logsExcerpt": [
"<string>"
],
"warnings": [
"<string>"
],
"simulatedAt": "2023-11-07T05:31:56Z",
"provider": "tatum"
},
"approvalUrl": "<string>",
"txHash": "<string>",
"scanId": "<string>",
"creditsRemaining": 123,
"proof": {
"transcriptRoot": "<string>",
"outputHash": "<string>",
"signature": "<string>",
"judge": "<string>",
"attested": true,
"anchorTx": "<string>",
"anchorVerified": true,
"transcriptUri": "<string>",
"explorerTx": "<string>"
},
"swap": {
"routing": "<string>",
"sell": {
"address": "<string>",
"decimals": 123,
"symbol": "<string>"
},
"buy": {
"address": "<string>",
"decimals": 123,
"symbol": "<string>"
},
"amountIn": "<string>",
"amountOut": "<string>",
"minimumOut": "<string>",
"amountInHuman": "<string>",
"amountOutHuman": "<string>",
"minimumOutHuman": "<string>",
"priceImpactPct": 123,
"slippagePct": 123,
"gasFeeUSD": "<string>",
"routeString": "<string>",
"approvalNeeded": true,
"approvalSpender": "<string>"
}
}Authorizations
An API key (chance_sk_live_…) from https://harness.chance.cc/keys.
Path Parameters
The wallet's id (UUID) or its name.
Body
0x token address, ETH, WETH, USDC, or a symbol the wallet holds on this chain.
0x token address, ETH, WETH or USDC.
Amount to sell, in the sell token's units.
Must be the wallet's chain.
ethereum, base 1 <= x <= 1000Context for the judge, treated as untrusted narration.
Response
The proposal outcome and the quote.
Escrow transaction id. Poll it at /api/v1/escrow-transactions/{id}.
blocked, awaiting_user, executing, executed, failed ALLOW, BLOCK or ESCALATE. BLOCK without a scanId means the wallet's limits refused it before the judge ran.
Hash of the canonical payload the wallet will sign. Execution recomputes it and refuses on a mismatch.
Show child attributes
Show child attributes
Set when the proposal waits for the owner. Send it to them; an API key cannot confirm.
Set when the proposal executed.
Verification id. Null when no judge ran.
Null when no credit was charged.
Null when no judge ran.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
