First seen time
You can fetch the first seen time for any txid using mempool.space API's.
This script will handle both confirmed and unconfirmed transactions.
Regular Confirmed
python txfirstseen.py 1a13c435cb5a423abe56b711b33e753d74fe291da52a4d77bc7d58ebe3914e0c
Regular confirmed transaction
{
"txid": "1a13c435cb5a423abe56b711b33e753d74fe291da52a4d77bc7d58ebe3914e0c",
"seen": {
"unix": 1725539361,
"human": "2024-09-05 12:29:21 UTC"
},
"conf": {
"unix": 1725539528,
"human": "2024-09-05 12:32:08 UTC"
}
}
response
Confirmed but not expected in block
python txfirstseen.py 174fbe5733f3d3669e03a1b26d269b67b226413c1e5155ef16e1d000ab9fcd98
{
"txid": "174fbe5733f3d3669e03a1b26d269b67b226413c1e5155ef16e1d000ab9fcd98",
"seen": {
"unix": 1726890532,
"human": "2024-09-21 03:48:52 UTC"
},
"conf": {
"unix": 1726905651,
"human": "2024-09-21 08:00:51 UTC"
}
}
Old Confirmed
python txfirstseen.py 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098
Old confirmed transaction before block audit data
{
"txid": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",
"seen": "unknown",
"conf": {
"unix": 1231469665,
"human": "2009-01-09 02:54:25 UTC"
}
}
response
Unconfirmed
python txfirstseen.py 807b3097009d51db785b1aa2c4e82bd9a4f26909e19ed5345931b60ecefea1bf
Unconfirmed transaction
{
"txid": "807b3097009d51db785b1aa2c4e82bd9a4f26909e19ed5345931b60ecefea1bf",
"seen": {
"unix": 1727098078,
"human": "2024-09-23 13:27:58 UTC"
},
"conf": null
}
response
Code
import sys
import json
from datetime import datetime, timezone
import requests
def get_transaction_info(txid):
tx_url = f"https://mempool.space/api/tx/{txid}"
try:
response = requests.get(tx_url)
response.raise_for_status()
tx_data = response.json()
first_seen = "unknown"
confirmation_time = None
if tx_data['status']['confirmed']:
block_hash = tx_data['status']['block_hash']
confirmation_time = tx_data['status']['block_time']
# Try to get audit data for first seen time
try:
block_url = f"https://mempool.space/api/v1/block/{block_hash}/tx/{txid}/audit"
block_response = requests.get(block_url)
block_response.raise_for_status()
block_data = block_response.json()
if 'firstSeen' in block_data:
first_seen = block_data['firstSeen']
else:
# If audit data doesn't have firstSeen, try block summary
summary_url = f"https://mempool.space/api/v1/block/{block_hash}/summary"
summary_response = requests.get(summary_url)
summary_response.raise_for_status()
summary_data = summary_response.json()
for tx in summary_data:
if tx['txid'] == txid:
first_seen = tx['time']
break
except requests.exceptions.RequestException as e:
print(f"Error fetching additional data: {e}")
# If both attempts fail, first seen remains "unknown"
else:
# Transaction is unconfirmed, use transaction-times API for first seen
times_url = f"https://mempool.space/api/v1/transaction-times?txId[]={txid}"
times_response = requests.get(times_url)
times_response.raise_for_status()
times_data = times_response.json()
if isinstance(times_data, dict) and txid in times_data:
first_seen = times_data[txid]
elif isinstance(times_data, list) and len(times_data) > 0:
first_seen = times_data[0][0] if isinstance(times_data[0], list) else times_data[0]
else:
print(f"Unexpected response format from transaction-times API: {times_data}")
return first_seen, confirmation_time
except requests.exceptions.RequestException as e:
print(f"Error occurred while fetching data: {e}")
return None, None
def format_time(timestamp):
if timestamp is None:
return None
if timestamp == "unknown":
return "unknown"
unix_time = int(timestamp)
human_readable = datetime.fromtimestamp(unix_time, tz=timezone.utc).strftime('%Y-%m-%d %H:%M:%S %Z')
return {"unix": unix_time, "human": human_readable}
def main():
if len(sys.argv) != 2:
print("Usage: python script.py <txid>")
sys.exit(1)
txid = sys.argv[1]
first_seen, confirmation_time = get_transaction_info(txid)
if first_seen is not None or confirmation_time is not None:
result = {
"txid": txid,
"seen": format_time(first_seen),
"conf": format_time(confirmation_time)
}
print(json.dumps(result, indent=2))
else:
print(json.dumps({"error": f"Unable to retrieve information for transaction ID: {txid}"}, indent=2))
if __name__ == "__main__":
main()