curl --request GET \
--url https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash} \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}', 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://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"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"
"net/http"
"io"
)
func main() {
url := "https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"items": [
{
"id": "YmFzZS9pbmsvNjIzMzkzNg",
"protocol": "across",
"status": "SUCCEEDED",
"time": "2026-09-22T11:02:37.000Z",
"matched_leg": "source",
"source": {
"network": "base",
"tx_hash": "0x9539f73f932974f9c1cc50658324a3007850ca8b944570f21038d07937e36175",
"address": "0x4e0fdbb660635e76ed66799cd6505372a960cfd3",
"time": "2026-09-22T11:02:37.000Z",
"asset": {
"symbol": "USDC",
"amount": 38.24,
"usd": 38.24
}
},
"destination": {
"network": "base",
"tx_hash": "0x9539f73f932974f9c1cc50658324a3007850ca8b944570f21038d07937e36175",
"address": "0x4e0fdbb660635e76ed66799cd6505372a960cfd3",
"time": "2026-09-22T11:02:37.000Z",
"asset": {
"symbol": "USDC",
"amount": 38.24,
"usd": 38.24
}
},
"funding_deposit_tx_hashes": [
"0x3d61d9dcb7dabf967dbebb0679d75a4e33bb48a2ff14c7fc2a100ea83ab081c9"
],
"gateway_deposit": {
"state": "unspent",
"reason": null,
"remaining_amount": 25,
"withdrawn_amount": null
}
}
],
"meta": {
"next_cursor": "eyJpZCI6IjkxeFFlV3Z...",
"page_number": 1
}
}Get cross-chain transfers by hash
Returns the cross-chain transfer whose source or destination transaction is tx_hash, with both legs: each leg’s network, transaction hash, address, time and asset, and matched_leg to say which leg your hash is. Send one hash from either leg; no network, protocol or direction is needed. The destination asset is what was actually delivered, so a cross-chain swap shows the asset received. Results are newest first, usually one; a hash with more than 100 transfers (an IBC relayer transaction) pages through meta.next_cursor. An empty items means no cross-chain transfer for this hash is indexed: it did not cross chains, or it crossed on a protocol, network or date range outside GET /v2/cross-chain/coverage. A transfer whose delivery is not yet observed is returned with its status and null destination fields, never as an empty answer. An IBC transfer is also found by its acknowledgement transaction, on the source leg. For Circle Gateway, the deposit into Gateway that funded a transfer also finds it, on the source leg and listed in funding_deposit_tx_hashes. A Gateway deposit not proven to fund a transfer comes back as its own item with status DEPOSITED and gateway_deposit saying whether it is unspent, partly spent, withdrawn, or why it cannot be linked; such items appear only here, never in GET /v2/transfers. To search transfers by address, network or date, use GET /v2/transfers.
curl --request GET \
--url https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash} \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}', 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://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"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"
"net/http"
"io"
)
func main() {
url := "https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/cross-chain/transfers/by-hash/{tx_hash}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"items": [
{
"id": "YmFzZS9pbmsvNjIzMzkzNg",
"protocol": "across",
"status": "SUCCEEDED",
"time": "2026-09-22T11:02:37.000Z",
"matched_leg": "source",
"source": {
"network": "base",
"tx_hash": "0x9539f73f932974f9c1cc50658324a3007850ca8b944570f21038d07937e36175",
"address": "0x4e0fdbb660635e76ed66799cd6505372a960cfd3",
"time": "2026-09-22T11:02:37.000Z",
"asset": {
"symbol": "USDC",
"amount": 38.24,
"usd": 38.24
}
},
"destination": {
"network": "base",
"tx_hash": "0x9539f73f932974f9c1cc50658324a3007850ca8b944570f21038d07937e36175",
"address": "0x4e0fdbb660635e76ed66799cd6505372a960cfd3",
"time": "2026-09-22T11:02:37.000Z",
"asset": {
"symbol": "USDC",
"amount": 38.24,
"usd": 38.24
}
},
"funding_deposit_tx_hashes": [
"0x3d61d9dcb7dabf967dbebb0679d75a4e33bb48a2ff14c7fc2a100ea83ab081c9"
],
"gateway_deposit": {
"state": "unspent",
"reason": null,
"remaining_amount": 25,
"withdrawn_amount": null
}
}
],
"meta": {
"next_cursor": "eyJpZCI6IjkxeFFlV3Z...",
"page_number": 1
}
}Authorizations
Authorization method required to allow user to access the api endpoints.
Path Parameters
A transaction hash from either side of a cross-chain transfer: the one that sent the funds or the one that delivered them. For Circle Gateway, also the deposit into Gateway that funded the transfer. No network, protocol or direction is needed.
1 - 128"0x9539f73f932974f9c1cc50658324a3007850ca8b944570f21038d07937e36175"
Query Parameters
Opaque cursor from a previous page's meta.next_cursor. Omit for the first page.
Response
The cross-chain transfers whose source or destination transaction is the looked-up hash, newest first, 100 per page. Usually one. For a Circle Gateway deposit hash: the transfers it funded, plus a DEPOSITED item for the deposit while it is not wholly linked. Empty when our index holds no cross-chain transfer for this hash: see GET /v2/cross-chain/coverage for what the index covers.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Was this page helpful?